7 votes

Le serveur n'envoie pas de paquet SYN/ACK en réponse à un paquet SYN.

En utilisant iptraf, tcpdump et wireshark, je peux voir un paquet SYN arriver mais seul le FLAG ACK est défini dans le paquet de réponse.

Je suis sous Debian 5 avec le noyau 2.6.36.

J'ai désactivé window_scaling et tcp_timestamps, tcp_tw_recycle et 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

J'ai joint une image de la sortie de Wireshark.

http://imgur.com/pECG0.png

Sortie vers netstat

netstat -natu | grep '72.23.130.104'

tcp        0      0 97.107.134.212:18000    72.23.130.104:42905     SYN_RECV

J'ai fait tout ce que j'ai pu pour trouver une solution, mais je n'ai toujours pas trouvé le problème. Toute aide ou suggestion est donc la bienvenue.

MISE À JOUR 1 : J'ai défini tcp_syncookies = 0 et j'ai remarqué que je réponds maintenant avec 1 SYN+ACK pour chaque 50 demandes SYN. L'hôte qui essaie de se connecter envoie une demande SYN environ une fois par seconde.

FICHIER PCAP

7voto

radius Points 9485

Après avoir eu le même problème, j'ai finalement trouvé la cause première.

Sous Linux, lorsqu'une socket est sur TIME_WAIT et qu'un nouveau SYN est ajouté (pour la même paire ip/port src, ip/port dest), le noyau vérifie si le numéro de SEQ du SYN est < ou > au dernier SEQ reçu pour cette socket.

(PS : dans l'image de la sortie de wireshark jointe à ce problème, les numéros de seq sont montrés comme relatifs, si vous ne les mettez pas comme absolus vous ne pouvez pas voir le problème. La capture devrait également montrer l'ancienne session pour pouvoir comparer les numéros de SEQ).

  • si le numéro SEQ du SYN est > au numéro SEQ du paquet précédent, une nouvelle connexion est créée et tout fonctionne.
  • si le numéro de SEQ du SYN est < au numéro de SEQ du paquet précédent, le noyau enverra un ACK relatif à la socket précédente car le noyau pense que le SYN reçu est un paquet retardé de la socket précédente.

Ce comportement est dû au fait qu'au début de TCP, les numéros de SEQ générés par les ordinateurs étaient incrémentiels, il était presque impossible de recevoir un numéro de SEQ inférieur au numéro de SEQ d'une socket précédente toujours en TIME_WAIT.

L'augmentation de la bande passante des ordinateurs fait que cela est passé de presque impossible à rare. Mais le plus important est qu'aujourd'hui la plupart des systèmes utilisent un numéro ISN (initial SEQ number) aléatoire pour améliorer la sécurité. Rien n'empêche donc le numéro SEQ d'un nouveau socket d'être > au numéro SEQ d'un socket précédent.

Chaque système d'exploitation utilise des algorithmes différents qui sont plus ou moins sûrs pour éviter ce problème particulier. http://www.bsdcan.org/2006/papers/ImprovingTCPIP.pdf donner une bonne présentation de la question.

Il y a un dernier point délicat... le noyau enverra donc un ACK relatif à l'ancienne session, alors ? L'OS client devrait recevoir l'ACK (de la session précédente), ne le comprend pas car pour le client la session est fermée, envoie un RST. Lorsque le serveur reçoit ce RST, il efface immédiatement le socket (il n'est donc plus en TIME_WAIT). De son côté, le client attend un SYN/ACK, s'il ne le reçoit pas, il enverra un nouveau SYN . Entre-temps, le RST a été envoyé et la session a été effacée sur le serveur, donc ce second SYN fonctionnera et le serveur répondra SYN/ACK et ainsi de suite.

Le comportement normal est donc que la connexion devrait fonctionner mais être retardée d'une seconde (jusqu'à ce que le SYN secondaire soit envoyé). Dans le cas de Jeff, il a dit dans un commentaire qu'il utilise un firewall Fortinet, ce firewall (par défaut) abandonnera l'ACK lié à l'ancienne session (parce que le firewall ne voit pas de session ouverte liée à l'ACK), donc le client n'envoie pas de RST et le serveur ne peut pas effacer la session de l'état TIME_WAIT (sauf bien sûr à la fin du timer TIME_WAIT). La commande "set anti-replay loose" sur fortinet peut permettre à ce paquet ACK d'être transmis au lieu d'être abandonné.

3voto

MikeyB Points 38317

Il semble que 97.107.134.212 croit déjà qu'il y a une connexion (72.23.130.104:42905, 97.107.134.212:18000) .

Quand 72,2

Mais il envoie un ACK avec SEQ=1736793629 et ACK=172352206. Ce sont probablement des valeurs provenant d'une connexion antérieure.

Toute nouvelle tentative de connexion devrait provenir d'un numéro de port différent... est-ce le cas ? Wireshark le signale dans le pkt#11 : "TCP Port numbers reused".

On dirait que le problème se situe au niveau de l'émetteur.

FWIW, je peux me connecter juste bien :

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

1voto

sysadmin1138 Points 129885

La seule fois où j'ai vu cela auparavant, c'était parce que les paquets sortants et entrants empruntaient des routes différentes sur le réseau, et qu'il y avait un dispositif de suivi des connexions avec état sur la branche entrante. Comme ce dispositif (un équilibreur de charge dans mon cas, mais il pourrait tout aussi bien s'agir d'un pare-feu) n'a jamais vu le SYN initial, le SYN-ACK a été abandonné au sol comme faux.

0voto

Paul Points 1228

Ce doit être plus qu'une simple asymétrie, car il nous manque aussi un paquet sortant :

Le SYN sort, mais nous ne voyons pas le SYN-ACK entrant, ou l'ACK sortant du serveur local. Quelque chose d'autre a donc dû envoyer ces deux paquets par procuration, puis nous voyons l'ACK entrant - qui est en fait le quatrième paquet de la séquence.

Je pense à un accélérateur WAN mal configuré entre les deux.

0voto

Daniel Points 310

Je vérifierais certaines choses :

Votre hôte est-il multi-homed (c.-à-d. avez-vous plus d'une interface ethernet ?) - si c'est le cas, vos routes peuvent être faussées. La façon la plus simple de tester cela serait de désactiver votre ou vos interfaces secondaires et de voir si le problème disparaît.

Il faut également vérifier si iptables (ou un autre pare-feu) est activé. Le service iptables stop le désactivera jusqu'au prochain redémarrage. Si cela résout le problème, vous devez modifier les paramètres d'iptables.

De même, si l'IPv6 est activé sur votre interface, il arrive qu'il y ait une route sur l'ipv4 mais pas sur l'ipv6. Lorsque cela se produit, et que la route ipv6 est la route "par défaut", vos paquets peuvent passer par la mauvaise adresse (même sur la bonne interface). Essayez de désactiver ipv6 pour voir si c'est le problème.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X