Einen OpenVPN-Client im Volltunnel-Modus auf einer Maschine einzuschalten, die Sie über SSH erreichen, kann die Sitzung binnen einer Sekunde kappen, und die Maschine macht dabei nichts falsch. Der Tunnel ändert nicht, wie Pakete den Server erreichen; er ändert, wie die Antworten ihn verlassen. Sobald die Standardroute auf tun0 zeigt, geht eine Antwort an Ihren SSH-Client in das Netz des Anbieters, das keine Route zurück zu Ihrer Adresse hat. Die Verbindung hängt, der nächste Versuch läuft in einen Timeout, und der Daemon lauscht die ganze Zeit weiter auf Port 22.

Lesen Sie die Routing-Tabelle, bevor Sie das VPN-Log lesen. Das Log wird sagen, dass der Tunnel hochkam, und es hat recht. Die Frage ist, an welche Schnittstelle jede Antwort übergeben wird, und das ist ein Nachschlagen pro Paket in einer Tabelle, die der Tunnel gerade neu geschrieben hat.

Warum die Antwort durch die falsche Tür hinausgeht

Eingehende Pakete kommen weiterhin auf der physischen Schnittstelle an, weil ein VPN-Client nicht ändern kann, wie das Internet die öffentliche Adresse Ihres Servers erreicht. Antworten sind eine eigene Entscheidung: Für jedes Paket schlägt der Kernel das Ziel nach, und nach --redirect-gateway sagt der Standardeintrag Tunnel. Der Ausgang des Anbieters sieht ein Ziel, das er nicht bedient, und verwirft das Paket.

Der eigene Schutz von OpenVPN deckt genau ein Ziel ab. Das Handbuch zu 2.6 beschreibt --redirect-gateway als Abfolge: Es fügt eine Host-Route für den VPN-Peer über das Gateway hinzu, das vor dem Tunnel im Einsatz war, damit der verschlüsselte Verkehr nicht in sich selbst zurückläuft, und ersetzt dann die Standardroute. Diese Host-Route gilt nur für den Peer. Ihr SSH-Client ist nur eine weitere Internetadresse und bekommt keine Ausnahme.

Ein Präfixfehler lohnt sich, früh auszuschließen. ip route add -net 0.0.0.0 gw 10.8.0.1 dev tun0 ohne Länge trifft die einzelne Adresse 0.0.0.0, nicht das Internet; es muss 0.0.0.0/0 sein. Und wenn die Übernahme der Standardroute den eigenen Transport des Tunnels bricht, fügen Sie den Endpunkt als Host-Route über die physische Schnittstelle hinzu, mit der echten Adresse des Anbieters.

Nageln Sie die Adresse Ihres SSH-Clients für eine sofortige Lösung fest

Die schnellste Reparatur ist eine Host-Route für Ihre Client-Adresse über das Gateway, das der Server vor dem Tunnel nutzte. Finden Sie auf Ihrer Seite die Adresse, die der Server sehen wird, und lesen Sie dann die Tabelle des Servers, um das alte Gateway zu kennen:

curl -s https://ifconfig.co
ip route

Fügen Sie auf dem Server die Ausnahme hinzu, bevor der Client startet. Die Adressen hier sind Platzhalter; die Form ist entscheidend:

sudo ip route add 80.128.240.55 via 192.168.178.1

Das ist die im gemeldeten Fall verwendete Reparatur, und sie wirkt sofort. Sie ist auch auf zwei vorhersehbare Arten fragil: Die Route verschwindet beim Neustart, und sie wird in dem Moment falsch, in dem Ihr Provider Ihnen eine andere Adresse gibt. Behandeln Sie sie als Notmaßnahme und machen Sie sie bewusst dauerhaft, über eine Netzwerk-Unit oder einen Dispatcher-Hook, oder akzeptieren Sie, dass sie vorübergehend ist, und notieren Sie den Rückweg.

Hindern Sie den Client daran, die Standardroute zu übernehmen

Die sauberere Option ist, den Tunnel die Standardroute gar nicht ersetzen zu lassen. route-nopull, zusammen mit --client oder --pull verwendet, akzeptiert gepushte Optionen außer Routen, block-outside-dns und DHCP-artigen Optionen wie DNS-Servern, Sie ergänzen also nur die Präfixe, die Sie brauchen. Ein schmaleres Werkzeug ist ein Pull-Filter, der eine störende Anweisung verwirft und den Rest behält:

route-nopull
pull-filter ignore "redirect-gateway"

Nehmen Sie das eine oder das andere, nicht beides, und seien Sie sich klar, was sich ändert. Ohne Standardroute durch den Tunnel surft der Server nicht mehr über den Anbieter im Internet; er erreicht nur, was Sie ausdrücklich geroutet haben. Wenn der Volltunnel der ganze Sinn des Aufbaus war, ist das der falsche Hebel, und die Host-Route oben ist der richtige.

Teilen Sie den Rückweg nach Quelle oder nach Verbindung

Wenn die eingehende Adresse stabil ist, hält eine Quellregel die Antworten lokal, ohne die eigenen Routen des Tunnels anzutasten. Geben Sie der Adresse der physischen Schnittstelle eine eigene Tabelle mit dem LAN-Präfix und der physischen Standardroute, und wählen Sie diese Tabelle dann für Verkehr, der von ihr stammt:

ip rule add from 192.168.1.11 table 128
ip route add table 128 to 192.168.1.0/24 dev eth0
ip route add table 128 default via 192.168.1.1

Das funktioniert, weil Antworten auf eine eingehende SSH-Verbindung von der Adresse stammen, mit der der Client sich verbunden hat. Ein gemeldeter Fall, in dem jeder eingehende Dienst weiterlaufen musste, nutzte genau diese Form. Wenn die eingehende Adresse schwankt oder der Pfad dynamisch ist, markieren Sie stattdessen die Verbindung: Setzen Sie eine Conntrack-Markierung auf das erste Paket von der physischen Schnittstelle, kopieren Sie sie in OUTPUT auf Antwortpakete, und routen Sie markierte Pakete über eine Tabelle, die auf das physische Gateway zeigt.

iptables -t mangle -A PREROUTING -i eth0 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1234
iptables -t mangle -A OUTPUT -m connmark --mark 1234 -j MARK --set-mark 4321
ip route add default via 192.168.1.1 dev eth0 table 3412
ip rule add fwmark 4321 table 3412

Halten Sie Verbindungsmarke, Firewall-Marke und Tabellennummer beim Testen getrennt. Eine Nummer für zwei Rollen wiederzuverwenden erzeugt eine Regel, die korrekt aussieht und die falschen Pakete trifft. Der Standardeintrag der Tabelle braucht außerdem via mit dem LAN-Gateway auf einem gewöhnlichen Ethernet-Link; ein nacktes dev eth0 funktioniert nur, wenn die Schnittstelle Punkt-zu-Punkt ist oder der nächste Hop anders aufgelöst wird. Der gemeldete Jessie-Host saß zufällig auf einem Link, wo die nackte Form funktionierte, was keine Distributionsregel zum Kopieren ist.

Prüfen, ohne sich selbst auszusperren

Testen Sie nicht durch Trennen. Lassen Sie die erste Sitzung offen, bringen Sie den Tunnel hoch und fragen Sie den Kernel, welchen Pfad Ihre eigene Adresse nehmen würde:

ip route get 80.128.240.55

Die Antwort sollte die physische Schnittstelle und das alte Gateway nennen, nicht den Tunnel. Öffnen Sie dann eine zweite SSH-Verbindung; das ist der eigentliche Test, denn die alte Sitzung kann auf Zustand überleben, den eine neue Verbindung nicht reproduzieren kann. Wenn die zweite hängt, während die erste noch antwortet, hat die Regel den entscheidenden Verkehr nie getroffen, und die Marken oder die Quelladresse sind die Stelle zum Nachsehen.

Halten Sie eine Out-of-Band-Konsole während der ganzen Übung verfügbar. Ein Server, dessen einziger Zugangsweg der Tunnel ist, den Sie gerade zerstört haben, lässt sich nicht über diesen Tunnel reparieren, und der Rückbau ist leichter, wenn Sie die Tabellennummern und Präfixe notiert haben, die Sie hinzugefügt haben.

Ähnliche Artikel