Sicherheitsschalter greift: Was passiert mit offenen TCP-Sitzungen?
Ein blockiertes Paket ist keine geschlossene Verbindung. Entscheiden Sie, ob eine Sitzung die Lücke überstehen soll, und prüfen Sie dann die Blockade und die Erholung als zwei getrennte Eigenschaften.
Der Tunnel bricht ab, der Sicherheitsschalter greift, und ein Download, der zu drei Vierteln fertig war, friert entweder ein oder scheitert sofort. Diese beiden Ausgänge stammen aus unterschiedlichen Durchsetzungsentscheidungen, nicht aus unterschiedlichen Schutzstufen. Ein verworfenes Paket lässt die Verbindung warten, während ein abgelehntes sie schließt und die Anwendung informiert. Zu entscheiden, welches Verhalten Sie wollen, ist eine Designfrage, und es zu testen ist eine separate Übung.
Verwerfen, Ablehnen und Zurücksetzen sind verschieden
Eine Firewall-Regel, die Verkehr verwirft, wirft das Paket weg und schickt nichts zurück, sodass der Absender nach seinen eigenen Timern weiter sendet. Eine Regel, die mit einem TCP-Reset ablehnt, schließt die Verbindung sofort, und die Anwendung sieht einen Fehler. Die meisten Sicherheitsschalter verwerfen, weil eine Ablehnung die Richtlinie verraten würde und weil Verwerfen dem Verhalten eines toten Netzes ähnelt.
Blockieren ist auch nicht dasselbe wie das Schließen des Sockets. Die Anwendung hält weiterhin einen Deskriptor in einem etablierten Zustand, und nur die Pakete fehlen. Deshalb kann eine Seite minutenlang auf einem Spinner hängen, während das Betriebssystem darauf besteht, dass die Verbindung existiert. Lesen Sie die dokumentierte Durchsetzung, statt sie aus der Meldung der Anwendung abzuleiten, denn beide Verhaltensweisen sehen aus wie ein ausgefallenes Netz.
Was die Anwendung tut, solange die Lücke dauert
TCP sendet mit wachsenden Verzögerungen erneut, und das Standardbudget für Wiederholungen unter Linux läuft irgendwo um eine Viertelstunde ab, nicht in Sekunden. Bis dahin ist der Socket weder nützlich offen noch geschlossen. Anwendungen mit eigenen Keepalives oder Anforderungs-Timeouts geben oft früher auf, weshalb sich zwei Programme auf derselben Maschine während eines Ausfalls unterschiedlich verhalten.
Wenn der Tunnel zurückkehrt, ist der lokale Socket unverändert, der Pfad aber vielleicht nicht. Eine neue öffentliche Quelladresse erzeugt beim Server ein anderes Vier-Tupel, sodass eine zustandsbehaftete Firewall auf der Gegenseite nicht mehr zur Sitzung passt. Die Verbindung ist tot, obwohl der Client nie einen Fehler sah.
Entscheiden Sie, ob eine Erholung nötig ist
Wählen Sie zwischen zwei Verträgen. Entweder muss die Sitzung eine kurze Lücke überstehen, was stabile Adressierung und einen Server erfordert, der seinen Zustand behält, oder die Anwendung muss sich sauber neu verbinden, was Wiederholungslogik erfordert, die gefahrlos wiederholbar ist. Alles dazwischen erzeugt das schlechteste Ergebnis: einen Client, der erneut sendet, was der Server bereits festgeschrieben hat, oder einen, der Erfolg für eine Sitzung meldet, die niemand sehen kann.
Stabile Adressierung ist der Teil, den Leute vergessen, denn eine Neuverbindung, die auf einer anderen öffentlichen Adresse landet, entwertet den Zustand auf der Serverseite, selbst wenn der Socket des Clients gesund aussieht. Schreiben Sie auf, welcher der beiden Verträge für welche Anwendung gilt, denn selten passen alle zusammen.
Prüfen Sie Blockade und Erholung getrennt
Behandeln Sie Leckageschutz und Sitzungsüberleben als zwei Eigenschaften, denn das Bestehen der einen sagt nichts über die andere. Eine Sitzung, die überlebt, ist kein Beweis dafür, dass direkter Verkehr blockiert wurde, und eine Sitzung, die stirbt, ist kein Beweis dafür, dass jede direkte Route blockiert wurde.
ss -tnp state established '( dport = :443 )'
sudo conntrack -L -p tcp --dport 443
sudo tcpdump -ni any 'tcp port 443 and tcp[tcpflags] & tcp-syn != 0'
Verwenden Sie beim Beobachten der Erholung einen harmlosen Testvorgang, damit eine doppelte Übermittlung nicht selbst zum Vorfall wird. Notieren Sie den Fehlermodus, den Sie tatsächlich gesehen haben: was die Anwendung anzeigte, ob der Socket überlebte und wann er sich von selbst erholte.
Schreiben Sie das erwartete Verhalten neben die Durchsetzungsregel und datieren Sie es. Die nächste Person, die diese Regel ändert, muss wissen, welchen der beiden Verträge der Einsatz zugesagt hat.