SSH-Tunnel: "bind: Address already in use" und "remote port forwarding failed"

Auf dem Port, den Ihr Tunnel braucht, lauscht schon etwas. Bei -L liegt der Port auf Ihrem Rechner, bei -R auf dem Server. Oft hält eine alte SSH-Sitzung den Tunnel noch fest. Finden Sie sie mit lsof -nP -iTCP:8080 -sTCP:LISTEN und beenden Sie den Prozess oder nehmen Sie einen anderen Port. Fügen Sie -o ExitOnForwardFailure=yes hinzu, denn ohne diese Option meldet SSH Sie trotzdem an und Sie haben keinen Tunnel.

Keine Lust, die PID eines hängenden Tunnels zu suchen? Wardterm speichert jeden Tunnel als Regel, die Sie an einer Stelle starten und stoppen. Zeigen

Aktualisiert am . Alle Meldungen und Befehle wurden mit OpenSSH 10.3 auf macOS gegen einen OpenSSH-10.0-Server unter Linux nachgestellt.

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 -f gestartet und vergessen. Führen Sie kill 4242 mit 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 ControlCe auf 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

Mehr zu Fehlermeldungen

Alle Anleitungen