🔗 拦截缓存
或者,如何让我的用户的浏览器在不配置代理的情况下使用我的缓存?
拦截缓存有许多名称——拦截缓存、透明代理、URL重写、SSL-Bump和缓存重定向。拦截缓存是指将来自远程客户端的HTTP连接重定向到缓存服务器的过程,而用户对此一无所知或未进行显式配置。
这种策略也有一些显著的缺点,正如Mark Elsen所概述的那样
- 拦截HTTP违反了TCP/IP标准,因为用户代理认为它们直接与源服务器通信。
- 在大多数操作系统上,需要IPv4和NAT,尽管有些现在也支持IPv6的TPROXY或NAT。
- 它会导致路径MTU(PMTUD)失败,可能导致某些远程站点无法访问。如果你的客户端通过Ethernet或DSL PPPoATM连接,其中缓存和客户端之间的所有链路的MTU为1500或更高,这通常不是问题。如果你的客户端通过DSL PPPoE连接,这很可能是一个问题,因为PPPoE链路的MTU经常会减小(1472是很常见的)。
- 连接多路复用不起作用。了解代理的客户端可以在一个代理连接上发送多个域的请求,从而节省资源,同时让代理执行多个后端连接。当与源通信时,客户端不允许这样做,并将为资源打开许多TCP连接。这会导致拦截代理比普通代理消耗更多的网络套接字。
- 代理身份验证不起作用。
- 基于IP的源身份验证失败,因为用户都被视为来自拦截缓存自己的IP地址。
- 您无法使用IDENT查找(它们本身非常不安全)。
- ARP中继在代理机器上失败。
- 拦截缓存仅支持HTTP协议,不支持gopher、SSL或FTP。您无法为HTTP以外的其他协议设置重定向规则到代理服务器,因为客户端不知道如何处理。
- 拦截缓存与旨在防止地址欺骗的IP过滤不兼容。
- 客户端仍应具有完整的Internet DNS解析能力;在某些内网/防火墙设置中,这并不总是想要的。
- 与上面相关:假设用户浏览器连接到一个宕机站点。然而,由于透明代理,它会与拦截器建立连接状态。最终用户可能会收到错误的错误消息或浏览器挂起,原因不明。
- DNS负载加倍,因为客户端进行一次DNS查找,拦截代理会重复一次。
- 通过被拦截的端口80或443的协议隧道会中断。
- WebSockets连接不起作用。
- SPDY连接不起作用(HTTPS拦截代理)。
- URL重写和SSL-Bump形式的拦截通常不兼容。SSL-Bump会生成一个假的服务器证书来匹配服务器呈现的内容。如果URL重写改变了正在联系的服务器,客户端将收到错误的证书。或者,尝试将HTTPS URL重写为http:://——服务器将不会呈现任何SSL证书。这两者都会导致用户可见的错误。
如果您认为优点大于缺点,您可能希望继续阅读并研究实施拦截缓存。
🔗 拦截缓存的要求和方法
- 在开始之前,您需要对您正在做的事情有一个很好的理解。这涉及到在TCP层理解连接的发生。这将帮助您配置系统,并在您部署解决方案后,在最终客户遇到问题时提供帮助。
- 当前的操作系统可能会使事情变得更容易。
- 很可能您需要一个网络设备来将流量重定向到您的缓存。如果您的Squid盒子也充当路由器,并且来自您网络的所有流量都在路径上,您可以跳过此步骤。如果您的缓存是一个独立的盒子,位于通常看不到您的客户端网页浏览流量的LAN上,您将需要选择一种方法将HTTP流量从您的客户端机器重定向到缓存。这通常是通过路由器或Layer 3交换机等网络设备完成的,这些设备要么重写目标MAC地址,要么通过GRE或WCCP隧道将网络流量封装到您的缓存。
NAT配置仅在在squid盒子上使用时才有效。这是准确和安全地执行拦截所必需的。要从网关机拦截并将流量指向单独的squid盒,请使用策略路由。
如果您在网络中使用Cisco路由器和交换机,您可能希望研究使用WCCP。WCCP是一种非常灵活的流量重定向方式,并且足够智能,可以在您的缓存离线时自动停止重定向客户端流量。这可能需要您升级路由器或交换机到支持WCCP的IOS版本或升级的功能集。下面有一个专门介绍WCCP的部分。
🔗 配置拦截缓存涉及的步骤
- 构建一个具有正确选项的Squid,通过./configure支持重定向并正确处理客户端。
- 将端口80的流量路由到您的Squid配置用于接受连接的端口。
- 解封装您的网络设备发送给Squid的数据包(仅当您使用GRE或WCCP拦截流量时)。
- 配置您的网络设备以重定向端口80的流量。
前两个步骤是必需的,后两个步骤可能需要也可能不需要,具体取决于您打算如何将HTTP流量路由到您的缓存。
在开始之前,务必仔细阅读squid.conf文件中的完整注释以及本文档的全部内容。让Squid实现拦截缓存并非易事,需要Squid和您的网络中的许多子系统都配置得完全正确,否则您会发现它将无法工作,您的用户将根本无法浏览。您必须在非实时环境中测试您的配置,然后才能将此功能推向您的最终用户。
🔗 编译一个接受其他地址连接的Squid版本
首先,您需要使用正确的选项通过./configure构建Squid,然后您需要配置squid.conf以支持拦截缓存。
🔗 选择传递给./configure的正确选项
所有当前可用的Squid版本都支持拦截缓存,但是为了使其正常工作,您的操作系统和网络也需要进行配置。对于某些操作系统,您需要配置并构建一个能够识别被劫持的连接并区分目标地址的Squid版本。
- 对于Linux,使用
--enable-linux-netfilter选项配置Squid。 - 对于基于*BSD且具有IP过滤的系统,使用
--enable-ipf-transparent选项配置Squid。 - 如果您使用的是OpenBSD的PF,请使用
--enable-pf-transparent配置Squid。
如果您之前在没有该选项的情况下配置过,请执行make clean,否则正确的设置可能不存在。
Squid默认支持WCCPv1和WCCPv2(除非明确禁用)。
🔗 配置Squid以接受和处理重定向的端口80连接
您必须更改Squid配置设置,以识别被劫持的连接并区分目标地址。
在ConfigExamples/Intercept中详细介绍了多种不同的拦截方法及其具体配置。
您通常可以手动配置浏览器连接到您指定为拦截的IP地址和端口。唯一的缺点是性能会略微下降(而且可能不明显),因为需要进行一个系统调用来查看连接是否被拦截。如果没有找到拦截状态,它将像普通连接一样被处理。
🔗 将流量路由到Squid缓存的正确端口
您必须配置您的缓存主机以接受重定向的数据包——任何IP地址,在端口80上——并将它们传递给您的缓存应用程序。这通常通过内核内置的IP过滤/转发功能来完成。
- 在Linux 2.4及以上版本中,这称为
iptables。 - 在FreeBSD中,它称为
ipfw。 - 其他BSD系统可能使用
ip filter、ipnat或pf。
在大多数系统中,可能需要重新编译内核或添加新的可加载内核模块。如果您正在运行一个现代Linux发行版并使用供应商提供的内核,您很可能不需要重新编译,因为所需的模块将默认构建。
🔗 Solaris、SunOS和BSD系统的拦截缓存数据包重定向
您不需要在FreeBSD上使用IP Filter。请使用内置的ipfw功能。请参阅下面的FreeBSD子部分。
🔗 安装IP Filter
首先,获取并安装IP Filter包。
🔗 配置ipnat
将这些行放入/etc/ipnat.rules
# Redirect direct web traffic to local web server.
rdr de0 1.2.3.4/32 port 80 -> 1.2.3.4 port 80 tcp
# Redirect everything else to squid on port 8080
rdr de0 0.0.0.0/0 port 80 -> 1.2.3.4 port 8080 tcp
修改您的启动脚本以启用ipnat。例如,在FreeBSD上,它看起来像这样
/sbin/modload /lkm/if_ipl.o
/sbin/ipnat -f /etc/ipnat.rules
chgrp nobody /dev/ipnat
chmod 644 /dev/ipnat
🔗 OpenBSD PF的拦截缓存数据包重定向
在编译了Squid以接受和处理上面列出的重定向的端口80连接后,无论是手动还是使用FLAVOR=transparent为/usr/ports/www/squid,都需要向pf(/etc/pf.conf)添加重定向规则。在下面的示例中,sk0是您想要透明重定向流量将到达的接口。
i = "sk0"
rdr on $i inet proto tcp from any to any port 80 -> $i port 3128
pass on $i inet proto tcp from $i:network to $i port 3128
或者,取决于您PF实现的最新程度
i = "sk0"
rdr pass on $i inet proto tcp to any port 80 -> $i port 3128
另外,请参阅Daniel Hartmeier关于此主题的页面。
🔗 将数据包从最终客户端发送到您的缓存服务器
有几种方法可以做到这一点。首先,如果您的代理机器已经在数据包路径上(即,它在您的代理用户和Internet之间路由流量),那么您就不必担心这一步,因为拦截缓存现在应该可以工作了。如果您将Squid安装在防火墙机器上,或者在基于UNIX的路由器上,情况就是如此。如果缓存不在连接的自然路径上,那么您需要使用路由器或交换机将数据包从正常路径分流到您的缓存主机。
如果您正在使用外部设备将流量路由到您的缓存,有多种方法可以做到这一点。您可能可以使用Cisco路由器使用WCCP,或者使用“route map”功能。您也可以使用所谓的4层交换机,如Alteon ACE-director或Foundry Networks ServerIron。
最后,您可能可以使用独立的路由器/负载均衡器产品,或接入服务器的路由功能。
🔗 使用策略路由(非WCCP)通过Cisco路由器进行拦截缓存数据包重定向
这与IOS 11.1及更高版本兼容。如果您的路由器执行比在以太网接口和串行端口或BRI端口之间移动数据包更复杂的操作,那么您应该仔细考虑这是否对您有效。
首先定义一个名为proxy-redirect的路由映射(名称不重要),并指定下一跳为运行Squid的机器。
!
route-map proxy-redirect permit 10
match ip address 110
set ip next-hop 203.24.133.2
!
定义一个访问列表来捕获HTTP请求。第二行允许Squid主机直接访问,以避免形成路由环路。通过仔细编写访问列表,如下所示,可以快速找到常见情况,从而大大减轻路由器的处理器负载。
!
access-list 110 deny tcp any any neq www
access-list 110 deny tcp host 203.24.133.2 any
access-list 110 permit tcp any any
!
将路由映射应用到以太网接口。
!
interface FastEthernet0/0
ip policy route-map proxy-redirect
!
🔗 Cisco IP策略路由映射方法的缺点
Bruce Morgan指出,Cisco存在一个与使用IP策略路由映射的拦截代理相关的bug,该bug会导致NFS和其他应用程序中断。据称,Cisco收到了两个bug报告,但未对公众公开。
当数据包的 o/s 数据长度超过1472 字节时,就会出现问题。如果您尝试通过一个带有访问列表和IP策略路由映射的Cisco接口ping一个数据包长度超过1472字节的主机,icmp请求将失败。数据包将被分片,第一个分片被访问列表检查并拒绝——它会走“正常路径”,因为它是一个icmp数据包——然而,当第二个分片被访问列表检查时,它被接受(它不被视为icmp数据包),并按照策略路由的决定进行处理!
John指出,您可以通过仔细编写访问列表来绕过此bug。如果最后/默认规则是允许,那么这个bug就会是个问题,但如果最后/默认规则是拒绝,那就不是问题了。我猜想,除了第一个分片之外,其他分片没有足够的信息来正确地对其进行策略路由。通常TCP数据包不应被分片,至少我的网络在所有地方运行1500的MTU以避免分片。所以这只会影响UDP和ICMP流量。
基本上,您将不得不选择是忍受bug还是获得更好的性能。这一套具有更好的性能,但存在bug。
access-list 110 deny tcp any any neq www
access-list 110 deny tcp host 10.1.2.3 any
access-list 110 permit tcp any any
相反,这一套性能较差,但适用于所有协议。
access-list 110 deny tcp host 10.1.2.3 any
access-list 110 permit tcp any any eq www
access-list 110 deny tcp any any
🔗 使用Foundry L4交换机进行拦截缓存数据包重定向
作者:Brian Feeny
首先,按照本节开头的说明配置Squid以进行拦截缓存。
接下来,配置Foundry 4层交换机将流量重定向到您的Squid服务器或服务器。默认情况下,Foundry将流量重定向到您的squid服务器的端口80。如果需要,可以将其更改为其他端口,但在此不予介绍。
此外,交换机还会对端口进行“健康检查”,以确保您的squid正在响应。如果您的squid没有响应,交换机会默认将流量直接通过,而不是重定向。当Squid恢复正常后,它会再次开始重定向。
本示例假定您有两个squid缓存。
squid1.foo.com 192.168.1.10
squid2.foo.com 192.168.1.11
我们将假设您有各种工作站、客户等连接到交换机,您希望对他们进行拦截并发送到Squid。squid缓存本身也应该连接到交换机。只有路由器连接的接口才重要。您将squid缓存或其他连接放置在哪里并不重要。
本示例假定您的路由器连接到交换机的接口17。如果不是,请相应地调整以下命令。
- 进入配置模式:
telnet@ServerIron#conf t - 在Foundry上配置每个squid。
telnet@ServerIron(config)# server cache-name squid1 192.168.1.10 telnet@ServerIron(config)# server cache-name squid2 192.168.1.11 - 将squid添加到缓存组。
telnet@ServerIron(config)#server cache-group 1 telnet@ServerIron(config-tc-1)#cache-name squid1 telnet@ServerIron(config-tc-1)#cache-name squid2 - 创建一个用于在本地端口上缓存http的策略。
telnet@ServerIron(config)# ip policy 1 cache tcp http local - 在连接到您路由器的端口上启用该策略。
telnet@ServerIron(config)#int e 17 telnet@ServerIron(config-if-17)# ip-policy 1
由于所有到Internet的出站流量都通过接口17(路由器)出去,并且在接口17上应用了缓存策略,因此HTTP流量将被拦截并重定向到您配置的缓存。
可以更改重定向到的默认端口。可以使用负载均衡算法(Least Used、Round Robin等)。如果需要,可以将端口从缓存中排除。可以应用访问列表,以便只重定向某些源IP地址等。此信息未包含在本文件中,因为它只是一个适用于大多数人的快速操作指南,并非旨在成为Foundry交换机配置的全面手册。不过,如果有人觉得应该包含,我可以根据需要修订。
🔗 Alcatel OmnySwitch 7700的拦截缓存数据包重定向
作者:Pedro A M Vazquez
在交换机上定义一个要拦截的网络组。
policy network group MyGroup 10.1.1.0 mask 255.255.255.0
定义要拦截的TCP服务。
policy service web80 destination tcp port 80
policy service web8080 destination tcp port 8080
定义一个使用上述服务的服务组。
policy service group WebPorts web80 web8080
并使用这些来创建一个拦截条件。
policy condition WebFlow source network group MyGroup service group WebPorts
现在,定义一个将流量重定向到运行squid的主机的操作。
policy action Redir alternate gateway ip 10.1.2.3
最后,创建一个使用此条件和相应操作的规则。
policy rule Intercept condition WebFlow action Redir
将规则应用到QoS系统以使其生效。
qos apply
不要忘记您仍然需要配置Squid和Squid的操作系统来处理被拦截的连接。请参阅上文了解Squid和特定于操作系统的详细信息。
🔗 Cabletron/Entrasys产品的拦截缓存数据包重定向
作者:Dave Wintrip, dave at purevanity dot net, 2004年6月3日。
我已经验证了此配置在Cabletron SmartSwitchRouter 2000上有效,并且它应该在任何支持4层功能的Cabletron或Entrasys产品上都有效。
您必须首先配置Squid以启用拦截缓存,如前所述。
接下来,确保您从4层设备到您的squid盒具有连接性,并且squid已正确配置为拦截发送给它的端口80请求。
我通常会创建两组重定向ACL,一组用于缓存,另一组用于绕过缓存。这种拦截方法与Cisco的route-map非常相似。
登录到设备,并进入enable模式以及configure模式。
ssr> en
Password:
ssr# conf
ssr(conf)#
我通常会创建两组重定向ACL,一组用于指定要缓存的对象,另一组用于需要绕过缓存的目标地址。这种拦截方法在此方面与Cisco的route-map非常相似。ACL cache-skip是我们要透明重定向到squid的一系列目标地址列表。
ssr(conf)# acl cache-skip permit tcp any 192.168.1.100/255.255.255.255 any http
ACL cache-allow是将被重定向到Squid的一个源地址列表。
ssr(conf)# acl cache-allow permit tcp 10.0.22.0/255.255.255.0 any any http
将新的ACL保存到运行配置中。
ssr(conf)# save a
接下来,我们需要创建执行重定向的ip-策略。请注意,10.0.23.2是我的Squid服务器,10.0.24.1是我的标准默认下一跳。通过将cache-skip ACL推送到默认网关,Web请求就像Squid盒子不存在一样发送出去。这也可以通过Squid配置来完成,但我宁愿Squid在没有理由的情况下不触碰数据。
ssr(conf)# ip-policy cache-allow permit acl cache-allow next-hop-list 10.0.23.2 action policy-only
ssr(conf)# ip-policy cache-skip permit acl cache-skip next-hop-list 10.0.24.1 action policy-only
将这些新策略应用到活动配置中。
ssr(conf)# save a
我们现在需要将ip-策略应用到我们想要缓存请求的接口上。假设localnet-gw是我们想要缓存请求的网络接口名称,我们首先将cache-skip ACL应用到我们不缓存列表上的请求,并将它们转发到默认网关。然后,我们将cache-allow ACL应用到同一个接口,以将所有其他请求重定向到缓存服务器。
ssr(conf)# ip-policy cache-skip apply interface localnet-gw
ssr(conf)# ip-policy cache-allow apply interface localnet-gw
我们现在需要应用并永久保存我们的更改。到目前为止所做的任何事情在没有将ip-策略应用到活动配置的情况下都不会生效,所以让我们试试看。
ssr(conf)# save a
ssr(conf)# save s
假设您的Squid盒子配置正确,您现在应该能够浏览网页,并且如果您将localnet-gw地址用作您的网关,您将被透明地缓存。
某些Cabletron/Entrasys产品还包含另一种应用Web缓存的方法,但本文件中未涵盖配置细节,不过它相当直接。
另外请注意,如果您的Squid盒子直接连接到您的4层交换机的端口,并且该端口属于其自己的VLAN和子网,如果该端口的状态变为关闭,或者地址变得无法访问,那么交换机将自动绕过ip-策略并通过正常方式转发您的Web请求。这很方便,我必须说。
🔗 ACC Tigris数字接入服务器的拦截缓存数据包重定向
这是关于为ACC Tigris数字接入服务器(如CISCO 5200/5300或Ascend MAX 4000)配置拦截代理。我发现在NAS中这样做可以减少LAN上的流量并降低CISCO的处理负载。Tigris有足够的CPU进行过滤。
第一步是创建允许本地流量通过的过滤器。根据需要添加尽可能多的地址范围。
ADD PROFILE IP FILTER ENTRY local1 INPUT 10.0.3.0 255.255.255.0 0.0.0.0 0.0.0.0 NORMAL
ADD PROFILE IP FILTER ENTRY local2 INPUT 10.0.4.0 255.255.255.0 0.0.0.0 0.0.0.0 NORMAL
第二步是创建一个捕获端口80流量的过滤器。
ADD PROFILE IP FILTER ENTRY http INPUT 0.0.0.0 0.0.0.0 0.0.0.0 0.0.0.0 = 0x6 D= 80 NORMAL
第三步是将端口80流量的“APPLICATION_ID”设置为80。这会导致所有匹配此过滤器的数据包具有ID 80而不是默认ID 0。
SET PROFILE IP FILTER APPLICATION_ID http 80
第四步是创建一个特殊路由,用于“APPLICATION_ID”设置为80的数据包。路由引擎使用ID来选择使用哪些路由。
ADD IP ROUTE ENTRY 0.0.0.0 0.0.0.0 PROXY-IP 1
SET IP ROUTE APPLICATION_ID 0.0.0.0 0.0.0.0 PROXY-IP 80
第五步是将所有内容绑定到一个名为transproxy的过滤器ID。先列出所有本地过滤器,最后列出http过滤器。
ADD PROFILE ENTRY transproxy local1 local2 http
有了这些,就可以使用您的RADIUS服务器将“Framed-Filter-Id = transproxy”键/值对返回给NAS。
您可以使用以下命令检查过滤器是否已分配给登录:
display profile port table
🔗 WCCP - Web Cache Coordination Protocol
贡献者:Glenn Chisholm、Lincoln Dale和Reuben Farrelly。
WCCP是一种非常常见且优秀的拦截缓存方法,因为它为流量重定向过程增加了额外的功能和智能。WCCP是一项动态服务,其中缓存引擎向路由器报告其状态,基于此,路由器决定是否重定向流量。这意味着如果您的缓存不可用,路由器将自动停止尝试将流量转发到它,最终用户将不会受到影响(可能甚至不会注意到您的缓存已停止服务)。
WCCPv1记录在Internet草案draft-forster-wrec-wccp-v1-00.txt中,WCCPv2记录在draft-wilson-wrec-wccp-v2-00.txt中。
要使WCCP工作,您首先需要配置您的Squid缓存,并另外配置主机操作系统,将HTTP流量从端口80重定向到您的Squid盒正在监听流量的任何端口。完成这些之后,您就可以继续在您的路由器上配置WCCP了。
🔗 Squid是否支持WCCP?
Cisco的Web Cache Coordination Protocol V1.0和WCCPv2在所有当前版本的Squid中都得到支持。
🔗 我需要Cisco路由器来运行WCCP吗?
不需要。最初WCCP支持只能在Cisco设备上找到,但现在一些其他网络供应商也支持WCCP。如果您有关于如何配置非Cisco设备的信息,请在此发布。
🔗 我可以在Windows版的Squid中使用WCCP吗?
技术上可能,但我们还没有听说有人这样做。最简单的方法是使用Layer 3交换机并进行Layer 2 MAC重写,将流量发送到您的缓存。如果您使用的是路由器,那么您需要找到一种方法来解封装路由器发送到您的Windows缓存的GRE/WCCP流量(这是您操作系统的功能,而不是Squid的功能)。
🔗 我在哪里可以找到更多关于WCCP的信息?
Cisco在其网站上有一些关于WCCP的精彩内容。其中一个更好的文档列出了功能并描述了如何在他们的路由器上配置WCCP,可以在他们的网站此处找到。
还有一个更技术性的文档描述了WCCP数据包的格式,请访问Colasoft。
🔗 运行WCCP所需的Cisco路由器软件
这取决于您使用的是交换机还是路由器。
🔗 Cisco路由器中的IOS支持
几乎所有Cisco路由器都支持WCCP,前提是您运行的是IOS 12.0或更高版本,但一些运行旧软件的路由器需要升级其软件功能集到“PLUS”功能集或更高版本。WCCPv2在最近的IPBASE版本中的几乎所有路由器上都得到支持。
Cisco的Feature Navigator列出了支持WCCPv2的平台。
通常,您应该为您路由器运行最新版本的IOS。我们不建议您运行T或分支版本,除非您在部署前已在测试环境中完全测试过它们,因为WCCP需要IOS的许多部分才能可靠工作。最新的主线12.1、12.2、12.3和12.4版本通常是最佳选择,并且应该是最少出问题的。
请注意,您需要设置一个GRE或WCCP隧道到您的缓存,以解封装您的路由器发送给它的数据包。
🔗 Cisco交换机中的IOS支持
高端Cisco交换机支持Layer 2 WCCPv2,这意味着以太网帧的下一跳/目标MAC地址会被重写为您的缓存引擎的MAC地址,而不是使用GRE隧道传输。这比路由器/GRE重定向方法在硬件上处理速度更快,实际上在某些平台(如6500系列)上,这可能是配置WCCP的唯一方法。据称,L2重定向在高端6500 Sup卡上能够重定向超过3000万PPS。
已知的能够支持 WCCPv2 的 Cisco 交换机包括 Catalyst 3550(仅支持非常基础的 WCCP)、Catalyst 4500-SUP2 及以上型号,以及所有 6000/6500 型号。
请注意,Catalyst 2900、3560、3750 和 4000 的早期 Supervisor(取决于 iOS 版本)不支持 WCCP。
Layer 2 WCCP 是 WCCPv2 的一项功能,在 cisco 的 WCCPv1 实现中不存在。
WCCPv2 Layer 2 重定向已添加到 12.1E 和 12.2S 版本中。
在部署 WCCP 之前,始终建议阅读您交换机上运行的软件版本的发行说明。
🔗 Cisco 防火墙(PIX OS)中的软件支持
cisco PIX 软件 7.2(1) 版本现在也支持 WCCP,允许您使用此设备进行 WCCP 重定向,而无需路由器执行重定向。
7.2(1) 已通过测试并验证可与 Squid-2.6 协同工作。
🔗 WCCPv2 如何?
WCCPv2 是 Squid-2.6 和 Squid-3.0 的一项新功能。WCCPv2 的配置与 WCCPv1 的配置类似。squid.conf 中的指令略有不同,但在该文件中都有详细记录。WCCPv2 的路由器配置完全相同,只是您不能强制路由器使用 WCCPv1(除非您另行指定,否则它默认为 WCCPv2)。
🔗 配置您的路由器
在 Cisco 路由器上配置 WCCP 有两种不同的方法。第一种方法适用于仅支持协议 V1.0 的路由器。第二种方法适用于支持两者的路由器。
🔗 WCCP 的缓存/主机配置
这分为两部分。首先,您需要配置 Squid 以支持 WCCP,此外,您还需要配置您的操作系统以解封装来自路由器的 WCCP 流量。
🔗 配置 Squid 以支持 WCCP
这些配置指令在 squid.conf 中都有详细记录。
对于 WCCPv1,您需要这些指令
wccp_router a.b.c.d
wccp_version 4
wccp_incoming_address e.f.g.h
wccp_outgoing_address e.f.g.h
- a.b.c.d 是您的 WCCP 路由器的地址
- e.f.g.h 是您希望 WCCP 请求的进出地址。如果您不确定或缓存上只有一个 IP 地址,请勿指定这些。
注意:请勿同时在您的 squid.conf 中配置 WCCPv1 指令(wccp_*)和 WCCPv2(wccp2_*)选项。Squid 一次只支持一种版本的配置,即 WCCPv1 或 WCCPv2。如果未配置,则未配置的版本(或版本)将不会启用。如果您配置了这两组选项,可能会发生不可预测的情况。
对于 WCCPv2,您将需要类似以下的配置
wccp2_router a.b.c.d
wccp2_version 4
wccp2_forwarding_method 1
wccp2_return_method 1
wccp2_service standard 0
wccp2_outgoing_address e.f.g.h
- 如果使用路由器和 GRE/WCCP 隧道,请将 wccp_forwarding_method 和 wccp2_return_method 设置为 **1**;如果使用 Layer 3 交换机进行转发,请设置为 **2**。
- 您的 wccp2_service 应设置为 **standard 0**,这是标准的 HTTP 重定向。
- a.b.c.d 是您的 WCCP 路由器的地址
- e.f.g.h 是您希望 WCCP 请求的进出地址。如果您不确定或缓存上只有一个 IP 地址,请不要指定这些参数,因为它们通常是不需要的。
现在您需要继续阅读有关配置您的操作系统以支持 WCCP 的详细信息。
🔗 配置 FreeBSD
FreeBSD 首先需要配置以接收和剥离来自路由器的 GRE 封装的 GRE 封装。步骤取决于您的内核版本。
🔗 FreeBSD 4.8 及更高版本
操作系统现在标配了一些 GRE 支持。您需要构建一个启用 GRE 代码的内核
pseudo-device gre
然后配置隧道,以便接受路由器的 GRE 数据包
# ifconfig gre0 create
# ifconfig gre0 $squid_ip $router_ip netmask 255.255.255.255 up
# ifconfig gre0 tunnel $squid_ip $router_ip
# route delete $router_ip
或者,您可以尝试这样做
ifconfig gre0 create
ifconfig gre0 $squid_ip 10.20.30.40 netmask 255.255.255.255 link1 tunnel $squid_ip $router_ip up
由于 WCCP/GRE 隧道是单向的,Squid 永远不会向 10.20.30.40 发送任何数据包,因此该特定地址无关紧要。
🔗 FreeBSD 6.x 及更高版本
FreeBSD 6.x 默认在内核中支持 GRE。它还支持 WCCPv1 和 WCCPv2。根据 gre(4) 手册页:“由于无法可靠地区分 WCCP 版本,因此应使用 link2 标志手动配置。如果未设置 link2 标志(默认),则选择 WCCP 版本 1。”其余配置与 4.8+ 相同。
🔗 标准 Linux GRE 隧道
早于 2.6.9 的 Linux 版本可能需要打补丁才能支持 WCCP。这就是为什么我们强烈建议您运行最新版本的 Linux 内核,因为如果您运行的是最新版本,您只需 modprobe 该模块即可获得其功能。
通过在您的内核配置中选择适当的选项,确保 GRE 代码是静态编译还是作为模块编译。然后重新编译您的内核。如果它是模块,您将需要
modprobe ip_gre
下一步是告诉 Linux 在路由器和您的主机之间建立 IP 隧道。
ip tunnel add wccp0 mode gre remote <Router-External-IP> local <Host-IP> dev <interface>
ip addr add <Host-IP>/32 dev wccp0
ip link set wccp0 up
或者,如果使用旧的网络工具
iptunnel add wccp0 mode gre remote <Router-External-IP> local <Host-IP> dev <interface>
ifconfig wccp0 <Host-IP> netmask 255.255.255.255 up
<Router-External-IP> 是正在拦截 HTTP 数据包的路由器的外部 IP 地址。<Host-IP> 是您的缓存的 IP 地址,而 <interface> 是接收这些数据包的网络接口(可能是 eth0)。
请注意,WCCP 与 Linux 中的 rp_filter 功能不兼容,如果启用了该功能,您必须禁用它。如果启用,由 WCCP 重定向并被 Netfilter/iptables 拦截的任何数据包都将由于其“意外”的 gre 接口来源而被 TCP/IP 堆栈静默丢弃。
echo 0 >/proc/sys/net/ipv4/conf/wccp0/rp_filter
然后,您需要告诉 Linux NAT 内核将 wccp0 接口上的入站流量重定向到 Squid
iptables -t nat -A PREROUTING -i wccp0 -j REDIRECT --redirect-to 3128
🔗 TProxy 拦截
🔗 TProxy v2.2
TProxy 是 Squid-2.6 中的一项新功能,它增强了标准的拦截缓存,使其能够进一步隐藏您的缓存的存在。通常,使用拦截缓存时,远程服务器将您的缓存引擎视为 HTTP 请求的来源。TProxy 将此进一步发展,通过隐藏您的缓存引擎,使最终客户端被视为请求的来源(尽管实际上并非如此)。
以下是Steven Wilton 关于如何正确使用 TProxy 的一些说明
我已成功使用 TProxy + WCCPv2 与 squid 2.6。有一些事情需要完成
- 内核和 iptables 需要使用 tproxy 补丁进行打补丁(并且 tproxy include 文件需要放置在 /usr/include/linux/netfilter_ipv4/ip_tproxy.h 或 squid src tree 的 include/netfilter_ipv4/ip_tproxy.h 中)
- iptables 规则需要使用 TPROXY 目标(而不是 REDIRECT 目标)将端口 80 的流量重定向到代理。即
iptables -t tproxy -A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j TPROXY --on-port 80 - 内核必须剥离入站数据包的 GRE 头(使用 ip_wccp 模块,或在 Linux 中设置指向路由器的 GRE 隧道(路由器上不需要 GRE 设置))
- 必须使用两个 WCCP 服务,一个用于出站流量,一个用于从 Internet 返回流量。我们在 squid.conf 中使用以下 WCCP 定义
wccp2_service dynamic 80 wccp2_service_info 80 protocol=tcp flags=src_ip_hash priority=240 ports=80 wccp2_service dynamic 90 wccp2_service_info 90 protocol=tcp flags=dst_ip_hash,ports_source priority=240 ports=80 - 强烈建议为这两个 WCCP 服务使用上述定义,否则如果您有多个缓存,事情将会出错(特别是,当 Web 服务器的名称解析为多个 IP 地址时,您将遇到问题)。
- 您要重定向到的 http 端口必须启用 transparent 和 tproxy 选项,如下所示(根据需要修改端口):http_port 80 transparent tproxy
- 必须定义 tcp_outgoing 地址。这将需要是有效的,以满足任何非 tproxied 连接。
- 在路由器上,您需要确保所有进出客户的流量都将被 **两个** WCCP 规则处理。我们实现此目的的方法是将 WCCP 服务 80 应用于从面向客户的接口进入的所有流量,并将 WCCP 服务 90 应用于从面向客户的接口出去的所有流量。我们还将 WCCP *exclude-in* 规则应用于从面向代理的接口进入的所有流量,尽管如果所有缓存都已注册到 WCCP 路由器,这通常可能不是必需的。即
interface GigabitEthernet0/3.100 description ADSL customers encapsulation dot1Q 502 ip address x.x.x.x y.y.y.y ip wccp 80 redirect in ip wccp 90 redirect out interface GigabitEthernet0/3.101 description Dialup customers encapsulation dot1Q 502 ip address x.x.x.x y.y.y.y ip wccp 80 redirect in ip wccp 90 redirect out interface GigabitEthernet0/3.102 description proxy servers encapsulation dot1Q 506 ip address x.x.x.x y.y.y.y ip wccp redirect exclude in - 强烈建议在 squid.conf 中将 httpd_accel_no_pmtu_disc 设置为 on。
TProxy 软件的主页位于 balabit.com。
🔗 TProxy v4.1+
从 Squid 3.1 开始,对 TProxy 的支持与 Linux 内核的 netfilter 组件紧密相连。有关详细信息,请参阅 TProxy v4.1 Feature。
🔗 其他配置示例
用户贡献的、拥有正在运行的安装的配置可以在 ConfigExamples/Intercept 部分找到,以获取最新详细信息。
如果您已成功配置您的操作系统以支持与 Squid 的 WCCP,请联系我们或将详细信息添加到此 wiki,以便他人受益。
🔗 完成
到现在为止,如果您已遵循文档,您应该已经拥有一个正在运行的拦截缓存系统。通过取消浏览器中的所有代理设置并从您的系统浏览出去来验证这一点。您应该在您的 access.log 中看到您在浏览器中访问的站点的条目。如果您的系统没有按预期工作,您需要继续阅读下面的故障排除部分。
🔗 故障排除和问题
🔗 它不起作用。如何调试?
- 首先测试您的缓存。检查以确保您已使用正确的配置选项配置了 Squid - squid -v 将告诉您 Squid 的配置选项。
- 您能否手动配置您的浏览器与代理端口通信?如果不能,您很可能遇到了代理配置问题。
- 您是否尝试卸载您缓存和/或网络设备内部地址上的所有防火墙规则,看看是否有帮助?如果您的路由器或缓存无意中阻止或丢弃了 WCCP 控制流量或 GRE,则将无法正常工作。
- 如果您在 cisco 路由器或交换机上使用 WCCP,路由器是否看到了您的缓存?使用命令 show ip wccp web-cache detail。
- 查看您的日志,包括 Squid(cache.log)以及您的路由器/交换机上的日志,其中 show log 很可能告诉您它是否检测到您的缓存引擎已注册。
- 在您的 Squid 缓存上,将 `debug_options ALL,1 80,3` 设置为 `debug_options ALL,1 80,3`,或者为了获得更多细节,请设置为 `debug_options ALL,1 80,5`。输出将在您的 cache.log 中。
- 在您的 cisco 路由器上,启用 WCCP 调试
router#term mon router#debug ip wccp events WCCP events debugging is on router#debug ip wccp packets WCCP packet info debugging is on router# -
完成调试会话后,请勿忘记将其关闭,因为它会影响路由器的性能。 - 在您的缓存接口上运行 tcpdump 或 ethereal,并查看流量,尝试弄清楚正在发生什么。您应该看到到端口 2048 和从端口 2048 的 UDP 数据包以及带有 TCP 的 GRE 封装流量。如果您看到关于“不支持的协议”或“无效的协议”的消息,则表示您的 GRE 或 WCCP 模块未加载,并且您的缓存正在拒绝流量,因为它不知道如何处理。
- 您是否配置了 *wccp_* 和 *wccp2_* 选项?您应该只配置其中一个,而不是两者都配置。
- 人们遇到的最常见问题是路由器和缓存正在相互通信,并且流量正在从路由器重定向,但流量解封装过程要么损坏,要么(几乎总是如此)配置错误。这通常是您的缓存上的流量重写规则未能正确应用的问题(请参阅上面的第 2 部分 - 将您的流量路由到 Squid 缓存上的正确端口)。
- 在您的路由器或交换机上运行软件系列的最新通用部署 (GD) 版本。损坏的 IOS 也可能导致重定向失败。对于没有明显 WCCP 损坏的路由器,一个已知良好的 IOS 版本是 12.3(7)T12。在 12.3(8)T 及更早的 12.4(x) 版本中,WCCP 存在大量损坏。12.4(8) 在您不对缓存所在的接口执行 ip firewall inspection 的情况下可以正常工作。
如果以上步骤都没有提供任何有用的线索,请将重要信息(包括您的路由器、代理、操作系统版本、流量重定向规则、调试输出以及您尝试过的其他事项)发布到 squid-users 邮件列表中。
🔗 为什么我不能将身份验证与拦截代理一起使用?
拦截代理的工作方式是让一个代理(代理)出现在本应不存在的地方。浏览器并不期望它在那里,并且实际上是被欺骗了,或者最多是被混淆了。作为该浏览器的用户,我要求它不要向意外方泄露任何凭据,您不这么认为吗?尤其是当用户代理能够这样做而不通知用户时,例如 Microsoft 浏览器在代理提供任何 Microsoft 设计的身份验证方案(如 NTLM)时(请参阅 ProxyAuthentication 和 NegotiateAuthentication)。
换句话说,这不是一个 squid 错误,而是 **浏览器安全** 功能。
🔗 我可以使用‘‘proxy_auth’’ 与拦截一起使用吗?
不可以。请参阅上一问题的答案。使用拦截代理时,客户端认为它正在与原始服务器通信,并且永远不会发送 *Proxy-authorization* 请求头。
🔗 “Connection reset by peer” 和 Cisco 策略路由
Fyodor 已经追踪到了在使用 Cisco 策略路由劫持 HTTP 请求时出现异常的“Connection reset by peer”消息的原因。
当路由器和缓存之间的网络连接短暂中断时,本应重定向的数据包会被发送到默认路由。如果发生这种情况,来自客户端主机的 TCP ACK 可能会发送到原始服务器,而不是被分流到缓存。原始服务器在收到意外的 ACK 数据包时,会向客户端发送 TCP RESET,从而中止客户端的请求。
为了解决这个问题,您可以为缓存地址安装一个指向 *null0* 接口的静态路由,该路由具有更高的度量(较低的优先级),例如 250。
然后,当链路中断时,来自客户端的数据包就会被丢弃,而不是发送到默认路由。例如,如果 1.2.3.4 是您的 Squid 缓存的 IP 地址,您可以添加
ip route 1.2.3.4 255.255.255.255 Null0 250
这似乎能产生正确的行为。
🔗 关于使用 Squid 配置拦截缓存的更多信息
Duane Wessels 撰写了关于 Web 缓存的 O'Reilly 书籍,这是 Squid(以及实际上非 Squid)缓存管理员的宝贵参考指南。他书籍中关于“拦截代理和缓存”的章节样本在线提供,网址为 O'Reilly。
🔗 HotMail 的问题
Hotmail 已知会受到 HTTP/1.1 Transfer Encoding 问题的影响。有关更多详细信息以及一些解决方案,请参阅 文章。
回到 FAQ 索引
导航: 网站搜索、网站页面、分类、🔼 向上