Lokale Portweiterleitung (-L): Der Port ist auf Ihrem Rechner belegt
Mit ssh -L 8080:localhost:80 user@server sehen Sie möglicherweise:
bind [127.0.0.1]:8080: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 8080
Could not request local forwarding.
Finden Sie heraus, wer den Port belegt. Das funktioniert unter macOS und Linux:
lsof -nP -iTCP:8080 -sTCP:LISTEN
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ssh 4242 user 4u IPv4 ... 0t0 TCP 127.0.0.1:8080 (LISTEN)
Unter Windows verwenden Sie netstat -ano | findstr :8080.
ssh: Ein früherer Tunnel läuft noch, oft mit-fgestartet und vergessen. Führen Siekill 4242mit der angezeigten PID aus oder lesen Sie den Abschnitt zu geteilten Verbindungen weiter unten.- Ein Entwicklungsserver, Docker oder eine Datenbank: Wählen Sie einen anderen lokalen Port. Nur die linke Zahl muss sich ändern:
ssh -L 18080:localhost:80 user@server. - Unter macOS ist
ControlCeauf Port 5000 oder 7000 der AirPlay-Empfänger. Wählen Sie einen anderen Port oder schalten Sie den AirPlay-Empfänger in den Systemeinstellungen aus.
Unsicher, welche Option Sie brauchen? SSH-Tunnel: lokale, entfernte und dynamische Weiterleitung vergleicht die drei.
Nur die erste Zeile erscheint
Wenn nur bind [127.0.0.1]:8080: Address already in use erscheint und die Sitzung trotzdem startet, hat SSH die IPv6-Seite gebunden, die IPv4-Seite aber nicht. -L 8080:... versucht beide. Der Port funktioniert dann nur halb: Clients, die 127.0.0.1 verwenden, erreichen das andere Programm statt Ihres Tunnels. Nennen Sie die Adresse ausdrücklich, dann meldet SSH den Fehler korrekt:
ssh -o ExitOnForwardFailure=yes -L 127.0.0.1:8080:localhost:80 user@server
Remote-Portweiterleitung (-R): Der Port ist auf dem Server belegt
Mit ssh -R 8080:localhost:80 user@server:
Warning: remote port forwarding failed for listen port 8080
Die Sitzung startet trotzdem, und die Warnung übersieht man leicht. Die Ursache liegt auf dem Server, und sein Log enthält dieselbe bind-Zeile. So sehen Sie dort, wer den Port belegt:
ssh user@server "ss -ltnp | grep ':8080'"
Der Prozessname erscheint nur bei Ihren eigenen Prozessen, es sei denn, Sie führen den Befehl mit sudo aus. Manchmal ist der Besitzer sshd oder sshd-session: Die vorige Verbindung von Ihrem Laptop oder Ihrem Tunnel-Skript ist abgebrochen, ohne dass der Server es bemerkt hat, und hält den Port weiter fest. Suchen Sie diese Sitzung auf dem Server und beenden Sie sie:
sudo ss -ltnp | grep ':8080'
sudo kill PID
Damit der Server solche Verbindungen selbst aufräumt, tragen Sie Folgendes in die sshd_config ein und laden den Dienst neu. Ein Client, der etwa 90 Sekunden lang schweigt, wird getrennt:
ClientAliveInterval 30
ClientAliveCountMax 3
Ein belegter Port ist nicht der einzige Grund für diese Warnung. Ist der Port frei, verbietet der Server vielleicht die Weiterleitung. Das behandelt administratively prohibited.
Wenn Sie keinen festen Port brauchen, lassen Sie den Server einen wählen. Der Client gibt den erhaltenen Port aus:
ssh -R 0:localhost:80 user@server
Allocated port 38587 for remote forward to localhost:80
Einen fehlgeschlagenen Tunnel laut scheitern lassen
Standardmäßig meldet SSH Sie auch dann an, wenn die Weiterleitung fehlgeschlagen ist. Skripte laufen dann weiter und scheitern später aus einem verwirrenden Grund. Mit dieser Option beendet sich SSH stattdessen mit Status 255:
ssh -o ExitOnForwardFailure=yes -N -L 127.0.0.1:8080:localhost:80 user@server
Bei -R lautet die Meldung dann:
Error: remote port forwarding failed for listen port 8080
Verwenden Sie diese Option in allem, was automatisch läuft, auch bei autossh. So sieht eine Wiederholungsschleife den Fehler und versucht es erneut, sobald der Port frei ist.
Geteilte Verbindungen halten auch Ports fest
Mit ControlMaster gehört die Weiterleitung zum Master-Prozess im Hintergrund, das Schließen Ihres Terminals gibt den Port also nicht frei. Sie können den Master mit demselben Host und derselben Konfiguration ansprechen:
ssh -O check user@server
ssh -O cancel -L 127.0.0.1:8080:localhost:80 user@server
ssh -O exit user@server
Mehr dazu unter SSH-Multiplexing.
Fragen
Wie finde ich heraus, welcher Prozess einen Port belegt?
Unter macOS und Linux mit lsof -nP -iTCP:8080 -sTCP:LISTEN, unter Linux auch mit ss -ltnp. Unter Windows hilft netstat -ano | findstr :8080. Die Ausgabe zeigt Programm und PID.
Warum meldet sich SSH an, obwohl die Portweiterleitung fehlgeschlagen ist?
Standardmäßig ist eine fehlgeschlagene Weiterleitung nur eine Warnung. Mit -o ExitOnForwardFailure=yes beendet sich ssh mit Status 255, und Skripte bemerken den Fehler.
Wie beende ich einen SSH-Tunnel im Hintergrund?
Suchen Sie den ssh-Prozess mit lsof und beenden Sie ihn mit kill und seiner PID. Gehört er zu einer ControlMaster-Verbindung, nutzen Sie ssh -O cancel oder ssh -O exit mit demselben Host.
Quellen
- ssh(1), Optionen -L, -R und -O
- ssh_config(5), ExitOnForwardFailure
- sshd_config(5), ClientAliveInterval