154 votes

Pourquoi les consoles se bloquent-elles parfois indéfiniment lorsque la connexion SSH est interrompue ?

J'ai vu cela avec de nombreuses consoles (sous Linux, Mac, ...), et avec beaucoup de machines différentes dans de nombreux réseaux différents. Je n'ai jamais pu trouver la raison exacte pour laquelle cela se produit : Tout ce que vous avez à faire est de vous connecter à une machine via SSH. Si la connexion est interrompue pour une raison quelconque (pour simplifier, disons que le câble réseau a été arraché), alors parfois la console se bloque pour toujours - à d'autres moments, elle sort simplement sans problème vers le Shell parent.

C'est tellement ennuyeux quand cela se produit (par exemple, vous perdez l'historique des commandes.) Y a-t-il peut-être un raccourci clavier secret qui peut forcer une sortie (Ctrl-C ou Ctrl-D ne fonctionnent pas) ? Et quelle est la raison de ce "bug" aléatoire dans toutes les implémentations ?

245voto

Caleb Points 11393

Il existe un raccourci clavier "secret" pour forcer une sortie :~) Depuis la session gelée, tapez ces touches dans l'ordre : Enter~. Le tilde (uniquement après un saut de ligne) est reconnu comme une séquence d'échappement par le client ssh, et le point indique au client de mettre fin à son activité sans autre forme de procès.

Le comportement d'attente prolongée en cas de problèmes de communication n'est pas un bogue, la session SSH attend dans l'espoir que l'autre partie revienne. Si le réseau s'interrompt, parfois même plusieurs jours plus tard, vous pouvez récupérer une session SSH. Bien sûr, vous pouvez lui demander d'abandonner et de mourir en suivant la séquence ci-dessus. Il y a également plusieurs choses que vous pouvez faire, comme définir des délais d'attente dans votre client de sorte que s'il n'a pas de lien actif pendant un certain temps, il se ferme de lui-même, mais le comportement par défaut est de rester aussi connecté que possible !

Editar: Une autre application utile de cette clé d'interruption est d'attirer l'attention du client ssh local et de le mettre en arrière-plan pour revenir à votre Shell local pendant une minute - disons pour obtenir quelque chose de votre historique - puis de le mettre en arrière-plan pour continuer à travailler à distance. Enter~ Ctrl + Z pour envoyer le client ssh dans la file d'attente des tâches d'arrière-plan de votre Shell local, puis fg comme d'habitude pour le récupérer.

Editar: Dans le cas de sessions SSH imbriquées, vous pouvez ajouter plusieurs caractères tilde pour ne sortir que d'une seule des sessions SSH de la chaîne, mais conserver les autres. Par exemple, si vous êtes imbriqué dans 3 niveaux, (c'est-à-dire que vous ssh de local->Machine1->Machine2->Machine3), Enter~. vous ramènera à votre session locale, Enter~~. vous laissera dans Machine1, et Enter~~~. vous laissera dans Machine2. Cela fonctionne également pour d'autres séquences d'échappement, comme le déplacement temporaire de la session ssh en arrière-plan. Ce qui précède fonctionne pour tout niveau d'imbrication, en ajoutant simplement d'autres tildes.

Enfin, vous pouvez utiliser Enter~? pour imprimer un menu d'aide des commandes d'échappement disponibles.

TL;DR - les commandes d'échappement prises en charge sont les suivantes Séquences d'échappement prises en charge :

 ~.   - 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.)

24voto

RD. Points 136

SSH offre une fonction "keep-alive". Ajoutez les éléments suivants à votre fichier local ~/.ssh/config (à créer s'il n'existe pas) :

ServerAliveInterval 15
ServerAliveCount 3

Ce paramètre établit un signal keep-alive envoyé toutes les 15 secondes à travers le tunnel sécurisé. Après trois échecs consécutifs, le client SSH se ferme.

Notez que sur certains systèmes (y compris macOS 10.14), il doit plutôt être :

ServerAliveInterval 15
ServerAliveCountMax 3

Tiré de cette réponse sur ask.ubuntu : https://askubuntu.com/a/29967/30266

10voto

joeqwerty Points 106914

Le fait qu'il se bloque est une fonction de TCP, pas de SSH. L'application n'a aucun moyen de savoir que la session/connexion TCP a été interrompue, à moins que TCP n'informe l'application utilisant la connexion que celle-ci n'existe plus. Du point de vue de chaque hôte, la session TCP est toujours dans l'état Établi et rien ne dit qu'une longue session inactive (aucune donnée ne circule) n'est pas valide, à part un RST ou une absence de réponse à un paquet TCP keepalive (qui n'est pas universellement implémenté). Cela ne me semble pas être un bogue dans SSH, je m'attendrais à ce comportement.

5voto

David Spillett Points 22424

Si la connexion est correctement suspendue, toute frappe magique ne sera pas transmise car la connexion est déjà suspendue avant que vous n'appuyiez sur les touches. Vous pouvez demander au client de mettre fin à la connexion, mais cela n'affectera pas l'historique conservé (ou non) au niveau du serveur.

Bien que cela ne réponde pas vraiment à la question, cela peut aider à réduire les effets d'un blocage de connexion : lorsque je travaille à distance (et même habituellement lorsque je ne le fais pas), je passe par screen (avec ou sans le byobu en fonction de sa disponibilité), de sorte qu'en cas d'interruption de la connexion, ma session, avec tout son historique, est préservée et disponible dans l'état où je l'ai laissée lorsque je me reconnecte.

1voto

Vasin Yuriy Points 101

Dans mon cas, le problème résidait dans la grande taille du MTU. Vous pouvez changer le MTU sur le routeur si vous utilisez le NAT, mais je change le MTU sur le serveur :

sudo /sbin/ifconfig eth0 mtu 1036
sudo /etc/init.d/networking restart

Sous Windows, vous pouvez également augmenter cette touche :

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
"TcpMaxDataRetransmissions"=dword:00000010

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X