Haftungsausschluss
Wenn Ihre SSH-Verbindung einen kurzen Netzwerkausfall nicht übersteht, lässt TCP etwas anderes nicht zu ssh
.
Siehe unten für Details. Sowieso:
Die schnellste und schmutzigste Lösung ohne Abhängigkeiten
Erstellen Sie ein Shell-Skript wie folgt:
#!/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"
Dies führt nur eine dumm-einfache Schleife aus, mit der versucht wird, eine Verbindung ssh
herzustellen und eine Verbindung herzustellen screen
. Übergeben Sie den Host oder was auch immer Sie normalerweise ssh
als Befehlszeilenargumente an Ihren Aufruf übergeben würden.
Die erneute Verbindung basiert lediglich darauf, ob SSH einen Fehler bei der Verbindung meldet, was bedeutet, dass es keine Intelligenz zum Erkennen von Nicht-SSH-Fehlern wie "Sie haben WiFI buchstäblich nicht aktiviert" oder was auch immer hat, aber das spielt wahrscheinlich keine Rolle Sie
Ich gehe davon aus, dass Sie über ssh-agent
einen SSH-Schlüssel ohne Passphrase verfügen , mit dem eine erneute Verbindung ohne zusätzliche Eingaben von Ihnen hergestellt werden kann.
Es wird eine winzige Racebedingung geben, bei der Sie, wenn Sie ^C
während eines erneuten Verbindungsaufbaus genau den richtigen, von Menschen nicht wahrnehmbaren Sekundenbruchteil treffen , das Skript beenden können, anstatt die Verbindung ^C
zum Client-Terminal weiterzuleiten Zerdrücke nicht ^C
zu eifrig.
Einfachste zusätzliche Softwarelösung
Sie können das Programm autossh ausprobieren , das in Ihrem Ubuntu-Paket-Repository verfügbar sein sollte.
Wenn Sie es aus dem Quellcode erstellen oder prüfen müssen, handelt es sich um ein einzelnes C-Programm, das ohne zusätzliche Bibliotheken als Abhängigkeiten kompiliert wird, mehr Informationen zur Überprüfung der Verbindungsbelebung zu haben scheint als mein Hack oben, und es wird auch mit einem praktischen rscreen
Skriptbefehl ausgeliefert, der auto -anhängt an screen
.
Einzelheiten
Wie ssh
normal erholt
Nur zur Überprüfung, da ich Dinge nicht gerne sage, ohne mich selbst zu überprüfen, habe ich einen kleinen Test durchgeführt, bevor ich antwortete:
Ich habe mit einem Linux-Gerät auf mein WLAN zugegriffen, eine SSH-Verbindung zu einem anderen Gerät in meinem LAN hergestellt, überprüft, ob ich eine funktionierende ssh
Verbindung zum anderen Ende habe (Befehle ausführen usw.), und dann auf dem Client das WLAN getrennt (wodurch die Schnittstelle verursacht wurde) zu dekonfigurieren: keine IP-Adressen mehr), ein paar weitere Zeichen in die ssh-Sitzung eingegeben (natürlich keine Antwort) und dann erneut mit meinem WLAN verbunden - die erneute Verbindung schlug mindestens einmal aufgrund eines schlechten Signals und anderer Faktoren fehl , dann endlich wieder verbunden: Ich wartete ungefähr fünf Sekunden, ssh
bis sich die Sitzung erholte, nichts geschah, also drückte ich eine weitere Taste, und die ssh
Sitzung wurde sofort wieder lebendig, wobei alle Tasten, die ich während der Trennung eingegeben hatte, in der Befehlszeile angezeigt wurden.
Sehen Sie, ssh
schreiben / lesen Sie einfach in den TCP-Netzwerk-Socket, bis das Betriebssystem meldet, dass ein Fehler aufgetreten ist, und TCP ist tatsächlich sehr tolerant gegenüber längeren Verbindungsabbrüchen.
Wenn der TCP-Stack in Linux mit den Standard-Kernel-Einstellungen auf seine eigenen Geräte gestellt ist, toleriert er es, dass die Verbindung viele Minuten lang völlig still ist, bevor er die Verbindung für tot erklärt und einen Fehler meldet ssh
- bis es endgültig aufgibt, reden wir im Ballpark von ~ 30 Minuten, oder zumindest mit Sicherheit lang genug, um Verbindungsprobleme von einer Sekunde oder einer Minute Dauer zu überstehen.
Im Hintergrund versucht der Linux-TCP-Stack nach und nach, Nachrichten mit immer längeren Verzögerungen erneut abzurufen. Dies bedeutet jedoch, dass Sie möglicherweise eine zusätzliche Verzögerung feststellen, bevor Ihre ssh
Sitzung wieder "lebendig" zu werden scheint.
Warum das manchmal kaputt geht
Häufig wird die Verbindung nach einer erheblich kürzeren Inaktivitätsdauer als der vom TCP-Stack tolerierten Zeitspanne aktiv geschlossen, und der Verbindungsstatus wird dann nicht an Ihren ssh
Client gemeldet .
Mögliche Kandidaten sind:
Firewalls oder NAT'ing-Router, die Speicher benötigen, um sich an jede Live-TCP-Verbindung zu erinnern - als Optimierung und als Abwehrmaßnahme gegen DOS-Angriffe vergessen sie manchmal einfach Ihre Verbindung und ignorieren dann automatisch die darauf folgenden Pakete, da Pakete in der mitten in einer Verbindung, wenn Sie sich nicht erinnern, dass die bestehende Verbindung ungültig ist.
Besser funktionierende Firewalls / Router injizieren ein TCP-RST-Paket, das normalerweise als connection reset by peer
Fehlermeldung angezeigt wird. Das zurückgesetzte Paket ist jedoch ein "Fire-and-Forget" -Paket. Wenn also in diesem Moment die Verbindung zu Ihrem Client weiterhin Probleme aufweist, wird das TCP-RST-Paket gelöscht Paket auch zurücksetzen, Ihr Client wird denken, dass die Verbindung noch besteht.
Der Server selbst verfügt möglicherweise über eine Firewall-Richtlinie, mit der unerwartete Pakete stillschweigend verworfen werden. Dadurch werden die Verbindungswiederaufnahmeversuche des Clients abgebrochen, wenn der Server denkt, dass die Verbindung geschlossen ist, der Client jedoch nicht: Ihr Client versucht weiterhin, die Verbindung fortzusetzen, der Server jedoch Ignorieren, da es keine Live-Verbindung gibt, zu der diese Pakete im Firewall-Status des Servers gehören.
Da Sie Linux verwenden, prüfen Sie sorgfältig, ob Ihr Server iptables
/ ip6tables
(oder nft
ob Sie das neue Material verwenden) genau das zulässt, was Sie zulassen, oder nicht. Es ist üblich, neue / eingerichtete / verwandte Pakete auf dem TCP-SSH-Port zuzulassen , aber keine "ungültigen". Wenn Sie im Hintergrund alles ablegen, was nicht zulässig ist, kann dieses übliche Setup nach kurzen Verbindungsproblemen zu solchen Einfrierungen führen .
Ihr SSH-Server selbst ist möglicherweise so konfiguriert, dass die Verbindung nach einer gewissen Zeit der Inaktivität geschlossen wird, indem Sie eine der OpenSSH-Optionen für Keepalive-Pakete für TCP- oder SSH-Clients verwenden. An sich führt dies nicht zu unbestimmten Hängen, aber es kann Sie in einen der oben beschriebenen Zustände versetzen.
Es ist möglich, dass Sie ihm nicht genug Zeit geben, um sich von selbst zu lösen, nachdem Sie in den Zustand gekommen sind, in dem Ihre ssh
Sitzung aufgelegt hat.
<Enter>
und geben Sie ein~.
, um Ihre Seite anzuweisen, die Verbindung zu trennen, und wiederholen Sie einfach den letzten ssh-Befehl, um die Verbindung wiederherzustellen (z. B. mit dem Aufwärtspfeil oder!!
).