1 votes

Déconnexion des sessions distantes Shell lors de l'hibernation

Je me suis souvent retrouvé à fermer l'ordinateur portable trop rapidement, avec peu de sessions ssh distantes ouvertes. Et au réveil, je trouve quelques shells morts, qui n'ont pas été fermés :/

Comment puis-je forcer une sortie propre des sessions ssh distantes en cas d'hibernation/suspension/arrêt ?

PS Sur gentoo et ubuntu

2voto

Tuer les clients ssh avant d'hiberner ou de suspendre.

Sur Ubuntu lucid, les scripts suspendus scripts sont en /etc/pm/sleep.d . La documentation se trouve dans le pm-action(8) page de manuel. Ajouter /etc/pm/sleep.d/20_dariusz_kill_ssh contenant quelque chose comme

#!/bin/sh
case $1 in
  suspend|hibernate) pkill -x ssh;;
esac

Je ne sais pas où se trouvent les scripts correspondants sur Gentoo. Vous pourriez vouloir affiner pour exclure ssh à localhost si jamais vous le faites.

Pour l'arrêt, vous n'avez pas besoin de faire quoi que ce soit, les scripts d'arrêt normaux tuent déjà les clients ssh proprement (ils fermeront donc la connexion).

Notez que laisser la session ouverte n'est pas un gros problème. Tout ce que vous gagnez en la tuant prématurément est de récupérer quelques ressources sur le serveur ssh et quelques pare-feu sur le chemin. Vous pourriez donc tuer les clients au moment de la reprise, et seulement si la connexion est perdue. Si vous choisissez cette approche, je pense que le bon endroit est dans les scripts du réseau : enregistrer les sessions ssh actives lorsque le réseau s'arrête, et éventuellement les tuer lorsque le réseau revient.

Voici une preuve de concept (complètement non testée). Sur /etc/network/if-down.d/ssh-sessions-record (emplacement Ubuntu), enregistrez l'adresse IP associée à l'interface disparue et l'heure à laquelle l'interface est tombée :

#!/bin/sh
{
  echo OLD_IP=$(ifconfig "$IFACE" | sed -n 's/^ *inet addr:\([0-9.]\+\).*/\1/p')
  echo OLD_DATE=$(date +%s)
} >"/var/run/$IFACE.ssh-sessions-record"

/etc/network/if-up.d/ssh-sessions-record pour tuer les connexions ssh qui sont passées par cette interface réseau, mais seulement si l'adresse IP a changé ou si suffisamment de temps s'est écoulé pour que le serveur ait pu s'arrêter :

#!/bin/sh
if [ -e "/var/run/$IFACE.ssh-sessions-record" ]; then
. "/var/run/$IFACE.ssh-sessions-record"
NEW_IP=$(ifconfig "$IFACE" | sed -n 's/^ *inet addr:\([0-9.]\+\).*/\1/p')
NEW_DATE=$(date +%s)
if [ "$NEW_IP" != "$OLD_IP" ] || [ $(($NEW_DATE-$OLD_DATE)) -ge 300 ]; then
  ## Kill all ssh processes that were connecting through $OLD_IP
  for pid in $(lsof -Fp -n -i "tcp@$OLD_IP"); do
    if [ "$(ps -$pid -o comm=)" = "ssh" ]; then
      kill $pid
    fi
  done
fi

0voto

Matt Points 406

Puisque personne d'autre n'a tenté de le faire, je vais m'y essayer. Si rien d'autre, peut-être que cela incitera quelqu'un d'autre à le faire.

Je n'ai pas d'ordinateur portable ni de Gentoo à portée de main, alors peut-être qu'Ubuntu suffira. Mon ordinateur de bureau actuel est Ubuntu 10.04... vous n'avez pas mentionné votre version - j'espère qu'elle est proche.

Quoi qu'il en soit, je regarderais la configuration de Upstart (ou /etc/inittab si vous n'utilisez pas Upstart). Vérifiez que vous exécutez upstart en :

# dpkg --list | grep upstart
ii  upstart          0.6.5-7     event-based init daemon

Évidemment, si vous ne voyez pas quelque chose de similaire, vous utilisez probablement init. Les deux outils (upstart et init) sont conçus pour faire des choses au démarrage, à l'arrêt, etc (c'est-à-dire des événements).

Dans le cas de Upstart, allez dans votre répertoire /etc/init et jetez un coup d'oeil aux fichiers qui s'y trouvent. Comme je ne suis pas sur un ordinateur portable, je n'ai pas de fonction "hibernation ou suspension", mais je parie que vous en avez une. Essayez d'y faire des greps pour voir :

/etc/init# egrep -i "suspend|hibernate" *

Cependant, mon control-alt-delete.conf Le fichier me semble être quelque chose d'intéressant. Si j'y jette un coup d'oeil, je vois :

/etc/init# cat control-alt-delete.conf 
# control-alt-delete - emergency keypress handling
#
# This task is run whenever the Control-Alt-Delete key combination is
# pressed, and performs a safe reboot of the machine.

description     "emergency keypress handling"
author          "Scott James Remnant <scott@netsplit.com>"

start on control-alt-delete

task
exec shutdown -r now "Control-Alt-Delete pressed"

Je suis prêt à parier que vous pourriez personnaliser cette dernière ligne pour script quelques déconnexions SSH, ou à peu près tout ce que vous voulez. Vous devriez mettre à jour (ou créer) le fichier de configuration approprié. Je suppose qu'une installation sur ordinateur portable aura quelque chose de spécifique pour hibernate/suspend/etc. En regardant certains des autres fichiers (comme apport.conf), je vois que les fichiers de configuration supportent en fait les script intégrés à l'intérieur.

Si vous avez affaire à init, au lieu de upstart, essayez de regarder les lignes de /etc/inittab comme :

# What to do when the power fails/returns.
pf::powerwait:/etc/init.d/powerfail start
pn::powerfailnow:/etc/init.d/powerfail now
po::powerokwait:/etc/init.d/powerfail stop
...
# What to do when CTRL-ALT-DEL is pressed.
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

Une fois que vous avez localisé l'endroit idéal, basé sur votre configuration, il ne serait pas trop difficile de jeter ensemble un bash script qui pourrait les tuer ou autre.

Un exemple simple :

#!/bin/bash
kill -9 `ps -ef | grep "[s]sh " | awk '{print $2}'`

J'espère que cela vous donne au moins un point de départ. Il existe peut-être un moyen plus simple, mais je n'utilise pas assez les ordinateurs portables pour le savoir.

J'ai presque oublié : en supposant que vous fassiez tout cela, vous devrez probablement faire un rebondissement pour que cela prenne effet :

# kill -HUP 1

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