Welchen brauchen Sie?
| Option | Port öffnet sich auf | Verwenden Sie ihn, um |
|---|---|---|
-L lokal | Ihrem Rechner | einen Dienst zu erreichen, den nur der Server erreicht, etwa eine Datenbank. |
-R remote | dem Server | den Server etwas auf Ihrem Rechner erreichen zu lassen, etwa eine Entwicklungsseite. |
-D dynamisch | Ihrem Rechner | im Web zu surfen oder sich mit vielen Hosts zu verbinden, als wären Sie auf dem Server. |
Eine einfache Eselsbrücke: -L lauscht auf Ihrem lokalen Rechner, -R auf dem entfernten (remote) Server, und -D ist dynamisch, weil die Anwendung das Ziel jedes Mal selbst wählt.
Lokale Weiterleitung: -L
ssh -N -L 8080:localhost:80 user@server
your app -> your machine, port 8080 -> SSH -> server -> localhost:80 as seen by the server
Das Format ist lokaler_port:ziel:zielport. Jetzt zeigt http://127.0.0.1:8080 auf Ihrem Rechner den Webserver, der nur auf der eigenen Loopback-Adresse des Servers lauscht.
Entscheidend ist, dass der Server das Ziel auflöst. localhost bedeutet den Server selbst, nicht Ihren Rechner. Das Ziel kann auch ein anderer Host sein, den der Server erreicht, und dieser letzte Abschnitt wird von SSH nicht verschlüsselt:
ssh -N -L 8080:intranet.example.com:80 user@server
Remote-Weiterleitung: -R
ssh -N -R 9000:localhost:3000 user@server
a program on the server -> server, port 9000 -> SSH -> your machine -> localhost:3000 as seen by your machine
Jetzt kann ein Programm auf dem Server http://127.0.0.1:9000 öffnen und die App erreichen, die auf Ihrem Rechner läuft. Das funktioniert auch, wenn Ihr Rechner hinter NAT liegt, weil Ihre Seite die Verbindung aufgebaut hat.
Dynamische Weiterleitung: -D
ssh -N -D 1080 user@server
your app -> SOCKS proxy on your machine, port 1080 -> SSH -> server -> any host:port the app asks for
Richten Sie eine Anwendung, die SOCKS unterstützt, auf 127.0.0.1:1080. Zum Testen mit curl:
curl --socks5-hostname 127.0.0.1:1080 http://intranet.example.com/
--socks5-hostname lässt den Server die DNS-Abfrage machen, sodass interne Namen funktionieren und die Abfrage nicht aus Ihrem eigenen Netz nach außen dringt. Das einfache --socks5 löst den Namen auf Ihrem Rechner auf.
Browser-Einstellungen und DNS-Lecks behandelt SSH als SOCKS-Proxy nutzen.
Mehrere Ports oder über einen Jump-Host
Wiederholen Sie die Option, um mehrere Weiterleitungen über eine Verbindung zu öffnen:
ssh -N -L 127.0.0.1:8080:localhost:80 -L 127.0.0.1:5433:localhost:5432 user@server
Steht der Server hinter einem Bastion-Host, fügen Sie -J hinzu. Die Weiterleitung beginnt am letzten Server der Kette, also löst dieser Server das Ziel auf:
ssh -N -J user@bastion -L 127.0.0.1:5433:localhost:5432 user@db-server
Ketten von Servern erklärt ProxyJump und Jump-Hosts in SSH nutzen.
Einen Tunnel ohne Shell betreiben
-Nführt keinen Befehl auf dem Server aus. Die Sitzung trägt nur den Tunnel.-fwechselt nach der Anmeldung in den Hintergrund, sodass Sie vorher noch eine Passphrase tippen können.-o ExitOnForwardFailure=yesbeendet sich mit einem Fehler, wenn die Weiterleitung nicht eingerichtet werden kann.
ssh -f -N -o ExitOnForwardFailure=yes -L 127.0.0.1:8080:localhost:80 user@server
Ohne ExitOnForwardFailure gibt ssh eine Warnung aus und bleibt ohne funktionierenden Tunnel verbunden, was in einem Skript verwirrend ist. Mit der Option endet ein bereits belegter lokaler Port mit Exit-Code 255 und Could not request local forwarding, und ein belegter Remote-Port mit remote port forwarding failed for listen port.
Ein Haken aus unseren Tests: Bei einem einfachen -L 8080:... lauscht ssh sowohl auf 127.0.0.1 als auch auf ::1. Ist nur eine davon belegt, zum Beispiel durch ein anderes Programm auf IPv4, gibt ssh bind [127.0.0.1]:8080: Address already in use aus und läuft auch mit ExitOnForwardFailure=yes weiter. Ihre App erreicht dann womöglich dieses andere Programm. Schreiben Sie die Adresse hin, wie in -L 127.0.0.1:8080:..., wird daraus ein echter Fehler, nutzen Sie diese Form also in Skripten.
Um einen Tunnel im Hintergrund zu beenden, suchen Sie seinen Prozess und beenden ihn:
pgrep -f 'L 127.0.0.1:8080'
kill PID
Tunnel, die Sie oft starten, stoppen Sie mit einem Control-Socket einfach per Name, mit ssh -O exit. Siehe SSH-Tunnel speichern, starten und stoppen.
Um einen Tunnel in Ihrer Konfiguration zu halten, verwenden Sie LocalForward, RemoteForward und DynamicForward:
Host dbtunnel
HostName 203.0.113.10
User user
LocalForward 127.0.0.1:8080 localhost:80
ExitOnForwardFailure yes
Nur an localhost binden
Ein weitergeleiteter Port ist für jeden offen, der ihn erreichen kann, und der Dienst dahinter vertraut womöglich Verbindungen vom Server. Standardmäßig bindet ssh nur an Loopback, belassen Sie es dabei, wenn Sie keinen Grund dagegen haben.
Diese Befehle öffnen den lokalen Port für Ihr ganzes Netz. Wir haben bestätigt, dass beide auf allen Schnittstellen lauschen:
ssh -N -L 0.0.0.0:8080:localhost:80 user@server
ssh -N -g -L 8080:localhost:80 user@server
Bei -R entscheidet der Server, mit GatewayPorts in seiner sshd-Konfiguration:
| GatewayPorts | -R 9000:... | -R 0.0.0.0:9000:... |
|---|---|---|
no (Standard) | Nur Loopback | Nur Loopback, ohne Fehler |
clientspecified | Nur Loopback | Alle Schnittstellen |
yes | Alle Schnittstellen | Alle Schnittstellen, und 127.0.0.1:9000 öffnet sich ebenfalls auf allen Schnittstellen |
Ist Ihr -R-Port von außen nicht erreichbar, ist GatewayPorts also der übliche Grund. Einen Dienst Ihres Laptops auf diese Weise im Internet freizugeben, ist selten das, was Sie wollen. Bevorzugen Sie clientspecified, wenn Sie es brauchen, und fügen Sie eine Firewall-Regel hinzu.
Wenn der Server ablehnt
AllowTcpForwarding in der sshd-Konfiguration des Servers steuert das. Die Werte sind yes (Standard), no, local (erlaubt -L und -D) und remote (erlaubt -R).
- Ein blockiertes
-Loder-Dverbindet ohne Probleme. Der Fehler kommt erst, wenn etwas den Port nutzt:channel 2: open failed: administratively prohibited: open failed. - Ein blockiertes
-Rmeldetremote port forwarding failed for listen port.
Die Handbuchseite weist darauf hin, dass das Abschalten der Weiterleitung wenig bringt, wenn Benutzer auch eine Shell haben, da sie einen eigenen Forwarder ausführen können. Um jemanden wirklich einzuschränken, nehmen Sie auch die Shell weg, wie bei einem reinen Tunnel-Benutzer für eine Datenbank.
Zwei weitere Fehler kommen oft vor. Ist der lokale oder entfernte Port belegt, hilft Address already in use und remote port forwarding failed. Werden Verbindungen durch den Tunnel abgelehnt, hilft administratively prohibited: open failed.
Fragen
Was ist der Unterschied zwischen ssh -L und ssh -R?
-L öffnet einen Port auf Ihrem Rechner, der zu etwas führt, das der Server erreicht. -R öffnet einen Port auf dem Server, der zurück zu etwas auf Ihrem Rechner führt.
Wie leite ich mehrere Ports mit einem ssh-Befehl weiter?
Wiederholen Sie die Option: ssh -N -L 127.0.0.1:8080:localhost:80 -L 127.0.0.1:5433:localhost:5432 user@server. Eine Verbindung trägt alle Weiterleitungen. In ~/.ssh/config schreiben Sie eine LocalForward-Zeile pro Port.
Wie halte ich einen SSH-Tunnel dauerhaft offen?
Starten Sie ihn mit -N und -o ExitOnForwardFailure=yes, und lassen Sie autossh oder einen systemd-Dienst ihn nach einem Abbruch neu starten. Siehe autossh und systemd.
Warum verbindet der Tunnel, aber nichts funktioniert?
Der Server kann Weiterleitungen mit AllowTcpForwarding verbieten. Ein gesperrtes -L oder -D verbindet trotzdem und scheitert erst bei Nutzung des Ports, mit administratively prohibited: open failed.
Ist SSH-Port-Forwarding sicher?
Der Verkehr ist zwischen Ihrem Rechner und dem SSH-Server verschlüsselt. Der Abschnitt vom Server zum Ziel ist es nicht, und einen Port, der auf 0.0.0.0 lauscht, kann jeder in Ihrem Netzwerk nutzen. Lassen Sie die Listen-Adresse daher auf 127.0.0.1.