
In einer unzuverlässigen WLAN-Umgebung muss ich mich häufig über SSH mit einem Server verbinden. Auf dem Server führe ich screen aus. Wenn die Verbindung unterbrochen wird, kann ich die Verbindung wiederherstellen, die Screen-Sitzung fortsetzen und dort weitermachen, wo ich aufgehört habe. Der Verbindungsverlust ist jedoch immer noch ein großer Zeitfresser: Wenn die Verbindung abbricht, während ich auf dem Server bin, friert das Terminalfenster häufig ein. Ich muss diesen Tab schließen, einen neuen öffnen, erneut per SSH eine Verbindung zum Server herstellen und die Screen-Sitzung fortsetzen. Ich habe dies versucht, indem ich screen auf dem Server und screen lokal ausgeführt habe. In beiden Fällen friert es häufig ein, wenn die Verbindung abbricht.
Gibt es eine Möglichkeit, etwas Ähnliches wie screen oder vielleicht screen selbst zu haben, das automatisch versucht, die Verbindung wiederherzustellen und die Sitzung am Laufen zu halten, sodass ich die Verbindung nicht immer wieder manuell wiederherstellen muss? Wenn ich die Verbindung verliere, denke ich oft, dass es nur für einen sehr kurzen Zeitraum ist – vielleicht weniger als eine Sekunde.
Ich verwende Ubuntu 14.04 LTS, MATE Edition. Danke
Antwort1
Sie könnten Folgendes verwenden mosh
:https://mosh.org/
Sie könnten einen „Jump“-Server mit einer zuverlässigen Internetverbindung einrichten, mit dem Sie mosh
sich verbinden, und dann ssh
Sitzungen mit jedem Server haben, den Sie verwalten. Der Grund, warum ich die Verwendung eines Jump-Servers vorschlage, ist, dass Sie möglicherweise nicht auf den Servern installieren möchten, mosh
die Sie verwalten.
Ein weiterer Vorteil mosh
besteht darin, dass es auf UDP statt auf TCP basiert und Ihre Sitzung eine Änderung der IP-Adresse übersteht, z. B. den Wechsel von WLAN zu einer mobilen Internetverbindung.
Nur um das klarzustellen: mosh
ist kein Ersatz für screen
, sondern . Es ist trotzdem eine gute Idee , es zusammen ssh
zu verwenden , da selbst keine Möglichkeit bietet, die Verbindung zu Ihrer Sitzung wiederherzustellen, wenn der Client aus irgendeinem Grund abstürzt.screen
mosh
Antwort2
Verwenden Sie die SSH- ServerAlive
Optionen, um festzustellen, wann die Verbindung fehlgeschlagen ist.
ServerAliveCountMax
Legt die Anzahl der Server-Alive-Nachrichten (siehe unten) fest, die gesendet werden können, ohne dass ssh(1) Nachrichten vom Server zurückerhält. Wenn dieser Schwellenwert erreicht wird, während Server-Alive-Nachrichten gesendet werden, trennt ssh die Verbindung zum Server und beendet die Sitzung. Es ist wichtig zu beachten, dass sich die Verwendung von Server-Alive-Nachrichten stark von TCPKeepAlive (unten) unterscheidet. Die Server-Alive-Nachrichten werden über den verschlüsselten Kanal gesendet und sind daher nicht fälschbar. Die von TCPKeepAlive aktivierte TCP-Keepalive-Option ist fälschbar. Der Server-Alive-Mechanismus ist wertvoll, wenn der Client oder Server wissen müssen, wann eine Verbindung inaktiv geworden ist.Der Standardwert ist 3. Wenn beispielsweise ServerAliveInterval (siehe unten) auf 15 eingestellt ist und ServerAliveCountMax auf dem Standardwert belassen wird, wird die SSH-Verbindung nach etwa 45 Sekunden getrennt, wenn der Server nicht mehr reagiert.
ServerAliveInterval
Legt ein Timeout-Intervall in Sekunden fest, nach dessen Ablauf ssh(1) eine Nachricht über den verschlüsselten Kanal sendet, um eine Antwort vom Server anzufordern, wenn keine Daten vom Server empfangen wurden. Der Standardwert ist 0, was bedeutet, dass diese Nachrichten nicht an den Server gesendet werden.
Wenn Sie also ServerAliveInterval
5 einstellen, ssh
wird die Verbindung automatisch getrennt, wenn das Netzwerk für 15 Sekunden ausfällt.
Antwort3
Ich verwendetmux
seit ein paar Jahren und meiner Erfahrung nach stellt es die Verbindung automatisch wieder her. Zumindest, wenn die Verbindung nur für relativ kurze Zeit unterbrochen ist. Beachten Sie, dass ich tatsächlichbyobu
mit tmux als Backend. Ich weiß nicht, ob diese Robustheit ein Merkmal der beiden tmux
oder byobu
sogar der Kombination der beiden ist, aber ich schlage vor, dass Sie beides ausprobieren.
Ich verbinde mich von meiner lokalen Arch-Installation über ein VPN mit verschiedenen Remote-Ubuntu-Servern. Ich habe es gerade getestet, indem ich mein Netzwerkkabel abgezogen habe, während ich mit dem Remote verbunden war. Die Sitzung blieb hängen, aber sobald mein Kabel wieder eingesteckt war, wurde sie nahtlos fortgesetzt.
Als ich meinen Router jedoch zum Testen neu gestartet habe, kam die Verbindung nicht zurück. Ich nehme an, es hat etwas damit zu tun, wie lange das Netzwerk ausgefallen war, aber es scheint, als würde die Verbindung wiederhergestellt, wenn es nur ein paar Sekunden ausgefallen ist.
Falls es relevant ist, ich mache das alles mitterminator
als mein Terminalemulator.
Alle drei sind in den Ubuntu-Repositories verfügbar:
sudo apt-get install tmux terminator byobu
Ich bin mir jedoch überhaupt nicht sicher, ob einer von beiden tmux
besser byobu
mit SSH-Verbindungsunterbrechungen umgehen kann. Ich weiß nur, dass sie meiner Erfahrung nach oft nach kurzen Verbindungsabbrüchen wiederhergestellt werden. Das kann jedoch an anderen Aspekten meiner Konfiguration liegen.
Antwort4
Haftungsausschluss
Wenn Ihre SSH-Verbindung kurze Netzwerkausfälle nicht übersteht, dann gibt esetwas anderesDas passiert, weil ssh
TCP nicht die normale Arbeit verrichten kann.
Weitere Einzelheiten finden Sie weiter unten. Wie dem auch sei:
Die schnellste und unkomplizierteste Lösung ohne Abhängigkeiten
Erstellen Sie ein Shell-Skript wie dieses:
#!/bin/sh -
# Tune these numbers depending on how aggressively
# you want your SSH session to get reconnected.
timeout_options='-o ServerAliveInterval=4 -o ServerAliveCountMax=2'
# 255 is the status OpenSSH uses to signal SSH errors, which
# means we want to connect. All other exit statuses suggest
# an intentional exit.
status=255
# Keep opening the SSH connection and immediately dropping into
# `screen` until an intentional exit happens.
while [ "$status" = 255 ]
do
ssh $timeout_options -t "$@" screen -dR
status=$?
# You can add a `sleep` command here or a counter or whatever
# you might need as far as rate/retry limiting.
done
exit "$status"
Dadurch wird einfach eine ganz einfache Schleife ausgeführt, die immer wieder versucht, eine Verbindung herzustellen ssh
und anzuhängen screen
. Übergeben Sie den Host oder was auch immer Sie normalerweise an Ihren ssh
Aufruf als Befehlszeilenargumente übergeben würden.
Die erneute Verbindung basiert nur darauf, ob SSH einen Verbindungsfehler meldet. Dies bedeutet, dass es nicht über die Fähigkeit verfügt, Nicht-SSH-Fehler wie „Sie haben WLAN buchstäblich nicht eingeschaltet“ oder ähnliches zu erkennen. Aber das ist für Sie wahrscheinlich nicht wichtig.
Ich gehe davon aus, dass Sie über ssh-agent
einen SSH-Schlüssel ohne Passphrase verfügen, mit dem erneute Verbindungen ohne weitere Eingaben Ihrerseits funktionieren.
Es wird einen winzigen Wettlaufzustand geben, bei dem Sie, wenn Sie ^C
während einer erneuten Verbindung genau im richtigen, für den Menschen nicht wahrnehmbaren Sekundenbruchteil eingreifen, am Ende das Skript beenden könnten, anstatt es ^C
an das Client-Terminal weiterzuleiten. Wenn Sie also vermuten, dass die Verbindung hängen bleibt, sollten Sie nicht ^C
zu eifrig herumhämmern.
Einfachste zusätzliche Softwarelösung
Sie können das Programm ausprobierenautossh, das in Ihrem Ubuntu-Paket-Repository verfügbar sein sollte.
Wenn Sie aus dem Quellcode erstellen oder ihn prüfen müssen, handelt es sich um ein einzelnes C-Programm, das ohne zusätzliche Bibliotheken als Abhängigkeiten kompiliert wird und über mehr Intelligenz bei der Überprüfung der Verbindungsaktivität zu verfügen scheint als mein Hack oben.UndEs wird außerdem mit einem praktischen rscreen
Skriptbefehl geliefert, der automatisch eine Verbindung herstellt screen
.
Einzelheiten
Wie ssh
erholt sich normalerweise
Nur zur Sicherheit – ich sage nicht gerne Dinge, ohne sie zu kontrollieren – habe ich vor der Antwort einen kleinen Test durchgeführt:
Ich habe mich mit einem Linux-Gerät in mein WLAN eingeloggt, eine SSH-Verbindung zu einem anderen Gerät in meinem LAN hergestellt, überprüft, ob ich eine funktionierende ssh
Verbindung zum anderen Ende hatte (Befehle ausführen konnte usw.), und dann auf dem ClientWLAN getrennt(wodurch die Schnittstelle dekonfiguriert wurde: keine IP-Adressen mehr), habe noch eine Menge Zeichen in die SSH-Sitzung eingegeben (natürlich keine Reaktion) und dann die Verbindung zu meinem WLAN wiederhergestellt – die Wiederherstellung der Verbindung schlug tatsächlich mindestens einmal aufgrund eines schlechten Signals und anderer Faktoren fehl, dann habe ich die Verbindung schließlich wiederhergestellt: Ich habe ungefähr fünf Sekunden gewartet, bis die ssh
Sitzung wiederhergestellt war, nichts geschah, also habe ich eine weitere Taste gedrückt und die ssh
Sitzung wurde sofort wieder aktiviert, wobei alle Tasten, die ich während der Trennung eingegeben hatte, in der Befehlszeile erschienen.
Sehen Sie, ssh
schreibt/liest einfach in den TCP-Netzwerk-Socket, bis das Betriebssystem ihm sagt, dass etwas schiefgelaufen ist, und TCP ist tatsächlichsehrtolerant gegenüber längeren Verbindungsabbrüchen.
Wenn man es mit den Standard-Kerneleinstellungen sich selbst überlässt, toleriert der TCP-Stack in Linux problemlos mehrere Minuten lang eine völlige Unterbrechung der Verbindung, bevor er sie für tot erklärt und einen Fehler meldet. ssh
Bis er schließlich aufgibt, vergehen ungefähr 30 Minuten, oder zumindest lange genug, um Verbindungsabbrüche von einer Sekunde oder Minute zu überstehen.
Im Hintergrund versucht der Linux-TCP-Stapel jedoch nach und nach, Nachrichten mit immer längeren Verzögerungen erneut zu übermitteln. Das bedeutet, dass es bis Ihre Verbindung wiederhergestellt ist, möglicherweise zu weiteren Verzögerungen kommen kann, bevor Ihre ssh
Sitzung scheinbar wieder „lebendig“ wird.
Warum das manchmal kaputt geht
Oftmals ist es ein aktiver Grund dafür, dass die Verbindung nach einiger Zeit geschlossen wird.deutlich kürzerDie Inaktivitätsdauer ist länger als vom TCP-Stapel toleriert, und anschließend wird der Verbindungsstatus nicht an Ihren ssh
Client gemeldet.
Mögliche Kandidaten sind:
Firewalls oder NAT-Router, die sich an jede aktive TCP-Verbindung erinnern müssen - als Optimierung und als Schutz vor DOS-Angriffen werden sie manchmal einfachvergessenIhre Verbindung und dannstillschweigend ignorierenKonsequente Pakete dafür, denn Pakete mitten in einer Verbindung, wenn Sie sich nicht daran erinnern, dass die Verbindung besteht, sehen ungültig aus.
Besser funktionierende Firewalls/Router fügen ein TCP-RST-Paket ein, das sich normalerweise als
connection reset by peer
Fehlermeldung äußert, bei dem Reset-Paket handelt es sich jedoch um ein Fire-and-Forget-Paket. Wenn also in diesem Moment immer noch Verbindungsprobleme mit Ihrem Client bestehen und das Reset-Paket ebenfalls gelöscht wird, geht Ihr Client davon aus, dass die Verbindung noch aktiv ist.Der Kellnerselbstverfügt möglicherweise über eine Firewall-Richtlinie zum stillschweigenden Löschen unerwarteter Pakete, wodurch die Versuche des Clients zur Wiederherstellung der Verbindung unterbrochen würden, wenn der Server denkt, die Verbindung sei beendet, der Client jedoch nicht: Ihr Client versucht weiterhin, die Verbindung aufrechtzuerhalten, aber der Server ignoriert dies einfach, da im Firewall-Status des Servers keine Live-Verbindung besteht, zu der diese Pakete gehören.
Da Sie Linux verwenden, überprüfen Sie sorgfältig das
iptables
/ Ihres Serversip6tables
(odernft
, wenn Sie das neue Zeug verwenden), um genau zu sehen, was Sie zulassen bzw. weglassen. Es ist sehr üblich, zuzulassenneu/gegründet/verwandtPakete auf dem TCP SSH-Port, abernicht„ungültige“ - wenn Sie alles, was nicht erlaubt ist, stillschweigend löschen, könnte diese gängige Konfiguration nach kurzen Verbindungsproblemen zu solchen Einfrierungen führen.Ihr SSH-Server selbst ist möglicherweise so konfiguriert, dass die Verbindung nach einer Zeit der Inaktivität geschlossen wird. Dazu wird eine der OpenSSH-Optionen für TCP- oder SSH-Client-Keepalive-Pakete verwendet. Dies allein führt nicht zu dauerhaften Hängern, kann Sie aber in einen der oben beschriebenen Zustände versetzen.
Möglicherweise geben Sie ihm einfach nicht genug Zeit, sich selbstständig wieder zu lösen, nachdem die
ssh
Sitzung abgebrochen wurde.