Avertissement
Si votre connexion SSH ne survit pas à de brèves pannes de réseau, alors il se passe autre chose qui ne permet pas à ssh
TCP de faire son travail normal.
Voir ci-dessous pour plus de détails. En tous cas:
La solution sans dépendances la plus rapide et la plus sale
Créez un script shell comme celui-ci:
#!/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"
Cela exécutera simplement une boucle stupide-simple qui continue d'essayer de se connecter ssh
et de s'y attacher screen
. Passez l'hôte ou tout ce que vous passez normalement à votre ssh
appel en tant qu'arguments de ligne de commande.
La reconnexion est simplement basée sur le fait que SSH signale une erreur avec la connexion, ce qui signifie qu'il n'a aucune intelligence pour détecter les erreurs non SSH comme "vous n'avez littéralement pas WiFI activé" ou autre, mais cela n'a probablement pas d'importance pour vous.
Je suppose que vous avez ssh-agent
ou une clé SSH sans phrase de passe qui permettra aux reconnexions de fonctionner sans aucune entrée supplémentaire de votre part.
Il va y avoir une petite condition de course où si vous frappez ^C
pendant juste la bonne fraction de seconde imperceptible par l'homme pendant une reconnexion, vous pourriez finir par tuer le script au lieu de passer ^C
par le terminal client, donc si vous suspectez une connexion de se bloquer ne pas écraser ^C
trop zélé.
Solution logicielle supplémentaire la plus simple
Vous pouvez essayer le programme autossh , qui devrait être disponible dans votre référentiel de paquets Ubuntu.
Si vous avez besoin de construire à partir de la source ou de l'auditer, c'est un seul programme C qui se compile sans bibliothèques supplémentaires en tant que dépendances, semble avoir plus d'informations sur la vérification de la vivacité de la connexion que mon hack ci-dessus, et il est également livré avec une rscreen
commande de script pratique qui auto -attache à screen
.
Détails
Comment ssh
récupère normalement
Juste pour vérifier, parce que je n'aime pas dire des choses sans me vérifier, j'ai fait un petit test avant de répondre:
Je me suis connecté à mon WiFi avec un appareil Linux, j'ai établi une connexion SSH avec un autre appareil sur mon LAN, vérifié que j'avais une ssh
connexion fonctionnelle à l'autre extrémité (je pouvais exécuter des commandes, etc.), puis le client a déconnecté le WiFi (provoquant l'interface à déconfigurer: plus d'adresses IP), tapé un tas de caractères dans la session ssh (pas de réponse, bien sûr), puis reconnecté à mon WiFi - la reconnexion a en fait échoué au moins une fois en raison d'un mauvais signal et d'autres facteurs , puis finalement reconnecté: j'ai attendu environ cinq secondes pour que la ssh
session se rétablisse, rien ne s'est passé alors j'ai appuyé sur une touche de plus, et la ssh
session a repris vie immédiatement, avec toutes les clés que j'avais tapées lors de la déconnexion apparaissant sur la ligne de commande.
Vous voyez, il ssh
suffit d'écrire / lire dans le socket réseau TCP jusqu'à ce que le système d'exploitation lui dise que quelque chose s'est mal passé, et TCP est en fait très tolérant aux chutes de connexion prolongées.
Laissée à ses propres appareils avec les paramètres de noyau par défaut, la pile TCP sous Linux tolérera volontiers la connexion complètement silencieuse pendant plusieurs minutes avant de déclarer la connexion morte et de signaler une erreur ssh
- au moment où elle abandonne finalement, nous parlons dans le stade approximatif de ~ 30 minutes, ou du moins certainement assez longtemps pour survivre à des hoquets de connexion qui durent une seconde ou une minute.
Sous les couvertures, la pile Linux TCP réessaye progressivement les messages avec des délais de plus en plus longs, cependant, ce qui signifie qu'au moment où votre connexion revient, vous pourriez envisager un décalage supplémentaire avant que votre ssh
session ne semble à nouveau "vivante".
Pourquoi cela casse parfois
Souvent, quelque chose provoque activement la fermeture de la connexion après une période d'inactivité considérablement plus courte que la quantité tolérée par la pile TCP, puis ne signale pas cet état de connexion à votre ssh
client.
Les candidats probables comprennent:
Pare-feu ou routeurs NAT, qui doivent utiliser de la mémoire pour se souvenir de chaque connexion TCP en direct - en tant qu'optimisation et atténuation contre les attaques DOS, ils oublient parfois simplement votre connexion, puis ignorent silencieusement les paquets conséquents pour cela, car les paquets dans le au milieu d'une connexion lorsque vous ne vous souvenez pas que la connexion existante n'est pas valide.
Les pare-feu / routeurs qui se comportent mieux injectent un paquet TCP RST, qui se manifeste généralement sous la forme d'un connection reset by peer
message d'erreur, mais le paquet de réinitialisation est un feu et oublie, donc si la connexion à votre client rencontre toujours des problèmes à ce moment-là et abandonne le réinitialiser le paquet aussi, votre client pensera que la connexion est toujours active.
Le serveur lui - même peut avoir une politique de pare-feu pour supprimer silencieusement les paquets inattendus, ce qui interromprait les tentatives de reprise de connexion du client chaque fois que le serveur pense que la connexion est fermée mais pas le client: votre client continue d'essayer de continuer la connexion, mais le serveur est juste l'ignorer car il n'y a pas de connexion active à laquelle ces paquets appartiennent dans l'état du pare-feu du serveur.
Puisque vous utilisez Linux, vérifiez soigneusement iptables
/ / ip6tables
ou nft
si vous utilisez les nouveaux éléments de votre serveur pour savoir exactement ce que vous autorisez par rapport à la suppression. Il est très courant d'autoriser les paquets nouveaux / établis / associés sur le port TCP SSH, mais pas les paquets "non valides" - si vous supprimez silencieusement tout ce qui n'est pas autorisé, cette configuration courante pourrait provoquer ce genre de gel après de brefs problèmes de connexion .
Votre serveur SSH lui-même peut être configuré pour fermer la connexion après une période d'inactivité, en utilisant l'une des options OpenSSH pour les paquets persistants du client TCP ou SSH. En soi, cela ne provoquera pas de blocages indéfinis, mais cela peut vous mettre dans l'un des états décrits ci-dessus.
Il est possible que vous ne lui laissiez pas suffisamment de temps pour «se désengager» de lui-même après être entré dans l'état où votre ssh
session raccroche.
<Enter>
et tapez~.
pour dire à votre côté de supprimer la connexion, et vous pouvez simplement répéter la dernière commande ssh pour vous reconnecter (par exemple avec la flèche vers le haut ou!!
).