C5-Squid-ACL
2012-08-27 11:56:14
标签:anti_hotlinking linux acl squid
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://dngood.blog.51cto.com/446195/974188
C5-Squid-ACL
1 ACL 代码
#http
acl all src 0/0
acl test dstdomain .test.com .testcdn.com gw.api.taobao.com
#icp
acl sibling src 10.0.100.72 10.0.100.73 10.0.100.74
#manager
acl manager proto cache_object
acl localhost src 127.0.0.1
#purge
acl Purge method PURGE
acl Admins src 127.0.0.1
miss_access deny sibling
icp_access allow sibling
icp_access deny All
http_access allow sibling
http_access allow manager localhost
http_access deny manager
http_access allow Admins Purge
http_access deny Purge
http_access allow all test
http_access deny all
2.访问控制(ACL)
2.1 访问控制元素
ACL 元素是 Squid 的访问控制的基础,这里告诉你如何指定包括IP地址,端口号,主机名, URL 匹配等变量。
和每个 ACL 元素有个名字,在编写访问控制规则时需要引用它们,基本的 ACL 元素语法如下:
acl name type value1 value2 ...
例如:
acl Workstations src 10.0.0.0/16
在多数情况下,你能对一个 ACL 元素列举多个值;
你也可以有多个 ACL 行使用同一个名字,例如下列两段配置是等价的:
acl Http_ports port 80 8000 8080
acl Http_ports port 80
acl Http_ports port 8000
acl Http_ports port 8080
2.1.1 一些基本的 ACL 类型
Squid 大约有 25 个不同的 ACL 类型,其中的一些有通用基本类型例如, src 和 dst ACL,src 使用 IP 地址作为它们的基本类型。
2.1.1.1 IP 地址
使用对象:src,dst,myip
squid 在 ACL 里指定 IP 地址时,拥有强有力的语法,你能以子网,地址范围,域名等形式编写地址;这样假如
squid 支持标准 IP 地址写法(由”.”连接的 4 个小于 256 的数字)和无类域间路由规范;
另外,假如你忽略掩码,squid 会自动计算相应的掩码。例如,下例中的每组是相等的。
2.1.1.2 域名
使用对象:srcdomain,dstdomain,和 cache_host_domain 指令
域名简单的就是 DNS 名字或区域,例如下面是有效的域名:
squid-cache.org
org
域名 ACL 有点深奥,因为相对于匹配域名和子域有点微妙的差别;
当 ACL 域名以"."开头,squid 将它作为通配符,它匹配在该域的任何主机名,甚至域名自身;
相反的,如果ACL 域名不以"."开头,squid 使用精确的字符串比较,主机名同样必须被严格检查。
注意你能在不同的 ACL 里任意使用这样的域名:
acl Foo dstdomain .lrrr.org
acl Bar dstdomain .am.lrrr.org
这是允许的,因为每个命名 ACL 使用它自己的 splay tree.
2.1.1.3 用户名
使用对象:ident,proxy_auth
该类型的 ACL 被设计成匹配用户名。
squid 可能通过 RFC 1413 ident 协议或者通过 HTTP验证头来获取用户名。用户名必须被严格匹配;
例如,bob 不匹配 bobby,squid 也有相关的ACL 对用户名使用正则表达式匹配(ident_regex 和 proxy_auth_regex);
你可以使用单词"REQUIRED"作为特殊值去匹配任意用户名,当使用基于用户名的访问控制时,squid 通常这样配置。
2.1.1.4 正则表达式
使用对象:srcdom_regex, dstdom_regex, url_regex, urlpath_regex, browser, referer_regex,ident_regex, proxy_auth_regex, req_mime_type, rep_mime_type
大量的 ACL 使用正则表达式来匹配字符串对 squid 来说,最常使用的正则表达式功能用以匹配字符串的开头或结尾。
例如
^字符是特殊元字符,它匹配行或字符串的开头:^
该正则表达式匹配任意以 http://开头的 URL;
$也是特殊的元字符,因为它匹配行或字符串的结尾:.jpg$
实际上,该示例也有些错误,因为.字符也是特殊元字符,它是匹配任意单个字符的通配符,我们实际想要的应该是:\.jpg$
反斜杠对这个"."进行转义。该正则表达式匹配以.jpg 结尾的任意字符串。假如你不使用^或$字符,正则表达式的行为就象标准子串搜索;
它们匹配在字符串里任何位置出现的单词或词组,对所有的 squid 正则表达式类,你可以使用大小写敏感的选项,匹配是默认大小写敏感的。
为了大小写不敏感,在 ACL 类型后面使用-i 选项 例如:
acl Foo url_regex -i ^
2.1.1.5 TCP 端口号
使用对象:port,myport
该类型是相对的,值是个别的端口号或端口范围,回想一下 TCP 端口号是 16 位值,这样它的值必须大于 0 和小于 65536。
例如:
acl Foo port 123
acl Bar port 1-1024
2.1.2 ACL 类型
现在我们能把焦点放在 ACL 类型自身上,在这里按照重要性的降序来列举它们。
2.1.2.1 src
IP 地址在访问控制元素里是最普遍使用的,大部分站点使用 IP 地址来控制客户允许或不允许访问 Squid;
src 类型指客户源 IP 地址,也就是说当 src ACL 出现在访问控制列表里时,squid 将它与发布请求的客户 IP 地址进行比较;
正常情况下你允许来自内网中主机的请求,并阻塞其他的,例如你的单位使用192.168.0.0 子网,你可以这样指定 ACL:
acl MyNetwork src 192.168.0.0
假如你有许多子网,你能在同一个 acl 行里面列举它们:
acl MyNetwork src 192.168.0.0 10.0.1.0/24 10.0.5.0/24 172.16.0.0/12
squid 有许多其他 ACL 类型用以检查客户地址,srcdomain 类型比较客户的完整可验证域名,它要求反向 DNS 查询,这可能会延缓处理该请求;
srcdom_regex ACL 是类似的,但它允许你使用正则表达式来匹配域名,最后src_as 类型比较客户的 AS 号。
2.1.2.4 dstdomain
在某些情况下,你发现基于名字的访问控制非常有用,你可以使用它们去阻塞对某些站点的访问,去控制 squid 如何转发请求;
以及让某些响应不可缓存,dstdomain 之所以非常有用,是因为它检查请求 url 里的主机名,然而首先我想申明如下两行的不同:
acl A dst
acl B dstdomain
A 实际上是 IP地址 ACL,当 Squid 解析配置文件时,它查询 的 IP地址,并将它们存在内存里;
它不保存名字,假如在 squid 运行时 IP 地址改变了,squid 会继续使用旧的地址,然而 dstdomain ACL 以域名形式存储并非IP地址;
squid 检查 ACL B时,当它对 URL的主机名部分使用字符串比较功能,在该情形下它并不真正关心是否 的IP地址改变了;
使用 dstdomain ACL 的主要问题是某些 URL 使用 IP地址代替主机名,假如你的目标是使用 dstdomain ACL 来阻塞对某些站点的访问;
聪明的用户能手工查询站点的 IP 地址,然后将它们放在 URL 里,例如下面的 2 行 URL 带来同样的页面:
http:///docs/FAQ/
第一行能被 dstdomain ACL 轻易匹配,但第二行不能,这样假如你依靠 dstdomain ACL,你也该同样阻塞所有使用 IP 地址代替主机名的请求。
2.1.2.8 method
method ACL 指 HTTP 请求方法,GET是典型的最常用方法,接下来是 POST,PUT,和其他,下例说明如何使用 method ACL:
acl Uploads method PUT POST
Squid 知道下列标准 HTTP 方法:
GET, POST, PUT, HEAD, CONNECT, TRACE,OPTIONS 和 DELETE;
另外,squid 了解下列来自 WEBDAV 规范,RFC 2518 的方法:
PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK;
某些 Microsoft 产品使用非标准的 WEBDAV 方法,所以 squid 也了解它们:
BMOVE, BDELETE, BPROPFIND;
最后,你可以在 extension_methods 指令里配置 squid 去理解其他的请求方法,请见附录 A;
注意 CONNECT 方法非常特殊,它是用于通过 HTTP 代理来封装某种请求的方法在处理 CONNECT 方法和远程服务器的端口号时应特别谨慎;
就像前面章节讲过的一样,你不希望 squid连接到某些远程服务,你该限制 CONNECT 方法仅仅能连接到 HTTPS/SSL 或 NNTPS 端口(443 和 563);
默认的
squid.conf 这样做:
acl CONNECT method CONNECT
acl SSL_ports 443 563
http_access allow CONNECT SSL_ports
http_access deny CONNECT
在该配置里,squid 仅仅允许加密请求到端口 443(HTTPS/SSL)和 563(NNTPS),CONNECT 方法对其他端口的请求都被拒绝;
PURGE 是另一个特殊的请求方法,它是 Squid 的专有方法,没有在任何 RFC 里定义,它让管理员能强制删除缓存对象;
既然该方法有些危险,squid 默认拒绝 PURGE 请求,除非你定义了 ACL 引用了该方法,否则任何能访问 cache 者也许能够删除任意缓存对象;
推荐仅仅允许来自 localhost 的 PURGE:
acl Purge method PURGE
acl Localhost src 127.0.0.1
http_access allow Purge Localhost
http_access deny Purge
关于从 squid 的缓存里删除对象,请见 7.6 章。
2.1.2.9 proto
该类型指 URI 访问(或传输)协议。如下是有效值:http, https (same as HTTP/TLS), ftp,gopher, urn, whois, 和 cache_object。
也就是说,这些是被 squid 支持的 URL 机制名字 例如,假如你想拒绝所有的 FTP 请求,你可以使用下列指令:
acl FTP proto FTP
http_access deny FTP
cache_object 机制是 squid 的特性,它用于访问 squid 的缓存管理接口,我将在 14.2 章讨论它,不幸的是它并非好名字,可能会被改变;
默认的 squid.conf 文件有许多行限制缓存管理访问:
acl Manager proto cache_object
acl Localhost src 127.0.0.1
http_access allow Manager Localhost
http_access deny Manager
这些配置行仅允许来自本机地址的缓存管理请求,所有其他的缓存管理请求被拒绝;
这意味着在 squid 机器上有帐号的人,能访问到潜在的敏感缓存管理信息;
你也许想修改缓存管理访问控制,或对某些页面使用密码保护,将在 14.2.2 章里谈论到。
2.1.5 Squid 如何匹配访问控制元素
理解 squid 如何搜索 ACL 元素去匹配是很重要的,当 ACL 元素有多个值时,任何单个值能导致匹配;
换句话说,squid 在检查 ACL 元素值时使用 OR 逻辑,当 squid 找到第一个值匹配时,它停止搜索;
这意味着把最可能匹配的值放在列表开头处,能减少延时,让我们看一个特殊的例子,考虑如下 ACL 定义:
acl Simpsons ident Maggie Lisa Bart Marge Homer
当 squid 在访问列表里遇到 Simpsons ACL 时,它执行 ident查询让我们看一下,当用户 ident 服务返回 Marge 时,会发生什么呢?
squid 的 ACL 代码在成功匹配 Marge 前,会先后将这个值与 Maggie,Lisa,和 Bart 对比当搜索完成时;
我们认为 Simpsons ACL 匹配了这个请求,实际上这有点欺骗,ident ACL 值并非存储在无序列表里,它们存储在 splay tree 中;
这意味着,在非匹配事件中,squid 不会搜索完所有的名字,对一个 splay tree 搜索 N 个条目需要记录 N 个比较;
许多其他的 ACL 类型也使用 splay tree,然而基于正则表达式的类型不使用,既然正则表达式不能这样存储;
它们以链表形式存储,这使得在大链表里它们特别低效,特别是不匹配链表里任何正则表达式的请求,为了改进这个形式;
当匹配发生时,squid 将正则表达式移到列表的顶部,实际上因为 ACL 匹配代码的天然特性,squid 将匹配的条目;
移到列表的第二个位置,这样普通的匹配值自然移到 ACL 列表的顶部,这样会减少比较数量。
让我们看另一个简单示例:
acl Schmever port 80-90 101 103 107 1 2 3 9999
该 ACL 匹配到原始服务器 80-90 端口,和其他独立端口的请求,80 端口的请求对squid通过查看第一个值就匹配了该 ACL;
对 9999 端口,其他每个值都先被检查,对某个不在列表里的端口,squid 要检查所有值才宣布它不匹配;
就像我已经讲过的,将最常用的值放在第一位能优化 ACL 匹配。
2.2 访问控制规则(部分)
前面提过,ACL 元素是建立访问控制的第一步,第二步是访问控制规则,用来允许或拒绝某些动作;
在早先的例子里,你已见过 http_access 规则,squid 有大量其他的访问控制列表:
http_access 这是最重要的访问控制列表。
它决定哪些客户 HTTP 请求被允许和哪些被拒绝,假如http_access 配置错误,squid cache 容易遭受攻击或被不当利用。
icp_access
假如你的 squid 被配置来服务 ICP 响应,那么该使用 icp_access 列表,大部分情况下你该仅仅允许来自邻居 cache 的 ICP 请求。
no_cache
使用 no_cache 访问列表来指示 squid,它不必存储某些响应(在磁盘或内存里);
该列表典型的与 dst,dstdomain,url_regex ACL 结合使用,对 no_cache 使用"否"条件,这样的双重否定会导致某些混乱;
被 no_cache 列表拒绝的请求不被缓存,换句话说no_cache deny...是让目标不被缓存
cache_peer_access
该访问列表控制发送到邻居 cache 的 HTTP 请求和 ICP/HTCP 查询。
2.2.1 访问规则语法
访问控制规则的语法如下:
access_list allow | deny [!]ACLname ...
例如:
http_access allow MyClients
http_access deny !Safe_Ports
http_access allow GameSites AfterHours
当读取配置文件时,squid 仅仅扫描一遍访问控制行,这样在访问列表里引用 ACL 元素之前,你必须在 acl 行里定义它们;
甚至访问列表规则的顺序也非常重要,你以怎样的顺序编写访问列表,那么 squid 就按怎样的顺序来检查它们;
将最常用的 ACL 放在列表的开始位置,可以减少 squid 的 CPU 负载。
2.2.2 Squid 如何匹配访问规则
回想一下 squid 在搜索 ACL 元素时使用的“或”逻辑,在 acl 里的任何单值都可以导致匹配;
然而访问规则恰好相反,对 http_access 和其他规则设置,squid 使用“与”逻辑,考虑如下示例: ##
access_list allow ACL1 ACL2 ACL3
对该匹配规则来说,请求必须匹配 ACL1,ACL2,ACL3 中的任何一个,假如这些 ACL中的任何一个不匹配请求,squid 停止搜索该规则,并继续处理下一条;
对某个规则来说,将最少匹配的 ACL 放在首位,能使效率最佳。
对某个 ACL 值的匹配算法是,squid 在访问列表里找到匹配规则时搜索终止,假如没有访问规则导致匹配,默认动作是列表里最后一条规则的取反。
例如,考虑如下简单访问配置:
acl Bob ident bob
http_access allow Bob
假如用户 Mary 发起请求她会被拒绝,列表里最后的(唯一的)规则是 allow 规则,它不匹配用户名 mary。
这样,默认的动作是 allow 的取反,故请求被拒绝,类似的假如最后的规则是 deny 规则,默认动作是允许请求。
在访问列表的最后加上一条,明确允许或拒绝所有请求,是好的实际做法。为清楚起见,以前的示例应该如此写:
acl All src 0/0
acl Bob ident bob
http_access allow Bob
http_access deny All
src 0/0 ACL 表示匹配每一个和任意类型的请求。
参考
Squid 中文权威指南
C1-Squid_Cache-Server
C2-Squid_Neighbour
C3-Squid-access.log
C4-Squid-Purge
UPDATE 20120827 squidi anti_hotlinking
squid 代码
#anti_hotlinking
[acl test dstdomain .test.com .testcdn.com gw.api.taobao.com] #[]可选,因为前边已添加
acl null_referer referer_regex .
acl right_referer referer_regex -i ^ ^*.test.com
http_access allow test !null_referer
http_access deny test !right_referer
deny_info right_referer
#deny_info 当被http_access相关规则拒绝时,使用自定义拒绝访问信息
#usage:deny_info error_page_name acl
html 代码
Welcome to nginx!
Welcome to nginx!
#此主机头为host:192.168.57.75
测试
firefox 请求
请求头信息 原始头信息
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Cache-Control max-age=0
Connection keep-alive
Host ss1.testcdn.com
If-Modified-Since Wed, 09 May 2012 07:17:54 GMT
Referer / # 注意
User-Agent Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:14.0) Gecko/20100101 Firefox/14.0.1
响应头信息 原始头信息
Age 1
Cache-Control max-age=25920000
Connection keep-alive
Content-Type image/jpeg
Date Fri, 27 Jul 2012 20:18:02 GMT
Expires Sun, 12 May 2013 12:45:00 GMT
Last-Modified Wed, 09 May 2012 07:17:54 GMT
X-Via 1.0 jxq37:8107 (Cdn Cache Server V2.0)
squid 日志
1 referer /
2 TCP_DENIED:NONE
192.168.4.33 - - [27/Aug/2012:11:13:07 +0800] "GET http://blog.test.com/wp-content/uploads/2012/08/v9-1-150x150.png \
HTTP/1.1" 302 376 "/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:14.0) Gecko/20100101 Firefox/14.0.1" \
TCP_DENIED:NONE
参考
squid参数
squid防盗链配置
结束
更多请:
linux 相关 37275208
vmware 虚拟化相关 166682360
本文出自 “dongnan” 博客,请务必保留此出处http://dngood.blog.51cto.com/446195/974188