以下是发生问题的一个wireshark转储,用“客户”和“服务器”代替IP地址:
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连接跟踪认为这些连接build立,并保持在内存中完整的120小时超时。 我有一些防火墙规则来防止大量的并发连接,而这些并发连接是人们所触及的极限,而实际上并没有多less连接处于活动状态。 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-Established数据包与其他数据包types相比的一些graphics。
编辑:我的iptables-rules有关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,nop,nop,timestamp 117224762 0,sackOK,eol> 16:05:52.999580 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) server.www > client.50538: S, cksum 0xa2ab (correct), 3062713115:3062713115(0) ack 38417002 win 5792 <mss 1460,sackOK,timestamp 2418739698 117224762,nop,wscale 6> 16:05:53.321788 IP (tos 0x0, ttl 55, id 24299, offset 0, flags [DF], proto TCP (6), length 52) client.50538 > server.www: ., cksum 0xe813 (correct), 1:1(0) ack 1 win 65535 <nop,nop,timestamp 117224765 2418739698> 16:05:56.252697 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) server.www > client.50538: S, cksum 0x9f7a (correct), 3062713115:3062713115(0) ack 38417002 win 5792 <mss 1460,sackOK,timestamp 2418740512 117224765,nop,wscale 6> 16:05:56.277250 IP (tos 0x0, ttl 55, id 15533, offset 0, flags [DF], proto TCP (6), length 52) client.50538 > server.www: ., cksum 0xe4c4 (correct), 1:1(0) ack 1 win 65535 <nop,nop,timestamp 117224798 2418740512>
我会蛮横的。 首先,我会尝试,如果它与iptables停止工作。 如果是这样,那么这是在iptables中的东西。
然后,我会逐一添加规则,并观察哪一个导致连接失败。 然后,我会玩这个规则,直到它做我想要的,而不会完全打乱交通。
如果iptables停止工作,它会开始真的很奇怪。
好的,我没有一个完整的答案,但自从这个问题出现以来,我学到了很多东西。 我会在这里分享我的见解。
telnet www.website.com 80而不是发送任何第三方Web服务器上见证它数据。 尽pipe如此,它仍然是一个Linux特性,因为我testing的服务器可能都运行Linux。 这种行为也没有加载任何iptables-rules,所以它真的是内核相关的。 iptables连接跟踪似乎没有共享这个逻辑,所以那里的连接将保持ESTABLISHED状态,直到它超时。 默认的超时时间是5天(!)。 我打算把这个减less到更明智的地方,比如几个小时。 nc -l ###打开一个监听端口并且连接到它时,我没有看到它。 所以它可能是Apache在其侦听套接字上设置的某个TCP选项。 或者它可能是Apache的独特之处。 大多数其他的守护进程在连接之后立即宣布自己,所以它们不是有效的testing用例。 连接需要进行三次握手,然后立即闲置。 感谢上面给出的见解,他们已经帮助到底了。