Selbst ein Laptop hinter dem NAT des Anbieters kann einem Kollegen dienen, solange der VPN-Server als Treffpunkt fungiert. Zwei Mechanismen führen dorthin: Der Client wählt sich nach außen und bittet den Server, einen lauschenden Port zu halten, oder der Server veröffentlicht einen Port und übersetzt ihn in den Tunnel. Beide lösen dasselbe Erreichbarkeitsproblem und verhalten sich bei Ausfall, Überwachung und Protokollierung unterschiedlich. Drei Bedingungen entscheiden, welche in Ihre Konfiguration gehört.

Zwei Formen, ein Treffpunkt

In der ersten Form öffnet der Client eine SSH-Sitzung nach außen und bittet den Server, auf einem gewählten Port zu lauschen, wobei jede Verbindung über diese Sitzung zurückgeführt wird. Auf dem Server wird nichts weitergeleitet und es findet keine Paketübersetzung statt, daher sind die einzigen Voraussetzungen ein SSH-Konto, eine erlaubte Weiterleitung und eine Firewallregel für den Port. Der Dienst bleibt am Loopback des Clients gebunden, was normalerweise gewünscht ist.

ssh -N -R 8081:127.0.0.1:8080 -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 [email protected]

In der zweiten Form besitzt der Server den öffentlichen Port und schreibt jede Verbindung auf die Tunneladresse des Clients um. Das erfordert aktivierte IP-Weiterleitung, eine Zielübersetzung auf dem Hinweg und eine Quellübersetzung auf dem Rückweg, und es funktioniert weiter, wenn keine SSH-Sitzung existiert. Der Port gehört dem Server und nicht einer Sitzung, und genau diese Eigenschaft entscheidet die meisten realen Fälle.

Keine der beiden Formen ist von der Konstruktion her sicherer. Beide legen einen Dienstport für alle offen, die die öffentliche Adresse des Servers erreichen können, und beide hängen weiterhin von der eigenen Authentifizierung des Dienstes ab.

Bedingung eins: Muss der Port die Sitzung überleben

Eine Reverse-Weiterleitung lebt genau so lange wie die SSH-Sitzung, die sie erzeugt hat. Wenn die Verbindung abbricht, verschwindet der Listener, und der Kollege sieht eine abgelehnte Verbindung statt eines langsamen Pfads. Die Überwachung des Befehls mit einer systemd-Unit und einer Neustartrichtlinie behebt das, und ExitOnForwardFailure=yes macht eine fehlgeschlagene Bindung sofort sichtbar, statt eine Sitzung ohne Weiterleitung laufen zu lassen.

Ein übersetzter Port übersteht Neustarts, wenn die Regeln dauerhaft gespeichert sind, aber er hängt davon ab, dass der Client dieselbe Tunneladresse behält. Ein dynamischer Pool, der dem Laptop nach einer Wiederverbindung eine andere Adresse gibt, lenkt die Regel still ins Leere. Reservieren Sie zuerst die Tunneladresse, schreiben Sie dann die Regel, und behandeln Sie beides als eine Änderung.

Wenn der Dienst um drei Uhr morgens ohne Aufsicht antworten muss, ist die Form mit dem vom Server veröffentlichten Port die mit weniger beweglichen Teilen, denn der einzige Prozess, der laufen muss, ist der Tunnel selbst.

Bedingung zwei: Wem gehören Firewall und Protokolle

Die Reverse-Form hält die gesamte Richtlinie an zwei Stellen. sshd entscheidet über AllowTcpForwarding, ob Remote-Weiterleitungen überhaupt erlaubt sind, und GatewayPorts entscheidet, ob der Listener an das Loopback oder an jede Adresse bindet. Mit dem Standardwert no kann ein Kollege außerhalb des Servers den Port nicht erreichen, obwohl die Weiterleitung erfolgreich war, und das sieht wie ein defekter Tunnel aus, obwohl es in Wahrheit eine Bindungsadresse ist.

sudo ss -ltn '( sport = :8081 )'
sudo grep -E '^(GatewayPorts|AllowTcpForwarding)' /etc/ssh/sshd_config

Die übersetzte Form benötigt aktivierte Weiterleitung und zwei Regeln, und bei der zweiten Regel gehen die meisten Rezepte schief. Die Quellübersetzung über den conntrack-Zustand DNAT einzuschränken bedeutet, dass nur die Verbindungen umgeschrieben werden, die die Zielregel erzeugt hat, statt jedes Paket, das der Server in den Tunnel schickt.

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8081 -j DNAT --to-destination 10.88.0.6:8080
sudo iptables -t nat -A POSTROUTING -o tun0 -m conntrack --ctstate DNAT -j SNAT --to-source 10.88.0.1

Diese Umschreibung zerstört außerdem die Zuordnung. Danach sieht der Client jeden Aufrufer als Tunneladresse des Servers, was jede Ratenbegrenzung pro Adresse in einen Topf wirft und verbirgt, wer was gesendet hat. Wenn Zuordnung wichtig ist, beenden Sie die Verbindung auf dem Server oder belassen Sie die Erlaubnisentscheidung dort und übergeben Sie eine Identität in einem Header, dem der Dienst vertraut. Die Wahl zwischen diesen beiden Korrekturen hängt davon ab, ob der Dienst überhaupt einen Proxy-Header liest.

Bedingung drei: ein Port oder viele, und wem gehört der Name

Ein einzelner Dienst auf einem einzelnen Port ist der Fall, in dem die Reverse-Weiterleitung beim Aufwand gewinnt. Sie brauchen einen Befehl, ein Konto und eine Firewallregel, und das Aufräumen ist das Beenden der Sitzung. Mehrere Dienste auf derselben öffentlichen Adresse drängen Sie zur vom Server veröffentlichten Form, weil jede Reverse-Weiterleitung ihren eigenen Serverport braucht und die Menge mit jedem Dienst wächst.

Namen machen es komplizierter. Eine Reverse-Weiterleitung kann hinter einem TCP-Proxy sitzen, der nach SNI routet, während ein übersetzter Port normalerweise ein Port pro Dienst ist. Wenn der Dienst TLS selbst beendet und den ursprünglichen Hostnamen braucht, bewahrt der Proxy-Ansatz ihn, und der DNAT-Ansatz bewahrt ihn nur, wenn der Dienst diesen Namen auf diesem Port akzeptiert.

Schreiben Sie auf, welche der drei Bedingungen die Form entschieden hat. Sonst wird die nächste Person, die einen zweiten Dienst hinzufügt, denselben Vergleich mit weniger Kontext neu eröffnen.

Entscheiden, dann von außen testen

Testen Sie den Pfad aus einem Netzwerk, das keine Route zum Laptop hat, und beobachten Sie die Zähler auf dem Server, während die Anfrage läuft. Ein Test vom Server zu seiner eigenen öffentlichen Adresse beweist hier nichts, weil das Paket lokal erzeugt wird und nie den eingehenden Übersetzungshaken erreicht, sodass der Test bestehen kann, während der echte Pfad defekt ist.

sudo iptables -t nat -L PREROUTING -n -v
sudo tcpdump -ni any 'tcp port 8081' -c 20

Zähler, die flach bleiben, bedeuten, dass das Paket die Regel nie erreicht hat, was auf den Anbieter oder die Host-Firewall hindeutet. Zähler, die sich bewegen, während der Dienst ablehnt, deuten auf die eigene Firewall des Clients oder die Adresse, auf der der Dienst lauscht. Ein Tunnel, der das Paket trägt, aber nichts zurückgibt, ist ein Routen- oder Rückwegproblem, und keines dieser drei Ergebnisse sollte durch Bearbeiten des Client-Adapters behoben werden. Notieren Sie, welcher Zähler sich bewegt hat, bevor Sie etwas ändern, denn der nächste Test braucht diese Ausgangslage.

Sobald die Form funktioniert, halten Sie Port, Eigentümer und Überwachungsmethode neben der Tunnelkonfiguration fest. Eine Erreichbarkeitskorrektur, die nur in der Shell-Historie von jemandem existiert, ist einen Neustart von einem Wiederholungsvorfall entfernt.

Ähnliche Artikel