以下是发生问题的wireshark转储,IP地址替换为’client’和’server’:
4414.229553 client -> server TCP 62464 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1452 WS=3 TSV=116730231 TSER=0 4414.229633 server -> client TCP http > 62464 [SYN,ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=2406364374 TSER=116730231 WS=6 4414.263330 client -> server TCP 62464 > http [ACK] Seq=1 Ack=1 Win=524280 Len=0 TSV=116730231 TSER=2406364374 4418.812859 server -> client TCP http > 62464 [SYN,ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=2406365520 TSER=116730231 WS=6 4418.892176 client -> server TCP [TCP Dup ACK 778#1] 62464 > http [ACK] Seq=1 Ack=1 Win=524280 Len=0 TSV=116730278 TSER=2406365520 4424.812864 server -> client TCP http > 62464 [SYN,ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=2406367020 TSER=116730278 WS=6 4424.891240 client -> server TCP [TCP Dup ACK 778#2] 62464 > http [ACK] Seq=1 Ack=1 Win=524280 Len=0 TSV=116730337 TSER=2406367020
因此,正常的SYN,SYN ACK,ACK序列似乎发生,除了服务器似乎没有解释ACK.相反,它继续重新发送SYN ACK,客户端尽职尽责地继续响应前一个ACK的副本.我不知道这是怎么发生的.
我注意到了这个问题,因为iptables连接跟踪会考虑建立这些连接,并将它们保留在内存中120小时的超时时间.我有一些防火墙规则来防止大量的并发连接,人们正在打的限制,而实际上没有那么多连接活动. netstat命令不显示这些幻像连接.
其他信息:
该服务器是一个标准的debian lenny系统,带有一个库存内核:
Linux tb 2.6.26-2-686 #1 SMP Wed Aug 19 06:06:52 UTC 2009 i686 GNU/Linux
运行:
Apache/2.2.9 (Debian) mod_ssl/2.2.9 OpenSSL/0.9.8g
我没有客户端上的所有信息(我无法在本地重现),但它是运行Chrome浏览器的Mac.
我没有任何防火墙规则搞乱ACK数据包.基本上我只过滤SYN数据包,允许所有其他TCP数据包通过.所以我实际上并没有使用连接跟踪进行防火墙,除了计算与其他数据包类型相比的并发连接和TCP建立数据包的一些图形.
编辑:我的iptables规则与TCP端口80有关:
iptables -P INPUT ACCEPT iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 50 -j LOGDROP-CONN iptables -A INPUT -p tcp --syn -m multiport --dports 80,443 -j ACCEPT iptables -A INPUT -p tcp --syn -j REJECT --reject-with tcp-reset iptables -A LOGDROP-CONN -m limit --limit 1/minute --limit-burst 1 -j LOG --log-prefix "ConConn " iptables -A LOGDROP-CONN -j DROP
编辑2:另一个转储,这次使用tcpdump -vv:
16:05:52.999525 IP (tos 0x0,ttl 55,id 46466,offset 0,flags [DF],proto TCP (6),length 64) client.50538 > server.www: S,cksum 0x4429 (correct),38417001:38417001(0) win 65535 <mss 1452,nop,wscale 3,timestamp 117224762 0,sackOK,eol> 16:05:52.999580 IP (tos 0x0,ttl 64,id 0,length 60) server.www > client.50538: S,cksum 0xa2ab (correct),3062713115:3062713115(0) ack 38417002 win 5792 <mss 1460,timestamp 2418739698 117224762,wscale 6> 16:05:53.321788 IP (tos 0x0,id 24299,length 52) client.50538 > server.www: .,cksum 0xe813 (correct),1:1(0) ack 1 win 65535 <nop,timestamp 117224765 2418739698> 16:05:56.252697 IP (tos 0x0,cksum 0x9f7a (correct),timestamp 2418740512 117224765,wscale 6> 16:05:56.277250 IP (tos 0x0,id 15533,cksum 0xe4c4 (correct),timestamp 117224798 2418740512>
解决方法
我蛮力了.首先我会尝试,如果它与iptables停止工作.如果是的话,那就是iptables中的东西.
然后我逐个添加规则并观察哪一个导致连接失败.然后我会玩这个规则,直到它完成我想要的而不会完全扰乱流量.
如果它不能与iptables停止工作,那么它将开始真的很奇怪.