Wie verhindere ich, dass die TCP-Verbindung über ein OpenVPN-Netzwerk einfriert?

19

Neue Details am Ende dieser Frage hinzugefügt; Es ist möglich, dass ich mich auf die Sache konzentriere.

Ich habe ein UDP OpenVPN-basiertes VPN im tapModus eingerichtet (ich brauche, tapweil ich das VPN zum Weiterleiten von Multicast-Paketen benötige, was mit tunNetzwerken anscheinend nicht möglich ist), mit einer Handvoll Clients über das Internet. Ich habe häufig TCP-Verbindungsabbrüche über das VPN festgestellt. Das heißt, ich werde eine TCP-Verbindung herstellen (z. B. eine SSH-Verbindung, aber andere Protokolle haben ähnliche Probleme). Irgendwann während der Sitzung scheint der Datenverkehr nicht mehr über diese TCP-Sitzung übertragen zu werden.

Dies scheint mit Punkten zu tun zu haben, an denen große Datenmengen übertragen werden, z. B. wenn ich lsin einer SSH-Sitzung einen Befehl ausführe oder wenn ich cateine lange Protokolldatei habe. Einige Google-Suchanfragen zeigen eine Reihe von Antworten wie die vorherige zu "Serverfehler" an , die darauf hinweisen, dass der wahrscheinliche Schuldige ein MTU-Problem ist: In Zeiten mit hohem Datenverkehr versucht das VPN, Pakete zu senden, die irgendwo in den Pipes zwischen dem Server abgelegt werden VPN-Endpunkte. In der oben aufgeführten Antwort wird vorgeschlagen, die folgenden OpenVPN-Konfigurationseinstellungen zu verwenden, um das Problem zu beheben:

fragment 1400
mssfix

Dies sollte die im VPN verwendete MTU auf 1400 Byte begrenzen und die maximale TCP-Segmentgröße festlegen, um die Generierung größerer Pakete zu verhindern. Dies scheint das Problem ein wenig zu lindern, aber ich sehe immer noch häufig die Einfrierungen. Ich habe eine Reihe von Größen als Argumente für die fragmentRichtlinie ausprobiert : 1200, 1000, 576, alle mit ähnlichen Ergebnissen. Ich kann mir keine seltsame Netzwerktopologie zwischen den beiden Enden vorstellen, die ein solches Problem auslösen könnte: Der VPN-Server wird auf einem direkt mit dem Internet verbundenen pfSense- Computer ausgeführt, und mein Client ist auch direkt an einem anderen Standort mit dem Internet verbunden.

Ein weiteres seltsames Puzzleteil: Wenn ich das tracepathDienstprogramm ausführe , scheint dies das Problem zu lösen. Ein Probelauf sieht so aus:

[~]$ tracepath -n 192.168.100.91
 1:  192.168.100.90                                        0.039ms pmtu 1500
 1:  192.168.100.91                                       40.823ms reached
 1:  192.168.100.91                                       19.846ms reached
     Resume: pmtu 1500 hops 1 back 64 

Der obige Lauf findet zwischen zwei Clients im VPN statt: Ich habe den Trace von 192.168.100.90zum Ziel von initiiert 192.168.100.91. Beide Clients wurden mit konfiguriert fragment 1200; mssfix;, um die für die Verbindung verwendete MTU zu begrenzen. Die obigen Ergebnisse scheinen darauf hinzudeuten, dass tracepatheine Pfad-MTU von 1500 Bytes zwischen den beiden Clients erkannt werden konnte. Ich würde davon ausgehen, dass es aufgrund der in der OpenVPN-Konfiguration angegebenen Fragmentierungseinstellungen etwas kleiner ist. Ich fand das Ergebnis etwas seltsam.

Noch seltsamer: Wenn ich eine TCP-Verbindung im blockierten Zustand habe (z. B. eine SSH-Sitzung mit einem Verzeichnis, das in der Mitte eingefroren ist), führt die Ausführung des tracepathoben gezeigten Befehls dazu, dass die Verbindung erneut gestartet wird ! Ich kann keine vernünftige Erklärung dafür finden, warum dies der Fall wäre, aber ich glaube, dies könnte auf eine Lösung hindeuten, um das Problem endgültig zu beseitigen.

Hat jemand irgendwelche Empfehlungen für andere Dinge zum Ausprobieren?

Edit: Ich bin zurückgekommen und habe mir das etwas genauer angesehen und nur etwas verwirrendere Informationen gefunden:

  • Ich habe die OpenVPN-Verbindung wie oben gezeigt auf Fragment auf 1400 Byte eingestellt. Dann stellte ich über das Internet eine Verbindung zum VPN her und überprüfte mit Wireshark die UDP-Pakete, die während des Abbruchs an den VPN-Server gesendet wurden. Keines war größer als die angegebene Anzahl von 1400 Bytes, daher scheint die Fragmentierung ordnungsgemäß zu funktionieren.

  • Um zu überprüfen, ob auch eine 1400-Byte-MTU ausreicht, habe ich den VPN-Server mit dem folgenden Befehl (Linux) gepingt:

    ping <host> -s 1450 -M do
    

    Dies (glaube ich) sendet ein 1450-Byte-Paket mit deaktivierter Fragmentierung (ich habe zumindest überprüft, dass es nicht funktioniert, wenn ich es auf einen offensichtlich zu großen Wert wie 1600 Byte eingestellt habe). Diese scheinen gut zu funktionieren; Ich erhalte ohne Probleme Antworten vom Host.

Vielleicht ist das überhaupt kein MTU-Problem. Ich bin nur verwirrt, was es sonst noch sein könnte!

Edit 2: Das Kaninchenloch wird immer tiefer: Ich habe das Problem jetzt ein bisschen genauer eingegrenzt. Es scheint mit dem genauen Betriebssystem zu tun zu haben, das der VPN-Client verwendet. Ich habe das Problem auf mindestens drei Ubuntu-Rechnern (Versionen 12.04 bis 13.04) erfolgreich dupliziert. Ich kann einen SSH-Verbindungsabbruch zuverlässig innerhalb einer Minute duplizieren, indem ich nur cateine große Protokolldatei anführe.

Allerdings , wenn ich den gleichen Test mit einem CentOS 6 Maschine als Client tun, dann sehe ich das Problem nicht! Ich habe genau die OpenVPN-Client-Version getestet, die ich auf Ubuntu-Rechnern verwendet habe. Ich kann catstundenlang Dateien protokollieren, ohne dass die Verbindung unterbrochen wird. Dies scheint einen Einblick in die letztendliche Ursache zu geben, aber ich bin mir nicht sicher, was dieser Einblick ist.

Ich habe den Datenverkehr über das VPN mit Wireshark untersucht. Ich bin kein TCP-Experte, daher bin ich mir nicht sicher, was ich mit den wichtigsten Details anfangen soll, aber das Wesentliche ist, dass irgendwann ein UDP-Paket aufgrund der begrenzten Bandbreite der Internetverbindung verworfen wird, was zu erneuten TCP-Übertragungen führt der VPN-Tunnel. Auf dem CentOS-Client werden diese erneuten Übertragungen ordnungsgemäß ausgeführt und die Dinge laufen problemlos weiter. Bei den Ubuntu-Clients beginnt das Remote-Ende jedoch irgendwann, dasselbe TCP-Segment immer wieder neu zu übertragen (wobei die Übertragungsverzögerung zwischen den einzelnen Neuübertragungen zunimmt). Der Client sendet bei jeder erneuten Übertragung eine Art gültiges TCP-ACK, die Gegenstelle überträgt jedoch weiterhin in regelmäßigen Abständen dasselbe TCP-Segment. Dies verlängert ad infinitum und die Verbindung wird unterbrochen. Meine Frage wäre hier:

  • Hat jemand Empfehlungen zur Behebung und / oder Ermittlung der Hauptursache des TCP-Problems? Es ist, als ob die Gegenstelle die vom VPN-Client gesendeten ACK-Nachrichten nicht akzeptiert.

Ein gemeinsamer Unterschied zwischen dem CentOS-Knoten und den verschiedenen Ubuntu-Versionen besteht darin, dass Ubuntu eine viel neuere Linux-Kernel-Version hat (von 3.2 in Ubuntu 12.04 auf 3.8 in 13.04). Ein Hinweis auf einen neuen Kernel-Bug? Ich gehe davon aus, dass ich in diesem Fall nicht der einzige wäre, bei dem das Problem auftritt. Ich glaube nicht, dass dies ein besonders exotisches Setup ist.

Jason R
quelle
Das Routing von Multicast-Paketen über ein tunNetzwerk sollte möglich sein, indem Multicast-Routing-Daemons (wie pimd ) ausgeführt werden und der OpenVPN-Server die --topologyauf "Subnetz" gesetzten Optionen verwendet - siehe Handbuch
kostix
Zeigen der VPN-Client oder -Server zum Zeitpunkt dieser Probleme etwas in den Protokollen an?
mgorven
@mgorven: Auf jeden Fall nicht auf dem Client. Ich muss ein bisschen arbeiten, um an die Server-Logs zu gelangen.
Jason R
@mgorven: Ich hatte endlich die Chance, darauf zurückzukommen. In den Client- oder Serverprotokollen ist in diesem Fall überhaupt nichts vorhanden. Es ist wirklich verwirrend.
Jason R
1
Gibt es eine Möglichkeit, dass die Clients, die einfrieren, lokale Firewalls haben, die ICMP-fragmentierungsbedürftige Pakete verwerfen, während diejenigen, die dies nicht tun, dies nicht tun und daher korrekt fragmentieren?
MadHatter unterstützt Monica am

Antworten:

10

Dieser Befehl löst es für mich:

$ sudo ip link set dev tun0 mtu 1350 && echo ":)"

Sie können die tun0-Einstellungen mit überprüfen

$ ip a s

Prost!

Sebastián A. La Spina
quelle
Auf der Client- oder Serverseite?
Matt
Vielen Dank! @Matt, es kommt darauf an, wo das Problem liegt. Für uns war es auf dem Server, aber es kann auf der Client-Seite sein. Auch der Wert kann abweichen, Sie können mit testen ping <host> -s 1350 -M do, um den richtigen Wert zu finden
Eino Gourdin
2

Deaktivieren Sie die Fensterskalierung in TCP mit:

sysctl -w net.ipv4.tcp_window_scaling=0

Danach funktioniert SSH zu Debian / Ubuntu-Systemen über VPN für mich einwandfrei.

Mifpi
quelle
0

Unter Windows mit Putty müssen Sie die MTU ändern, indem Sie zur lokalen Verbindung für die VPN-Verbindung wechseln -> Details zur Netzwerkschnittstelle (TAP-Windows-Adapter oder ähnliches) -> Erweitert -> Eigenschaften -> MTU (ändern Sie sie in etwas) niedriger als 1500). Möglicherweise müssen Sie erneut eine Verbindung herstellen. Bei Windows und Putty hat es funktioniert

Nick_K
quelle