Ich benutze einen SSH-Tunnel von der Arbeit, um verschiedene idotische Firewalls zu umgehen (bei meinem Chef ist das in Ordnung :)). Das Problem ist, dass nach einer Weile die SSH-Verbindung normalerweise unterbrochen wird und der Tunnel unterbrochen wird.
Wenn ich den Tunnel zumindest automatisch überwachen könnte, könnte ich den Tunnel neu starten, wenn er hängt, aber ich habe nicht einmal eine Möglichkeit gefunden, dies zu tun.
Bonuspunkte für denjenigen, der mir sagen kann, wie ich verhindern kann, dass meine SSH-Verbindung hängt!
watch
wie Befehl:watch -n1 60 echo "wiiiii"
. Der Tunnel stirbt erst, wenn das Netzwerk unterbrochen ist oder Sie es nicht verwenden.Antworten:
Klingt so, als ob Sie autossh brauchen . Dadurch wird ein SSH-Tunnel überwacht und bei Bedarf neu gestartet. Wir haben es für ein paar Jahre benutzt und es scheint gut zu funktionieren.
Weitere Details zum -M-Parameter hier
quelle
autossh
in der Antwort verwenden?autossh -f -nNT -i ~/keypair.pem -R 2000:localhost:22 [email protected]
Möglicherweise bemerken Sie, dass ich dies mit -nNT eingerichtet habe, wodurch kein Remote-Terminal erstellt wird, sodass ich autossh in den Hintergrund stellen kann, und mit der Option -i, damit SSH eine PEM-Datei verwendet. Wenn Sie die ganze Zeit über eine Verbindung offen halten, empfehle ich auf jeden Fall, das zusätzliche Setup durchzuarbeiten.-M
Parameter wegzulassen : bugs.debian.org/cgi-bin/bugreport.cgi?bug=351162Alle Stateful Firewalls vergessen eine Verbindung, nachdem sie einige Zeit kein Paket für diese Verbindung gesehen haben (um zu verhindern, dass die Statustabellen mit Verbindungen voll werden, bei denen beide Enden gestorben sind, ohne die Verbindung zu schließen). Die meisten TCP-Implementierungen senden nach einer langen Zeit ein Keepalive-Paket, ohne von der anderen Seite zu hören (2 Stunden sind ein üblicher Wert). Wenn es jedoch eine Stateful Firewall gibt, die die Verbindung vergisst, bevor die Keepalive-Pakete gesendet werden können, wird eine langlebige, aber inaktive Verbindung unterbrochen.
In diesem Fall besteht die Lösung darin, zu verhindern, dass die Verbindung inaktiv wird. OpenSSH verfügt über eine Option namens ServerAliveInterval , mit der verhindert werden kann, dass die Verbindung zu lange inaktiv ist.
quelle
Konfigurieren Sie Ihren ssh auf Ihrem eigenen Mac oder Linux-Computer und halten Sie den ssh-Server alle 3 Minuten am Leben. Öffne ein Terminal und bring deine unsichtbare .ssh zu dir nach Hause:
Dann erstelle eine 1-zeilige Konfigurationsdatei mit:
Sie sollten auch hinzufügen:
Der Standardwert ist 3, sodass ServerAliveInterval 180 den Sendevorgang nach 9 Minuten beendet (3 des von ServerAliveInterval angegebenen 3-Minuten-Intervalls).
quelle
ServerAliveInterval 180
geben Sie uns 6 Minuten? Intuition macht mich dies versuchen:180/60 == 3
. Funktioniert das alsoServerAliveInterval
in Vielfachen von 30 Sekunden?Ich habe das folgende Bash-Skript verwendet, um weiterhin neue ssh-Tunnel zu erzeugen, wenn der vorherige stirbt. Die Verwendung eines Skripts ist praktisch, wenn Sie keine zusätzlichen Pakete installieren möchten oder können oder den Compiler verwenden.
Beachten Sie, dass hierfür eine Schlüsseldatei erforderlich ist, um die Verbindung automatisch herzustellen. Dies gilt jedoch auch für autossh.
quelle
Dafür ist Systemd bestens geeignet.
Erstellen Sie eine Servicedatei
/etc/systemd/system/sshtunnel.service
mit:(Ändern Sie den Befehl ssh entsprechend.)
sshtunnel
, stellen Sie also sicher, dass der Benutzer zuerst existiertsystemctl enable sshtunnel
, um es so einzustellen, dass es beim Booten startetsystemctl start sshtunnel
sofort zu startenUpdate Januar 2018 : Einige Distributionen (z. B. Fedora 27) verwenden möglicherweise die SELinux-Richtlinie, um die Verwendung von SSH von systemd init zu verhindern. In diesem Fall muss eine benutzerdefinierte Richtlinie erstellt werden, um die erforderlichen Ausnahmen bereitzustellen.
quelle
systemd
System. Wenn manRestart=on-failure
den SSH-Client verwendet, führt das manuelle Beenden nicht zu einem Neustart durch das System, da der SSH-Client mit Erfolg beendet wird.ExecStart
um beispielsweise diessh
Argumentliste zu erstellen , führen Sie grundlegende Überprüfungen usw. durch, und rufen Sie es dann wie folgt aus dem Skript aufexec /bin/ssh -N ...
. Hier ist mein Befehl:exec /bin/ssh -N -oExitOnForwardFailure=Yes -oTCPKeepAlive=no -oServerAliveInterval=5 -oServerAliveCountMax=6 -i "${LOCAL_PRIVATE_KEY}" -L "${TUNNEL_INLET}:${TUNNEL_OUTLET}" "${REMOTE_USER}@${REMOTE_MACHINE}"
woTUNNEL_INLET="127.0.0.1:3307"
undTUNNEL_OUTLET="127.0.0.1:3306"
Mir scheint, dass Sie ServerAliveCountMax falsch interpretieren. Nach meinem Verständnis ist es die Anzahl der Server-Alive-Nachrichten, die unbeantwortet bleiben können, ohne dass die Verbindung beendet wird. Wenn Sie also in den hier beschriebenen Fällen einen hohen Wert festlegen, wird nur sichergestellt, dass eine unterbrochene Verbindung nicht erkannt und beendet wird!
Das einfache Einstellen von ServerAliveInterval sollte ausreichen, um das Problem zu lösen, dass eine Firewall die Verbindung vergisst. Wenn Sie ServerAliveCountMax niedrig lassen, kann das Ursprungsende den Fehler feststellen und die Verbindung beenden, wenn die Verbindung trotzdem fehlschlägt.
Was Sie möchten, ist, 1) dass die Verbindung unter normalen Umständen permanent offen bleibt, 2) dass ein Verbindungsfehler erkannt wird und die Ursprungsseite bei einem Fehler beendet wird, und 3) dass der Befehl ssh jedes Mal neu ausgegeben wird Exits (wie Sie das machen, ist sehr plattformabhängig, das von Jawa vorgeschlagene "while true" -Skript ist eine Möglichkeit, unter OS XI tatsächlich ein launchd-Element einzurichten).
quelle
Verwenden Sie immer die
ServerAliveInterval
SSH-Option, wenn die Tunnelprobleme durch abgelaufene NAT-Sitzungen generiert werden.Verwenden Sie immer eine Respawn-Methode, wenn die Konnektivität vollständig ausfällt. Hier haben Sie mindestens drei Möglichkeiten:
while true do ssh ...; sleep 5; done
) entfernt den Befehl sleep nicht, schlägtssh
möglicherweise schnell fehl und Sie werden zu viele Prozesse erneut erzeugen/etc/inittab
Um Zugriff auf eine Box zu erhalten, die in einem anderen Land geliefert und installiert wurde, und zwar hinter NAT, ohne dass ein Port an die Box weitergeleitet wird, können Sie diese so konfigurieren, dass ein SSH-Tunnel für Sie erstellt wird:Upstart-Skript auf Ubuntu, wo
/etc/inittab
nicht verfügbar:oder immer beide Methoden anwenden.
quelle
Ich habe dieses Problem folgendermaßen gelöst:
Bearbeiten
Und füge hinzu
Laut Manpage für ssh_config:
quelle
ExitOnForwardFailure yes
ist eine gute Ergänzung zu den anderen Vorschlägen. Wenn eine Verbindung hergestellt wird, die Portweiterleitung jedoch nicht hergestellt werden kann, ist dies für Sie genauso nutzlos, als ob überhaupt keine Verbindung hergestellt worden wäre.quelle
Ich musste einen SSH-Tunnel langfristig unterhalten. Meine Lösung wurde von einem Linux-Server ausgeführt und es ist nur ein kleines C-Programm, das ssh mithilfe der schlüsselbasierten Authentifizierung wiederherstellt.
Ich bin nicht sicher, ob ich hängen soll, aber ich habe Tunnel wegen Timeouts sterben lassen.
Ich würde gerne den Code für den Respawner bereitstellen, aber ich kann ihn augenblicklich nicht finden.
quelle
während es tools wie autossh gibt, die helfen, ssh session neu zu starten ... was ich wirklich nützlich finde, ist, den 'screen'-befehl auszuführen. Sie können Ihre ssh-Sitzungen auch nach dem Trennen der Verbindung fortsetzen. Besonders nützlich, wenn Ihre Verbindung nicht so zuverlässig ist, wie sie sein sollte.
... vergessen Sie nicht zu markieren, dies ist die "richtige" Antwort, wenn es Ihnen hilft, k! ;-)
quelle
Ein bisschen hacken, aber ich benutze gerne Bildschirm, um dies zu halten. Ich habe derzeit eine Remote-Weiterleitung, die seit Wochen ausgeführt wird.
Beispiel, lokal starten:
Wenn die Remote-Weiterleitung angewendet wird und Sie eine Shell auf dem Remote-Computer haben:
Sie haben jetzt eine ununterbrochene Remote-Weiterleitung. Der Trick besteht darin, den Bildschirm an beiden Enden auszuführen
quelle
Vor kurzem hatte ich dieses Problem, da Sie bei diesen Lösungen jedes Mal das Kennwort erneut eingeben müssen, wenn Sie eine Kennwortanmeldung verwenden. Ich habe sshpass in einer Schleife zusammen mit einer Textaufforderung verwendet, um zu vermeiden, dass das Kennwort in der Batchdatei enthalten ist.
Dachte, ich würde meine Lösung auf diesem Thead teilen, falls jemand das gleiche Problem hat:
quelle
Ich hatte ähnliche Probleme mit meinem vorherigen ISP. Für mich war es mit jeder TCP-Verbindung, dem Besuch von Websites oder dem Versenden von E-Mails dasselbe.
Die Lösung bestand darin, eine VPN-Verbindung über UDP zu konfigurieren (ich verwendete OpenVPN). Diese Verbindung war toleranter gegenüber den Ursachen der Unterbrechungen. Dann können Sie jeden Dienst über diese Verbindung ausführen.
Es kann immer noch Probleme mit der Verbindung geben, aber da der Tunnel toleranter ist, fühlt sich jede SSH-Sitzung eher als eine kurze Verzögerung an, als dass die Verbindung getrennt wird.
Dazu benötigen Sie einen VPN-Dienst online, den Sie auf Ihrem eigenen Server einrichten können.
quelle
Da
autossh
dies nicht unseren Anforderungen entspricht (es ist fehlerhaft, wenn beim ersten Versuch keine Verbindung zum Server hergestellt werden kann), haben wir eine reine Bash-Anwendung geschrieben: https://github.com/aktos-io/link- with-serverStandardmäßig wird ein umgekehrter Tunnel für den sshd-Port (22) des NODE auf dem Server erstellt. Wenn Sie andere Aktionen ausführen müssen (z. B. Weiterleiten zusätzlicher Ports, Senden von E-Mails bei bestehender Verbindung usw.), können Sie Ihre Skripts
on-connect
undon-disconnect
Ordner platzieren.quelle