Les sessions SSH se bloquent à l'arrêt / au redémarrage

13

J'ai un serveur qui exécute Debian et sshd dessus, et au cas où j'aurais besoin de redémarrer le serveur, ma session SSH se bloque côté client jusqu'au délai TCP. Je suppose que cela est dû au fait que lorsqu'il sshdest terminé, il ne ferme pas explicitement les sessions SSH ouvertes à l'hôte. Que dois-je faire pour d' sshdabord déconnecter tout le monde, puis se terminer normalement? Jusqu'à présent, je ne vois pas de paramètre man sshd_configlié au comportement de fermeture.

Vesper
la source
1
Lorsque tout le reste échoue, vous pouvez tuer un client SSH à tout moment en appuyant sur [Entrée] [~] [.]. Explication sur la façon de résoudre réellement votre problème.
2015

Réponses:

32

Lorsque vous systemdarrêtez ou redémarrez votre système, essaie d'arrêter tous les services aussi vite que possible. Cela implique d'arrêter le réseau et de mettre fin à tous les processus qui sont toujours en vie - généralement dans cet ordre. Ainsi, lorsque systemd tue les processus SSH bifurqués qui gèrent vos sessions SSH, la connexion réseau est déjà désactivée et ils n'ont aucun moyen de fermer la connexion client avec élégance.

Votre première pensée pourrait être de simplement tuer tous les processus SSH comme première étape lors de l'arrêt, et il existe de nombreux fichiers de service systemd qui font exactement cela.

Mais il y a bien sûr une solution plus propre ( la façon dont il est « censé » être fait): systemd-logind.
systemd-logindgarde une trace des sessions utilisateur actives (locales et SSH) et affecte tous les processus générés en leur sein à ce qu'on appelle des "tranches". De cette façon, lorsque le système est arrêté, systemd peut simplement SIGTERM tout ce qui se trouve dans les tranches utilisateur (qui inclut le processus SSH fourchu qui gère une session particulière), puis continuer à arrêter les services et le réseau.

systemd-logindnécessite un module PAM pour être averti des nouvelles sessions utilisateur et vous devrez l' dbusutiliser loginctlpour vérifier son état, alors installez les deux:

apt-get install libpam-systemd dbus

Assurez-vous que vous /etc/ssh/sshd_configallez réellement utiliser le module avec UsePAM yes.

n.st
la source
D'accord, objectif atteint et merci pour l'explication. (Bien que j'aimerais un moyen de contrôle des dépendances pour l'arrêt, afin que tout soit d'abord SIGTERM tout en étant en mesure de terminer leur travail, cela peut être une solution en couches.)
Vesper
Pour une raison quelconque, je n'ai pas été informé de la réponse en visitant uniquement StackOverflow. Bizarre.
Vesper
1
Donc, pour faire court, juste pour raser quelques secondes à l'arrêt, nous devons installer une charge entière de merde juste pour que nos connexions se terminent correctement? Sérieusement ? Ça va mal. Nous sommes condamnés.
leucos
3
Notez que le premier redémarrage après l'installation de libpam-systemd et dbus laisserait toujours votre session SSH en suspens. Pour éviter cela, au lieu de reboot, effectuez une opération shutdown -rqui prend par défaut un délai d'une minute, vous laissant le temps de fermer la session SSH.
mivk
9

C'est quelque chose que vous devez définir côté client, pas côté serveur. Modifiez votre ~/.ssh/configpour contenir

ServerAliveInterval 15
ServerAliveCountMax 5

Cela signifie qu'après 15 secondes d'inactivité, votre client enverra un message au serveur. S'il n'obtient aucune réponse, il réessayera jusqu'à 5 fois, et s'il n'obtient toujours pas de réponse, il fermera la session.

Jenny D
la source
2
Cela entraînera un délai de 75 secondes avant que le client ssh ne signale le serveur mort. Droite?
Vesper
1
Oui, et vous pouvez ajuster les paramètres pour raccourcir le délai.
Tero Kilkanen
Cela a résolu le problème pour moi. Un tel problème irritant.
Justin Andrusk
5

Ce comportement est signalé sur ce bogue Debian , il vous suffit de configurer correctement les scripts d'arrêt livrés avec le paquet car, automatiquement, ils ne sont pas copiés par défaut:

cp /usr/share/doc/openssh-client/examples/ssh-session-cleanup.service /etc/systemd/system/
systemctl  enable ssh-session-cleanup.service
Rfraile
la source
1

Vous pouvez spécifier les options dont Jenny D a parlé dans sa réponse juste pour une commande ssh, comme

ssh -t -o ServerAliveInterval=1 -o ServerAliveCountMax=1 user@host sudo poweroff

si vous le faites souvent, vous pouvez l'écrire.

Diego Medaglia
la source
0

Fonctionne pour moi avec lshd. La solution serait donc

apt install lsh-server
apt remove openssh-server
Dieu
la source
0

malheureusement, serverfault ne m'a pas permis de répondre en raison de trop de points depuis des années. Mais je n'ai pas besoin de spam dans d'autres blogs pour obtenir le déverrouillage ^^ ... donc comme réponse dédiée:

Comme l'a mentionné Rfraile

cp /usr/share/doc/openssh-client/examples/ssh-session-cleanup.service /etc/systemd/system/
systemctl  enable ssh-session-cleanup.service

travaux. Pour l'utiliser sans redémarrer l'instance / le serveur, vous devez effectuer des tâches supplémentaires:

systemctl daemon-reload
systemctl start ssh-session-cleanup.service

le service est donc enregistré et démarré et systemd doit l'arrêter à des fins de redémarrage / arrêt.

Reiner030
la source
Alors, répétez-vous simplement une autre réponse?
RalfFriedl
Non? J'ai utilisé les 2 lignes uniquement comme référence pour la réponse supérieure car je ne peux pas encore répondre comme écrit. J'ai ajouté les étapes nécessaires pour l'utiliser sans redémarrage. Cela peut également être indiqué dans un autre fil de questions, mais que je n'ai pas vérifié.
Reiner030