9.5 配置
Squid假如你使用Linux 2.4和iptables,在运行./configure时,可使用--enable-linux-netfilter选项。它激活某些Linux的特殊代码,以发现发起请求的原始服务器的IP地址。Squid正常情况下从Host头部,得到原始服务器的名字(和/或地址)。--enable-linux-netfilter功能仅对没有Host头部的请求来说是必要的。统计显示几乎所有的请求有Host头部,所以实际中可以不使用--enable-linux-netfilter选项。
假如正在使用IPFilter包(NetBSD,Solaris,或其他),因为同样的理由,你应该使用--enable-ipf-transparent选项。在OpenBSD上,请使用--enable-pf-transparent选项。每次运行./configure时,必须重编译squid,见3.8章的描述。
在运行了./configure和重编译了squid后,可以编辑squid.conf文件。作为起点,请确认下列指令定义了给定的值:
httpd_accel_host virtualhttpd_accel_port 80httpd_accel_uses_host_header onhttpd_accel_with_proxy onhttpd_accel_single_host off
http_accel_host指令是关键。它指示squid接受包含局部URI的HTTP请求。httpd_accel_uses_host_header被激活,允许squid使用Host头部来重新构建完整URI。virtual关键字指示squid在缺乏Host头部时,将原始服务器的IP地址放进URL里。
httpd_accel_with_proxy指令控制squid是否既接受HTTP服务(部分URI)请求,又接受代理(完整URI)请求。在cache拦截里,它应该被激活。如果没有用户明确的配置使用squid做代理,那即使httpd_accel_with_proxy没被激活,squid也能工作。
httpd_acces_single_host指令正常情况下被禁止,在早期版本的squid里,它可能被默认激活。在cache拦截里,它应明确被禁止。
假如拦截不止针对80端口,你也许该将httpd_accel_port设为0。见附录A的更多信息。
假如你没有使用WCCP,就该准备开始发起拦截会话到squid了。通过使用浏览器来上网冲浪,或者使用squidclient发起测试请求,就可以放手一试。假如你使用WCCP,那么还有许多步骤要完成。9.5.1 配置WCCPv1路由器不发送任何会话到squid,直到squid宣称它自己是路由器。为了让squid那样做,在squid.conf中增加如下行:
wccp_router 172.16.102.65wccp_version 4
路由器有多个接口。请确认使用与squid相连的接口的IP地址。这点是必要的,因为来自路由器的WCCP消息,将源IP地址设置为外出接口的地址。假如源地址不匹配wccp_router值,squid会拒绝WCCP消息。
WCCPv1文档规定4作为协议版本号。然而,某些用户报告,Cisco IOS 11.2仅支持协议版本3。假如你使用该版本的IOS,请在squid.conf里改变版本号:
wccp_version 3
9.6 调试问题HTTP拦截比较复杂,因为许多不同设备必须组合正确工作。为了帮助你跟踪问题,如下是一个问题解答检查列表:
- * 客户端数据包正在通过路由器/交换机吗?
- 在简单网络里,这点显而易见。你可以trace线缆并观察指示灯的活动闪烁。然而在大而复杂的网络,数据包可能走不同的路线。假如你的组织够大,并有网络sniffer设备,就可以观察线路中web客户端的请求数据包。低技术的方法是,断开有问题的线路,并观察是否影响客户端的web浏览。
- * 路由器/交换机配置是否正确?
- 你也许要再次检查路由器/交换机配置。假如你已配置了某个接口,那能否确保它正确呢?是否新的配置真正在设备上运行?也许在你保存配置之前,路由器/交换机已重启了。在改变生效前,你或许需要reboot设备。
- * 交换机/路由器能与squid主机会话吗?
- 能从路由器/交换机上ping通squid吗?大部分4层拦截配置要求网络设备和squid在同一子网里。登陆路由器/交换机,确认能ping通squid的IP地址。
- * 交换机/路由器相信squid在运行吗?
- 许多传输拦截设备不会发送会话到squid,除非它们知道squid是健壮的。使用调试命令来预览squid的健壮性状态。也许会发现三层健壮性检测(例如ICMP ping)比四层检测(例如HTTP)更容易,它使网络设备更容易将squid标记为存活状态。
- * Squid实际在运行吗?
- 请再次确认squid真正在运行,特别是在系统近期重启过的情况下。
- * 数据包正在抵达squid主机吗?
- 使用tcpdump能见到拦截的TCP连接。如下是示例: # tcpdump -n -i eth0 port 80
假如使用WCCP,请检查来自路由器的GRE包: # tcpdump -n -i eth0 ip proto gre
假如没有看到tcpdump的任何输出,则路由器/交换机可能没有发送任何数据。在这种情况下,返回到以前的建议。 注意,假如设备正使用四层健壮性检测,你可以在tcpdump的输出里见到这些。健壮性检测来自路由器/交换机的IP地址,所以它们容易被认出。假如你见到健壮性检测,但没有其他数据,那可能意味着路由器/交换机正把squid的响应理解为不健壮。例如,设备可能想见到200(OK)响应,但squid返回一个错误,例如401(未授权)或404(未发现)。请对access.log运行tail -f命令。
- * 激活了IP转发吗?
- 请再次确认squid运行的操作系统配置了IP包转发。假如没有,主机可能会丢弃拦截数据包,因为目的IP地址并非本地。
- * 配置包过滤了吗?
- 请确认包过滤器(例如ipfw,iptables,pf等)配置正确。当每件事都运行良好时,你能定期运行命令来显示过滤规则,并观察计数器增长。例如: # ipfw show 300 ; sleep 3; ipfw show 30000300 86216 8480458 fwd 127.0.0.1,3128 tcp from any to any 80 in00300 86241 8482240 fwd 127.0.0.1,3128 tcp from any to any 80 in
注意该示例在FreeBSD上,包和字节计数器(第二和第三列)正在增长。
- * 环路接口起来和配置了吗?
- 假如有一条规则转发/重定向包到127.0.0.1,请确认环路接口(例如lo0,lo等)起来了,并配置过它。假如没有,内核简单的跳过这条转发/重定向规则。
- * WCCP/GRE包被正确解开了吗?
- 假如使用WCCP,请确认GRE包被正确解开。假如因为某些理由,系统不知道该如何处理GRE包,那就在netstat -s的输出里会见到"unknown/unsupported protocol"计数器在增长。 # netstat -s | grep unknown 46 packets for unknown/unsupported protocol
假如OS有GRE接口,请频繁运行netstat -i命令,观察不断增长的包数量: # netstat -in | grep ^gre0Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Collgre0 1476 <Link#4>304452 0 0 4 0
另外,在GRE接口上运行tcpdump: # tcpdump -n -i gre0
- * Squid能响应客户端吗?
- 有可能路由器/交换机能发送包到squid,但squid不能将包发送回客户端。这种情况可能发生在:防火墙过滤规则拒绝外出数据包,或squid没有到客户端IP地址的路由。为了检查这种情况,请运行netstat -n并观察SYN_RCVD状态的sockets: % netstat -nActive Internet connectionsProto Recv-Q Send-Q Local Address Foreign Address (state)tcp4 0 0 10.102.129.246.80 10.102.0.1.36260 SYN_RCVDtcp4 0 0 10.102.129.226.80 10.102.0.1.36259 SYN_RCVDtcp4 0 0 10.102.128.147.80 10.102.0.1.36258 SYN_RCVDtcp4 0 0 10.102.129.26.80 10.102.0.2.36257 SYN_RCVDtcp4 0 0 10.102.129.29.80 10.102.0.2.36255 SYN_RCVDtcp4 0 0 10.102.129.226.80 10.102.0.1.36254 SYN_RCVDtcp4 0 0 10.102.128.117.80 10.102.0.1.36253 SYN_RCVDtcp4 0 0 10.102.128.149.80 10.102.0.1.36252 SYN_RCVD
假如你看到这些,请使用ping和traceroute来确认squid能与客户端双向通信。
- * Squid能与原始服务器会话吗?
- 假如squid不能连接到原始服务器,拦截HTTP连接会无法进行。如果这点发生,netstat会显示许多连接在SYN_SENT状态: % netstat -nActive Internet connectionsProto Recv-Q Send-Q Local Address Foreign Address (state)tcp4 0 0 172.16.102.66.5217 10.102.129.145.80 SYN_SENTtcp4 0 0 172.16.102.66.5216 10.102.129.224.80 SYN_SENTtcp4 0 0 172.16.102.66.5215 10.102.128.71.80 SYN_SENTtcp4 0 0 172.16.102.66.5214 10.102.129.209.80 SYN_SENTtcp4 0 0 172.16.102.66.5213 10.102.129.62.80 SYN_SENTtcp4 0 0 172.16.102.66.5212 10.102.129.160.80 SYN_SENTtcp4 0 0 172.16.102.66.5211 10.102.128.129.80 SYN_SENTtcp4 0 0 172.16.102.66.5210 10.102.129.44.80 SYN_SENTtcp4 0 0 172.16.102.66.5209 10.102.128.73.80 SYN_SENTtcp4 0 0 172.16.102.66.5208 10.102.128.43.80 SYN_SENT
再次用ping和traceroute来确认squid能与原始服务器会话。
- * 外出连接正被拦截吗?
- 假如squid能ping通原始服务器,并且仍然见到大量的连接在SYN_SENT状态,那么路由器/交换机可能正在拦截squid的外出TCP连接。在某些情况下,squid能检测到这种转发循环,并写警告日志到cache.log。如此的转发死循环能迅速耗光squid的所有文件描述符,这样也会在cache.log里产生警告。
假如你怀疑这个问题,请使用squidclient程序来发起一些简单的HTTP请求。例如,该命令发起一条直接到原始服务器的HTTP请求:
% /usr/local/squid/bin/squidclient -p 80 -h slashdot.org /
假如该命令成功,你可以在屏幕上见到来自Slashdot站点的许多难看的HTML。然后通过squid来试试同样的请求:
% /usr/local/squid/bin/squidclient -r -p 3128 -h 127.0.0.1 http://slashdot.org/
假如没有在cache.log里看到错误消息,就可以再次在屏幕上看到一些HTML。假如看到转发循环错误,就必须重新配置交换机/路由器,以便它允许squid的外出连接正常通过,而不被拦截。