Frage Warum hängen Konsolen manchmal für immer, wenn die SSH-Verbindung unterbrochen wird?


Ich habe das mit so vielen Konsolen gesehen (auf Linux, Mac, ...) und mit vielen verschiedenen Maschinen in vielen verschiedenen Netzwerken. Ich kann den genauen Grund, warum das passiert, nie genau bestimmen: Sie müssen sich nur per SSH bei einer Maschine anmelden. Wenn die Verbindung aus irgendeinem Grund unterbrochen wird (der Einfachheit halber wird angenommen, dass das Netzwerkkabel gezogen wurde), bleibt die Konsole manchmal für immer hängen - zu anderen Zeiten kommt sie einfach in die Parent-Shell zurück.

Es ist so ärgerlich, wenn dies passiert (z. B. wenn Sie den Befehlshistorie verlieren.) Gibt es vielleicht eine geheime Tastenkombination, die einen Exit erzwingen kann (Strg-C oder Strg-D funktionieren nicht)? Und was ist der Grund für diesen zufälligen "Bug" über alle Implementierungen hinweg?


74
2018-06-22 18:12


Ursprung


Dieser Thread scheint angemessen zu erwähnen Mosh (Mobile Shell), die gut mit Verbindungsfehlern, einschließlich Roaming (IP-Änderung) und anderem beschäftigt. - Ciprian Tomoiagă


Antworten:


Es gibt eine "geheime" Tastenkombination, um einen Exit zu erzwingen: ~) Drücken Sie in der eingefrorenen Sitzung die folgenden Tasten nacheinander: Eingeben~. Die Tilde (nur nach einer Zeilenumbruch) wird vom ssh-Client als Escape-Sequenz erkannt, und der Zeitraum sagt dem Client, dass er seine Arbeit ohne weiteres beenden muss.

Das Long-Hang-Verhalten bei Kommunikationsproblemen ist kein Fehler, die SSH-Sitzung hängt ab, in der Hoffnung, dass die andere Seite zurückkommen wird. Wenn das Netzwerk ausfällt, können Sie manchmal sogar Tage später eine SSH-Sitzung abrufen. Natürlich können Sie ihm ausdrücklich sagen, dass er aufgibt und mit der obigen Sequenz stirbt. Es gibt auch verschiedene Dinge, die Sie tun können, wie Keep-Alive Timeouts in Ihrem Client, so dass es, wenn es für eine bestimmte Zeit keine aktive Verbindung hat, es sich selbst beendet, aber das Standardverhalten ist, als zu bleiben verbunden wie möglich!

Bearbeiten: Eine weitere nützliche Anwendung dieses Interrupt-Schlüssels besteht darin, die Aufmerksamkeit des lokalen ssh-Clients auf sich zu ziehen und ihn für eine Minute zurück in Ihre lokale Shell zu befördern, um etwas aus Ihrem Verlauf zu holen. Eingeben~  Strg+Z um den ssh-Client dann an die Hintergrundjob-Warteschlange Ihrer lokalen Shell zu senden fg als normal, um es zurück zu bekommen.

Bearbeiten: Bei geschachtelten SSH-Sitzungen können Sie mehrere Tilde-Zeichen hinzufügen, um nur aus einer der SSH-Sitzungen in der Kette auszubrechen, die anderen jedoch beizubehalten. Wenn Sie beispielsweise in 3 Ebenen verschachtelt sind (d. H. Sie ssh von local-> Machine1-> Machine2-> Machine3), Eingeben~. bringt Sie zurück zu Ihrer lokalen Sitzung, Eingeben~~. wird Sie in Machine1 verlassen, und Eingeben~~~. wird dich in Machine2 lassen. Dies funktioniert auch für andere Escape-Sequenzen, wie z. B. das vorübergehende Verschieben der SSH-Sitzung in den Hintergrund. Das obige funktioniert für jede Verschachtelungsebene, indem einfach weitere Tilden hinzugefügt werden.

Schließlich können Sie verwenden Eingeben~? um ein Hilfemenü mit verfügbaren Escape-Befehlen zu drucken.

TL; DR - die unterstützten Escape-Befehle sind Unterstützte Escape-Sequenzen:

 ~.   - terminate connection (and any multiplexed sessions)
 ~B   - send a BREAK to the remote system
 ~C   - open a command line
 ~R   - request rekey
 ~V/v - decrease/increase verbosity (LogLevel)
 ~^Z  - suspend ssh
 ~#   - list forwarded connections
 ~&   - background ssh (when waiting for connections to terminate)
 ~?   - this message
 ~~   - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)

121
2018-06-22 18:15



+1 für das Passwort dodecatouple-secret-probation für die Aufnahme von sshd im Kopf. Hast du es genauso herausgefunden wie ich es tat? ~/.somethingorother nach dem Drücken von Enter)? - voretaq7
@ Voretaq7: Nein, ich war nicht so schlau, aber wenn jemand mich anklopfte, ging ich "Wirklich? So ist das passiert, all die Male, als meine Shell einfach nur BANG ging, ohne Grund beim Tippen?". Es ist keine gewöhnliche Sequenz, außer in den Tippfehlern der von Ihnen erwähnten, aber es kann passieren. - Caleb
Wobei "geheim" er "in der Manpage" meint. - larsks
Während viele Leute davon nicht wissen, ist es wirklich ein Geheimnis in der Übersicht. man ssh deckt dies unter den ESCAPE CHARACTERS Sektion. ~. (Trennen) und ~^Z (Hintergrund ssh) sind sehr praktisch. - Stefan Lasiewski
Natürlich ist es in der Manpage :) Ich habe nur das Wort Secret benutzt, weil das OP es tat, und ich benutzte ironisch. Das Problem mit dieser Funktion ist, dass die Leute nicht wissen, wo sie suchen sollen, sie erwarten, dass Kontrollzeichen und solche Signale Teil der Shell oder so sein werden. Sobald Sie wissen, wo Sie suchen oder was Sie fragen müssen, ist es natürlich da. - Caleb


SSH bietet eine Keep-Alive-Einrichtung. Fügen Sie Ihrem lokalen Benutzer Folgendes hinzu: ~/.ssh/config (Erstellen, wenn es nicht existiert):

ServerAliveInterval 15
ServerAliveCount 3

Mit dieser Einstellung wird ein Keep-Alive-Signal erstellt, das alle 15 Sekunden durch den sicheren Tunnel gesendet wird. Nach drei aufeinander folgenden Fehlern wird der SSH-Client beendet.

Beachten Sie, dass auf einigen Systemen stattdessen Folgendes erforderlich ist:

ServerAliveInterval 15
ServerAliveCountMax 3

Aus dieser Antwort auf ask.ubuntu: https://askubuntu.com/a/29967/30266


10
2018-01-19 08:44





Die Tatsache, dass es hängt, ist eine Funktion von TCP, nicht von SSH. Die Anwendung hat keine Möglichkeit zu wissen, dass die TCP-Sitzung / Verbindung getrennt wurde, es sei denn, TCP informiert die Anwendung über die Verbindung, dass die Verbindung nicht mehr besteht. Aus der Perspektive jedes Hosts befindet sich die TCP-Sitzung immer noch im Status "Established" und es gibt nichts zu sagen, dass eine lange Idle-Sitzung (keine Datenflüsse) nicht gültig ist, außer einer RST oder fehlender Antwort auf ein TCP-Keepalive-Paket ist nicht allgemein implementiert). Das scheint mir kein Fehler in SSH zu sein, ich würde dieses Verhalten erwarten.


8
2018-06-22 19:49





Wenn die Verbindung ordnungsgemäß unterbrochen ist, wird ein magischer Tastendruck nicht durchkommen, da die Verbindung bereits unterbrochen ist, bevor Sie die Tasten drücken. Sie können dem Client mitteilen, dass er beendet werden soll, aber dies wirkt sich nicht auf den Verlauf aus, der am Serverende beibehalten wird (oder nicht).

Während dies die Frage nicht wirklich beantwortet, kann es helfen, die Auswirkungen eines Verbindungsabhangs zu reduzieren: wenn ich remote arbeite (und sogar normalerweise, wenn ich nicht bin), laufe ich durch screen (mit oder ohne die byobu Wrapper abhängig von seiner Verfügbarkeit), so dass, wenn es irgendeine Art von Verbindung zu verlieren gibt, meine Sitzung mit all ihrer Geschichte in dem Zustand erhalten und verfügbar bleibt, den ich bei der Wiederverbindung verlassen habe.


5
2018-06-22 18:18



Ihr Vorschlag zum Bildschirm ist in Ordnung, aber das erste Bit ist eigentlich nicht auf das Problem anwendbar. Sie müssen die Schlüssel nicht zur entfernten Seite bringen, Sie müssen sie nur zum LOCAL ssh Client durchstellen! Der OP will seine lokale Shell zurück mit Geschichte. SSH übernimmt es und reagiert nicht auf normale Break-Sequenzen wie CTRL-C, weil es diese weitergibt. Es gibt eine Möglichkeit, den lokalen Client zu erreichen und zu beenden, siehe meine Antwort. Der Verlauf am lokalen Ende wird normalerweise beibehalten, wenn Sie sich erneut einloggen, abhängig von der Shell-Konfiguration. - Caleb
@Caleb: Die Frage, die speziell erwähnt wurde, verliert Geschichte, und die Befehlsgeschichte wird serverseitig gespeichert. Um dem Server mitzuteilen, dass er etwas anderes mit dem Verlauf tun soll, müssen Sie eine Nachricht an den Server senden, um ihm mitzuteilen, dass er etwas anderes mit dem Verlauf tun soll. Natürlich gibt es Möglichkeiten, bash (und einige andere Shells) dazu zu bringen, die History-Zeilen sofort aufzuzeichnen, anstatt sie im RAM zu sammeln, bis der Benutzer die Shell ordnungsgemäß existiert exit/logout welches das Geschichteproblem lösen würde, ohne zu verwenden screen. - David Spillett