红联Linux门户
Linux帮助

《Squid 中文权威指南》续 (九)

发布时间:2009-03-25 20:06:13来源:红联作者:gary168
>理解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 匹配。


6.2 访问控制规则

前面提过,ACL 元素是建立访问控制的第一步。第二步是访问控制规则,用来允许或拒绝某些动作。在早先的例子里,你已见过http_access 规则。squid 有大量其他的访问控制列表:

http_access
这是最重要的访问控制列表。它决定哪些客户HTTP 请求被允许,和哪些被拒绝。假如http_access 配置错误,squid cache 容易遭受攻击或被不当利用。

http_reply_access
http_reply_access 与http_access 类似。不同之处是前者在squid 接受到来自原始服务器或上级代理的响应时,才会被检测。大部分访问控制基于客户请求的方式,对这些使用http_access 就够了。然而,某些人喜欢基于响应内容类型来允许或拒绝请求。更多信息请见6.3.9 章。

icp_access
假如你的squid 被配置来服务ICP 响应(见10.6 章),那么该使用icp_access 列表。大部分情况下,你该仅仅允许来自邻居cache 的ICP 请求。

no_cache
你能使用no_cache 访问列表来指示squid,它不必存储某些响应(在磁盘或内存里)。该列表典型的与dst,dstdomain,url_regex ACL 结合使用。
对no_cache 使用"否"条件,这样的双重否定会导致某些混乱。被no_cache 列表拒绝的请求不被缓存。换句话说,no_cache deny...是让目标不被缓存。见6.3.10 章的示例。

miss_access
miss_access 列表主要用于squid 的邻居cache。它决定squid 怎样处理cache 丢失的请求。如果squid 使用集群技术,那么该功能必需。见6.3.7 的示例。

redirector_access
该访问列表决定哪个请求被发送到重定向进程(见11 章)。默认情况下,假如你使用重定向器,那么所有的请求都通过重定向器。你可以使用redirector_access 列表来阻止某些请求被重写。这点特别有用,因为这样的访问列表,使重定向器相对于访问控制系统,接受的请求信息要少一些。

ident_lookup_access
ident_lookup_access 列表与redirector_access 类似。它允许你对某些请求执行懒惰ident查询。squid 默认不发布ident 查询。假如请求被ident_lookup_access 规则(或ident ACL)允许,那么squid 才会进行ident 查询。

always_direct
该访问列表影响squid 怎样处理与邻居cache 转发cache 丢失。通常squid 试图转发cache
丢失到父cache,和/或squid 使用ICP 来查找临近cache 响应。然而,当请求匹配always_direct规则时,squid 直接转发请求到原始服务器。
使用该规则,对"allow"规则的匹配导致squid 直接转发请求,见10.4.4 章的更多细节和示例。

never_direct
never_direct 与always_direct 相反。匹配该列表的cache 丢失请求必须发送到邻居cache。这点对在防火墙之后的代理特别有用。
使用该列表,对"allow"规则的匹配导致squid 转发请求到邻居cache。见10.4.3 章的更多细节和示例。

snmp_access
该访问列表应用到发送给squid 的SNMP 端口的查询。你能配合该列表使用的ACL 是snmp_community 和src。假如你确实想使用它,那也能使用srcdomain,srcdom_regex和src_as。见14.3 章的示例。

broken_posts
该访问列表影响squid 处理某些POST 请求的方法。某些老的用户代理在请求主体的结尾处发送一个特别的回车换行符。那就是说,消息主体比content-length 头部指示的长度要多2 个字节。更糟糕的是,某些老的HTTP 服务器实际上依赖于这种不正确的行为。当请求匹配该访问列表时,squid 模拟这种客户端并且发送特殊的回车换行符。
Squid 有大量的使用ACL 元素的其他配置指令。它们中的某些过去是全局配置,后被修改来使用ACL 以提供更灵活的控制。

cache_peer_access
该访问列表控制发送到邻居cache 的HTTP 请求和ICP/HTCP 查询。见10.4.1 章的更多信息和示例。

reply_body_max_size
该访问列表限制对HTTP 响应主体的最大可接受size。见附录A 的更多信息。

delay_access
该访问规则列表控制是否延时池被应用到某个请求的cache 丢失响应。见附录C。

tcp_outgoing_address
该访问列表绑定服务端TCP 连接到指定的本地IP 地址。见附录A。

tcp_outgoing_tos
该访问列表能设置到原始服务器和邻居cache 的TCP 连接的不同TOS/Diffserv 值,见附录A。

header_access
使用该指令,你能配置squid 从它转发的请求里删除某些HTTP 头部。例如,你也许想Squid过滤掉发送到某些原始服务器的请求里的Cookie 头部。见附录A。

header_replace
该指令允许你替换,而不是删除,HTTP 头部的内容。例如,你能设置user-agent 头部为假值,满足某些原始服务器的要求,但仍保护你的隐私。见附录A。


6.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 负载。

对大部分访问列表,deny 和allow 的意义明显。然而,它们中的某些,却并非如此含义清楚。请谨慎的编写always_direct,never_direct,和no_cache 规则。在always_direct 中,allow规则意味着匹配的请求直接转发到原始服务器。always_direct deny 规则意味着匹配的请求不强迫发送到原始服务器,但假如邻居cache 不可到达,那可能还是会这么做。no_cache 规则也有点麻烦。这里,你必须对不必被cache 的请求使用deny。

6.2.2 Squid 如何匹配访问规则

回想一下squid 在搜索ACL 元素时使用的“或”逻辑。在acl 里的任何单值都可以导致匹配。

然而,访问规则恰好相反。对http_access 和其他规则设置,squid 使用“与”逻辑。考虑如下示例:
access_list allow ACL1 ACL2 ACL3

对该匹配规则来说,请求必须匹配ACL1,ACL2,ACL3 中的任何一个。假如这些ACL中的任何一个不匹配请求,squid 停止搜索该规则,并继续处理下一条。对某个规则来说,将最少匹配的ACL 放在首位,能使效率最佳。考虑如下示例:
acl A method http
acl B port 8080
http_access deny A B

该http_access 规则有点低效,因为A ACL 看起来比B ACL 更容易匹配。反转顺序应该更好,以便squid 仅仅检查一个ACL,而不是两个:
http_access deny B A

人们易犯的典型错误是编写永不正确的规则。例如:
acl A src 1.2.3.4
acl B src 5.6.7.8
http_acc
文章评论

共有 0 条评论