Frage Warum würde ein Server kein SYN / ACK-Paket als Antwort auf ein SYN-Paket senden?


In letzter Zeit sind wir auf ein TCP-Verbindungsproblem aufmerksam geworden, das hauptsächlich auf Mac- und Linux-Benutzer beschränkt ist, die unsere Websites durchsuchen.

Aus Sicht der Benutzer stellt es sich als eine wirklich lange Verbindungszeit zu unseren Webseiten dar (> 11 Sekunden).

Es ist uns gelungen, die technische Signatur dieses Problems zu finden, aber wir können nicht herausfinden, warum es passiert oder wie wir es beheben können.

Grundsätzlich passiert, dass der Rechner des Clients das SYN-Paket sendet, um die TCP-Verbindung herzustellen, und der Webserver empfängt sie, antwortet jedoch nicht mit dem SYN / ACK-Paket. Nachdem der Client viele SYN-Pakete gesendet hat, antwortet der Server schließlich mit einem SYN / ACK-Paket und für den Rest der Verbindung ist alles in Ordnung.

Und natürlich, der Kicker zu dem Problem: Es ist intermittierend und passiert nicht die ganze Zeit (obwohl es zwischen 10-30% der Zeit passiert)

Wir verwenden Fedora 12 Linux als Betriebssystem und Nginx als Webserver.

Screenshot der Wireshark-Analyse

Screenshot of wireshark analysis

Aktualisieren:

Durch das Deaktivieren der Fensterskalierung auf dem Client wurde das Problem behoben. Jetzt brauche ich nur eine serverseitige Auflösung (wir können nicht alle Clients dazu bringen) :)

Letzte Aktualisierung:

Die Lösung bestand darin, beide auszuschalten TCP-Fensterskalierung  und  TCP-Zeitstempel auf unseren Servern, die für die Öffentlichkeit zugänglich sind.


37
2018-02-15 22:54


Ursprung


Ich denke, wir müssen sehen, dass etwas passiert. - coredump
Haben Sie irgendwelche Regeln oder Regeln, die auf Reverse-DNS basieren? Möglicherweise müssen Sie sich mehr als nur die Verbindung zwischen dem Client und dem Server ansehen. Vielleicht ist ein DNS-Lookup Timeout? - Zoredache
@coredump: Hier ist ein Screenshot der Wireshark-Analyse, die das Problem zeigt i.imgur.com/Bnnrm.png  (konnte nicht herausfinden, wie man nur den Stream exportiert ....) - codemonkey
@Zoredache: Nein, wir haben keine AIs oder Regeln, die auf Reverse-DNS basieren. Dies ist ein öffentlich zugänglicher Webserver und wir erlauben jedem den Zugriff darauf - codemonkey
Nur eine Ahnung, aber machen Sie irgendeine Art von eingehenden Verbindung Rate-Limiting auf dem Server? Sag, mit iptables? - Steven Monday


Antworten:


Wir hatten genau dasselbe Problem. Das Deaktivieren der TCP-Zeitstempel löste das Problem.

sysctl -w net.ipv4.tcp_timestamps=0

Um diese Änderung dauerhaft zu machen, machen Sie einen Eintrag in /etc/sysctl.conf.

Seien Sie sehr vorsichtig beim Deaktivieren der Option TCP Window Scale. Diese Option ist wichtig für maximale Leistung über das Internet. Jemand mit einer 10-Megabit / s-Verbindung wird eine suboptimale Übertragung haben, wenn die Zeit für eine Rundreise (im Prinzip wie Ping) ist mehr als 55 ms.

Wir haben dieses Problem wirklich bemerkt, als mehrere Geräte hinter demselben NAT waren. Ich vermute, dass der Server möglicherweise verwirrt wurde, Zeitstempel von Android-Geräten und OSX-Maschinen gleichzeitig zu sehen, da sie völlig andere Werte in die Zeitstempelfelder eingetragen haben.


11
2018-04-05 16:26



Für den Fall, dass jemand anderes hier durch dasselbe Kaninchenloch landet, das ich gerade runtergegangen bin: Bevor Sie TCP-Zeitstempel oder Fensterskalierung ausschalten, was schwerwiegende Auswirkungen auf die Performance bei einer stark frequentierten Verbindung haben kann, prüfen Sie, ob tcp_tw_recycle Ihr Problem ist: stackoverflow.com/questions/8893888/... - nephtes


In meinem Fall behebt der folgende Befehl das Problem mit fehlenden SYN / ACK Antworten vom Linux Server:

sysctl -w net.ipv4.tcp_tw_recycle=0

Ich denke, es ist korrekter als das Deaktivieren von TCP-Zeitstempeln, da TCP-Zeitstempel schließlich nützlich sind (PAWS, Fensterskalierung usw.).

Die Dokumentation zum tcp_tw_recycle explizit besagt, dass es nicht empfohlen wird, es zu aktivieren, da viele NAT-Router Zeitstempel beibehalten und somit PAWS einspringen, da Zeitstempel von derselben IP nicht konsistent sind.

   tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4)
          Enable fast recycling of TIME_WAIT sockets.  Enabling this
          option is not recommended for devices communicating with the
          general Internet or using NAT (Network Address Translation).
          Since some NAT gateways pass through IP timestamp values, one
          IP can appear to have non-increasing timestamps.  See RFC 1323
          (PAWS), RFC 6191.

9
2018-06-27 13:47



Gute Erklärung hier: vincent.bernat.im/de/blog/2014-tcp-time-wait-state-linux  Auf der Serverseite sollten Sie net.ipv4.tcp_tw_recycle nicht aktivieren, es sei denn, Sie sind sich ziemlich sicher, dass Sie keine NAT-Geräte in der Mischung haben werden. - Gnought
In meinem Fall, net.ipv4.tcp_tw_recycle ist der wahre Grund. Vielen Dank. - bluearrow


Ich frage mich nur, aber warum für das SYN-Paket (Frame # 539; das, das akzeptiert wurde), fehlen die WS- und TSV-Felder in der Spalte "Info"?

WS ist TCP-Fensterskalierung und TSV ist Zeitstempelwert. Beide sind unter tcp.options zu finden und Wireshark sollte sie trotzdem zeigen, wenn sie vorhanden sind. Vielleicht hat Client TCP / IP Stack beim 8. Versuch ein anderes SYN-Paket erneut gesendet und das war der Grund, warum es plötzlich bestätigt wurde?

Könnten Sie uns die internen Werte von Frame 539 zur Verfügung stellen? Kommt das SYN / ACK immer für ein SYN-Paket, für das kein WS aktiviert ist?


5
2018-02-16 00:29



@Ansis: Hier sind einige Screenshots für Frame 539 Details (musste in zwei Teilen gemacht werden): i.imgur.com/D84GC.png & i.imgur.com/4riq3.png - codemonkey
@codemonkey: Ihr 8. SYN-Paket scheint sich von den ersten sieben SYN-Paketen zu unterscheiden. Antwortet der Server mit SYN / ACK nur dann auf das SYN des Clients, wenn das Feld tcp.options eine Größe von 8 Byte hat (die ersten sieben SYN-Pakete haben wahrscheinlich tcp.options mit einer Größe von 20 Byte)? Können Sie die TCP-Fensterskalierung auf der Clientseite deaktivieren, um zu sehen, ob das Problem verschwindet? Scheint wie ein Problem mit TCP / IP-Stack auf der Serverseite oder falsch konfigurierte Firewall irgendwo ... - Hans Solo
@Ansis: Ja, ich habe mir das angesehen, seit du darauf hingewiesen hast und alle anderen SYN-Pakete 24 Bytes haben. Ich werde versuchen, die Fensterskalierung auf dem Client zu deaktivieren und am Morgen mit den Ergebnissen zurück zu schauen. - codemonkey
@Ansis: Durch das Deaktivieren der Windows-Skalierung auf dem Client wurde das Problem behoben. Vielen Dank! Jetzt muss ich jedoch herausfinden, wie das auf der Serverseite behoben werden kann (da wir nicht alle unsere Clients dazu bringen können, die Windows-Skalierung zu deaktivieren) :) Der betreffende Server hat net.ipv4.tcp_windows_scaling = 1 - codemonkey
@Codemonkey: Ich stimme zu, dass das Deaktivieren von WS auf allen Clients keine Lösung ist, aber wir haben das Problem zumindest auf Probleme mit WS / Paketgröße untersucht. Um die Ursache weiter zu finden, sollten wir uns ansehen, wie Ihre Firewall konfiguriert ist. Können Sie TCP-Verbindungen mit WS zu verschiedenen TCP-Ports herstellen? Von verschiedenen Quell-IPs? - Hans Solo


Wir haben gerade das genau gleiche Problem (es dauerte wirklich eine ganze Weile, um es an den Server zu pinnen, nicht syn-ack).

"Die Lösung war, tcp windows scaling und tcp timestamps auf unseren öffentlich zugänglichen Servern abzuschalten."


4
2018-03-18 06:14





Um weiterzumachen, was Ansis gesagt hat, habe ich Probleme wie diese gesehen, wenn die Firewall TCP Windows Scaling nicht unterstützt. Welche make / model Firewall ist zwischen diesen beiden Hosts?


2
2018-02-16 01:15



Die Firewall ist eine Fedora 13-Box mit iptables. net.ipv4.tcp_windows_scaling ist auch auf diesem Rechner auf 1 gesetzt - codemonkey


Ich habe gerade entdeckt, dass Linux TCP-Clients ihr SYN-Paket nach 3 Versuchen ändern und die Window Scaling-Option entfernen. Ich vermute, die Kernel-Entwickler haben festgestellt, dass dies eine häufige Ursache für Verbindungsfehler im Internet ist

Es erklärt, warum diese Clients es schaffen, sich nach 11 Sekunden zu verbinden (das fensterlose TCP SYN passiert nach 9 Sekunden in meinem kurzen Test mit den Standardeinstellungen)


1
2017-08-28 03:20





Das fehlende SYN / ACK könnte durch zu niedrige Grenzen Ihres SYNFLOOD-Schutzes auf der Firewall verursacht werden. Es hängt davon ab, wie viele Verbindungen zu Ihrem Serverbenutzer erstellt werden. Die Verwendung von Spdy würde die Anzahl der Verbindungen reduzieren und könnte in Situationen, in denen es sich dreht, helfen net.ipv4.tcp_timestamps Aus hilft nicht.


1
2018-05-20 12:11





Dies ist das Verhalten eines empfangenden TCP-Sockets, wenn sein Rückstand voll ist.

Mit Ngnix kann das Backlog-Argument in der Konfiguration festgelegt werden: http://wiki.nginx.org/HttpCoreModule#listen

höre 80 backlog = num

Versuchen Sie, num auf etwas zu setzen, das größer ist als der Standardwert, z. B. 1024.

Ich gebe keine Garantie, dass eine vollständige Warteliste tatsächlich Ihr Problem ist, aber dies ist eine gute erste Sache zu überprüfen.


0
2018-02-16 00:04



Danke für den Tipp. Ich werde es ausprobieren. Wir haben das Backlog auf der Betriebssystemebene festgelegt, aber nicht explizit in der Nginx-Konfiguration. Ich werde mit dem Ergebnis aktualisieren. - codemonkey
Es hat das Verhalten überhaupt nicht verändert. Schätze, es ist nicht das Problem? oder das einzige Problem ... - codemonkey
der Rückgriffsparameter auf Anwendungsebene steuert die Größe der Warteschlange für abgeschlossene TCP-Verbindungen, d. h. der 3-Wege-Handshake ist beendet, d. h. syn-ack empfangen - so dass er nicht mit der OP-Situation übereinstimmt - ygrek


Ich hatte ein ähnliches Problem, aber in meinem Fall war es die TCP-Prüfsumme, die falsch berechnet wurde. Der Kunde war hinter einem veth und laufendem Ettool - K veth0 rx off tx off hat den Trick gemacht.


0
2017-10-16 20:36