Servidor não enviando um pacote SYN / ACK em resposta a um pacote SYN

6

Usando iptraf, tcpdump e wireshark, consigo ver um pacote SYN chegando, mas somente o ACK FLAG é definido no pacote de resposta.

Estou usando o Debian 5 com o kernel 2.6.36

Eu desativei window_scaling e tcp_timestamps, tcp_tw_recycle e tcp_tw_reuse:

cat /etc/sysctl.conf 



net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_timestamps = 0

Eu anexei uma imagem da saída do wireshark.

link

Saída para netstat

netstat -natu | grep '72.23.130.104'

tcp        0      0 97.107.134.212:18000    72.23.130.104:42905     SYN_RECV

Eu tenho feito todo o possível para encontrar uma solução e ainda não descobri o problema, portanto, qualquer ajuda / sugestão é muito apreciada.

UPDATE 1: Eu configurei tcp_syncookies = 0 e notei que agora estou respondendo com 1 SYN + ACK para cada 50 solicitações SYN. O host tentando se conectar está enviando uma solicitação SYN uma vez por segundo.

ARQUIVO PCAP

    
por jeff 03.08.2011 / 16:37

5 respostas

6

Depois de ter o mesmo problema, finalmente percebo a causa raiz.

No Linux, quando um socket está em TIME_WAIT e um novo SYN append (para o mesmo par de ip / port src, ip / port dest), o kernel verifica se o número SEQ do SYN é < ou > que o último SEQ recebido para este socket.

(PS: na imagem da saída do wireshark anexada a este problema, o número do seq é mostrado como relativo, se você não os definir como absolutos, você não pode ver o problema. A captura teria que mostrar o antigo sessão também para poder comparar números SEQ)

  • se o número SEQ do SYN for > que o número SEQ do pacote anterior, uma nova conexão é criada e tudo funciona
  • se o número de SEQ do SYN for < que o número SEQ do pacote anterior, o kernel irá enviar um ACK relacionado ao socket anterior porque o kernel acha que o SYN recebido é um pacote atrasado do socket anterior.

O comportamento é assim porque no início do TCP o número SEQ gerado pelos computadores era incremental, era quase impossível receber um número SEQ < que o número SEQ de um socket anterior ainda em TIME_WAIT.

O aumento da largura de banda dos computadores torna isso quase impossível até raro. Mas as coisas mais importantes aqui são que agora a maioria dos sistemas usa ISN aleatório (número SEQ inicial) para melhorar a segurança. Portanto, nada impede que o número SEQ a do novo socket seja > que o número SEQ de um anterior.

Cada sistema operacional usa diferentes algoritmos que são mais ou menos seguros para evitar esse problema específico O link oferece uma boa apresentação do assunto.

Há uma última coisa complicada ... então o kernel irá enviar um ACK relacionado à sessão antiga, então? O sistema operacional do cliente deve receber o ACK (da sessão anterior), não entendi porque para o cliente a sessão está fechada, envie um RST. Quando o servidor receber este RST, ele limpará imediatamente o soquete (portanto, ele não estará mais em TIME_WAIT). Por seu lado, o cliente está esperando por um SYN / ACK, pois ele não o recebe, ele irá enviar um novo SYN. Enquanto isso, o RST foi enviado ea sessão foi limpa no servidor, portanto, este SYN secundário funcionará e o servidor responderá ao SYN / ACK e assim por diante.

Portanto, o comportamento normal é que a conexão funcione, mas seja atrasada por um segundo (até que o SYN secundário seja enviado). No caso de Jeff, ele disse em um comentário que ele usa um firewall Fortinet, esse firewall (por padrão) descartará o ACK relacionado à sessão antiga (porque o firewall não vê nenhuma sessão aberta relacionada ao ACK), então o cliente não envie qualquer RST e o servidor não poderá limpar a sessão do estado TIME_WAIT (exceto, é claro, no final do temporizador TIME_WAIT). O comando "set anti-replay loose" no fortinet pode permitir que este pacote ACK seja encaminhado ao invés de ser descartado.

    
por 27.06.2013 / 16:12
3

Parece que 97.107.134.212 já acredita que existe uma conexão (72.23.130.104:42905, 97.107.134.212:18000) .

Quando 72.23.130.104:42905 envia seu pacote SYN, seu número de seqüência é 246811966. O próximo deve ser um pacote SYN / ACK com seu próprio número SEQ e um valor ACK de 246811967.

Mas está enviando um ACK com SEQ = 1736793629 e ACK = 172352206. Esses são provavelmente valores de uma conexão anterior.

Qualquer nova tentativa de conexão deve vir de um número de porta diferente ... isso está acontecendo? O Wireshark aponta isso no campo # 11: "Números de porta TCP reutilizados".

Parece que o problema está no remetente.

FWIW, posso conectar apenas bem:

1   0.000000    192.168.0.135   97.107.134.212  TCP 45883 > biimenu [SYN] Seq=809402803 Win=14600 Len=0 MSS=1460 SACK_PERM=1 TSV=2319725 TSER=0 WS=7
2   0.022525    97.107.134.212  192.168.0.135   TCP biimenu > 45883 [SYN, ACK] Seq=4293896301 Ack=809402804 Win=14600 Len=0 MSS=1360 SACK_PERM=1
3   0.022553    192.168.0.135   97.107.134.212  TCP 45883 > biimenu [ACK] Seq=809402804 Ack=4293896302 Win=14600 Len=0
    
por 05.08.2011 / 23:05
1

A única vez que vi isso antes, foi porque os pacotes de saída e entrada estavam tomando rotas diferentes na rede e havia um dispositivo de rastreamento de conexão com estado na perna de entrada. Uma vez que esse dispositivo (um balanceador de carga no meu caso, mas poderia facilmente ser um firewall) nunca vi o SYN inicial, o SYN-ACK foi jogado no chão como espúrio.

    
por 04.08.2011 / 23:50
0

Deve ser mais do que apenas assimetria, porque estamos perdendo um pacote de saída também:

O SYN sai, mas não vemos o SYN-ACK recebido, ou o ACK de saída do servidor local. Então, algo mais deve ter proxies ambos os pacotes e, em seguida, vemos o ACK de entrada - que é realmente o quarto pacote na seqüência.

Meu palpite é um acelerador de WAN mal configurado entre os dois.

    
por 05.08.2011 / 08:43
0

Eu verificaria algumas coisas:

O seu host é multi-homed (por exemplo, você tem mais de uma interface ethernet?) - se assim for, suas rotas podem estar confusas. A maneira mais fácil de testar isso seria desabilitar sua (s) interface (s) secundária (s) e verificar se o problema desaparece.

Outra coisa a verificar é se o iptables (ou algum outro firewall) está habilitado. O serviço iptables stop irá desligá-lo até a próxima reinicialização - se isso resolver o problema, você precisará ajustar as configurações do iptables.

Além disso, se você tiver o IPv6 ativado em sua interface, às vezes há uma rota em ipv4, mas não em ipv6. Quando isso acontece, e a rota ipv6 é o "padrão", seus pacotes podem passar pelo endereço errado (mesmo na interface correta). Tente desativar o ipv6 para ver se esse é o problema.

    
por 17.06.2013 / 19:36