O seguinte é um despejo wireshark do problema ocorrendo, endereços IP substituídos por 'client' e '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
Assim, a seqüência normal SYN, SYN + ACK, ACK parece ocorrer, exceto que o servidor não parece interpretar o ACK. Em vez disso, ele continua reenviando o SYN + ACK, ao qual o cliente obedientemente responde respondendo com uma duplicata do ACK anterior. Não vejo como isso possa acontecer.
Percebi o problema porque o rastreamento de conexões do iptables considera essas conexões estabelecidas e as mantém na memória por um tempo limite total de 120 horas. Eu tenho algumas regras de firewall para evitar um grande número de conexões simultâneas, os limites que as pessoas estavam atingindo, sem realmente ter que muitas conexões ativas. O comando netstat
não mostra essas conexões fantasmas.
Outras informações:
O servidor é um sistema debian lenny padrão com um kernel padrão:
Linux tb 2.6.26-2-686 #1 SMP Wed Aug 19 06:06:52 UTC 2009 i686 GNU/Linux
em execução:
Apache/2.2.9 (Debian) mod_ssl/2.2.9 OpenSSL/0.9.8g
Não tenho todas as informações sobre o cliente (não consigo reproduzir localmente), mas é um Mac que executa o navegador Chrome.
Eu não tenho nenhuma regra de firewall mexendo com pacotes ACK. Basicamente eu apenas filtro pacotes SYN, todos os outros pacotes TCP são permitidos. Portanto, na verdade, não uso o rastreamento de conexão para firewall, além de contar as conexões simultâneas e alguns gráficos dos pacotes Estabelecidos no TCP em comparação com outros tipos de pacotes.
Edit: minhas regras do iptables relacionadas à porta 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
Editar 2: outro dump, desta vez usando 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>