Die Meldung
client_loop: send disconnect: Broken pipe
In unserem Test gab ein TCP-Reset unter einer laufenden Sitzung dies aus:
Read from remote host server: Connection reset by peer
client_loop: send disconnect: Broken pipe
Ältere Clients melden dasselbe Problem in anderer Form:
packet_write_wait: Connection to 203.0.113.10 port 22: Broken pipe
Broken pipe heißt, ssh hat in eine Verbindung geschrieben, die nicht mehr existiert. Es sagt nicht, wer sie beendet hat, und hat nichts mit Ihren Schlüsseln oder Ihrem Passwort zu tun.
Ursachen, nach Wahrscheinlichkeit geordnet
1. Ein Router oder eine Firewall hat eine ruhende Verbindung getrennt
Heimrouter, Firmen-Firewalls und Cloud-NAT-Gateways führen eine Tabelle offener Verbindungen und entfernen ruhende, oft nach wenigen Minuten. Ihre Sitzung wirkt in Ordnung, bis Sie eine Taste drücken. Der Hinweis: Die Sitzung stirbt nur, wenn Sie sie in Ruhe lassen, und zu einer ziemlich regelmäßigen Zeit. Ein kurzer Test: Setzen Sie die Lösung unten bei einer Verbindung und lassen Sie sie länger ruhen, als sie sonst überlebt.
2. Ihr Computer war im Ruhezustand oder hat das Netz gewechselt
Das Zuklappen eines Laptops oder der Wechsel vom WLAN zu einem Handy-Hotspot beendet die Verbindung. Ändert sich Ihre Adresse, kann kein Keepalive sie retten. Der Hinweis: Es passiert direkt nach dem Aufklappen des Laptops oder dem Ortswechsel.
3. Der Server hat sie beendet
Ein Neustart, ein Absturz oder ein vom Administrator gesetztes Inaktivitäts-Timeout sehen von Ihrer Seite ähnlich aus. Prüfen Sie Uptime und Log des Servers und suchen Sie nach Idle-Einstellungen:
uptime
sudo journalctl -u ssh --since "1 hour ago"
sudo sshd -T | grep -iE '^(clientalive|channeltimeout|unusedconnectiontimeout)'
Eine absichtlich vom Server beendete Sitzung gibt meist Connection to server closed by remote host. aus statt Broken pipe.
Die Lösung auf dem Client: ServerAliveInterval
Tragen Sie dies in ~/.ssh/config ein:
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
Zum einmaligen Ausprobieren ohne Änderung einer Datei:
ssh -o ServerAliveInterval=60 user@server
Nach 60 Sekunden Stille vom Server sendet ssh eine kleine Nachricht durch die verschlüsselte Verbindung und erwartet eine Antwort. Das bewirkt zwei Dinge:
- Der Datenverkehr hält die Verbindung in der Tabelle des Routers.
- Bleiben die Antworten aus, gibt
sshnachServerAliveCountMaxVersuchen auf, hier nach etwa 3 Minuten, statt zu hängen.
Das Standardintervall ist 0, also aus, und die Standardanzahl ist 3. Wird Ihre Verbindung früher als nach einer Minute entfernt, verkleinern Sie das Intervall. Ist die Grenze erreicht, sehen Sie dies:
Timeout, server 203.0.113.10 not responding.
Diese Meldung heißt, dass der Keepalive seine Arbeit tut: Das Netz hat wirklich aufgehört zu antworten.
Dasselbe auf dem Server: ClientAliveInterval
Wenn Sie den Server betreiben und das für alle wollen, legen Sie eine Datei wie /etc/ssh/sshd_config.d/keepalive.conf an:
ClientAliveInterval 60
ClientAliveCountMax 3
Prüfen und laden Sie dann neu:
sudo sshd -t && sudo systemctl reload ssh
Die Unit heißt auf manchen Systemen sshd. Außer dass sie Verbindungen am Leben hält, räumt sie auch Sitzungen verschwundener Clients auf. Als wir einen Client eingefroren haben, protokollierte der Server dies und schloss die Sitzung:
Timeout, client not responding from user user 203.0.113.20 port 40896
TCPKeepAlive ist nicht dasselbe
TCPKeepAlive ist auf beiden Seiten standardmäßig an, und es erneut einzuschalten hilft selten. Es gibt zwei Unterschiede:
- Es wird vom Betriebssystem nach eigenem Zeitplan gesendet. Unter Linux beträgt die Standard-Wartezeit 2 Stunden, viel zu lang, um den Tabelleneintrag eines Routers am Leben zu halten.
- Es liegt außerhalb des verschlüsselten Kanals und lässt sich daher fälschen. Server-Alive-Nachrichten nicht.
Das Handbuch merkt auch an, dass TCP-Keepalive Verbindungen sterben lässt, wenn eine Route kurz ausfällt. Wollen Sie kurze Ausfälle lieber überstehen, können Sie es ausschalten und sich allein auf ServerAliveInterval verlassen.
Wann stattdessen tmux
Keepalives verhindern, dass eine gesunde Verbindung wegen Inaktivität getrennt wird. Sie können eine Sitzung nicht retten, wenn das Netz tatsächlich wegfällt. Endet die Verbindung, enden normalerweise auch die Shell auf dem Server und alles, was darin läuft.
Für lange Jobs oder wenn Sie zwischen Netzen wechseln, führen Sie die Arbeit in tmux auf dem Server aus:
tmux new -A -s work
Führen Sie nach dem Wiederverbinden denselben Befehl aus, und Sie sind zurück in derselben Sitzung, mit weiterlaufendem Job. Siehe SSH-Sitzungen mit tmux am Leben halten. Nutzen Sie beides: Keepalives für die alltäglichen Abbrüche, tmux für das, was nicht verloren gehen darf.
Wenn Sie oft das Netz wechseln, geht ein Mosh-Client weiter: Die Sitzung folgt Ihrer neuen Adresse, statt zu enden.
Fragen
Was bedeutet client_loop: send disconnect: Broken pipe?
Die Netzwerkverbindung unter Ihrer SSH-Sitzung ist beendet, und ssh hat es beim nächsten Senden bemerkt. Mit Ihren Schlüsseln oder Ihrem Passwort hat das nichts zu tun.
Welcher Wert ist für ServerAliveInterval sinnvoll?
60 Sekunden passen zu den meisten Routern und Firewalls. Brechen untätige Sitzungen schon nach weniger als einer Minute ab, nehmen Sie 30. Mit ServerAliveCountMax 3 endet eine tote Verbindung nach etwa drei Intervallen.
Hält ServerAliveInterval die Sitzung bei einem Netzwechsel am Leben?
Nein. Es verhindert das Trennen wegen Untätigkeit auf einer funktionierenden Verbindung. Ändert sich Ihre Adresse, endet die Verbindung. Lassen Sie lange Arbeiten deshalb in tmux auf dem Server laufen, oder nutzen Sie Mosh.