Comment tuer une session SSH démarrée avec l'option -f (exécutée en arrière-plan)

50

Je suis assez perdu à ce sujet. De la page de manuel:

 -f      Requests ssh to go to background just before command execution.

Après avoir démarré SSH avec l' -foption, j'ai un tunnel fonctionnel. Mais une fois que j'ai fini de l'utiliser, je ne sais pas comment continuer à interagir avec elle. Par exemple, je ne peux pas fermer le tunnel SSH lorsque je termine.

Les méthodes habituelles que je connais ne fonctionnent pas. Par exemple, jobsne renvoie rien. La ~commande n'est pas reconnue (et je ne sais pas exactement comment l'utiliser, de toute façon).

Cependant, il pgrepme dit que le tunnel SSH est toujours en cours d'exécution (après la fermeture du terminal, etc.). Comment interagir avec? Comment puis-je le fermer?

MountainX
la source

Réponses:

65

Une solution particulièrement intéressante pour les scripts consiste à utiliser master mode, avec un socket pour les commandes de contrôle:

ssh -f -N -M -S <path-to-socket> -L <port>:<host>:<port> <server>

Pour le refermer:

ssh -S <path-to-socket> -O exit <server>

Cela évite à la fois la recherche d’identificateurs de processus et les problèmes de minutage pouvant être associés à d’autres approches.

Brian H
la source
10
Juste pour développer un peu pour les non initiés, le <chemin d'accès au socket> est un chemin d'accès à un fichier que l'instance principale du client ssh créera pour la communication interprocessus avec d'autres instances de clients ssh souhaitant partager la connexion de l'instance principale. Le fichier créé représentera en réalité un socket de domaine Unix. Il peut être nommé et situé où bon vous semble, par exemple /tmp/session1(bien qu'il soit recommandé de le nommer à l'aide de % patterns - voir la description de ControlPath dans man ssh_config)
golem
1
De plus, il semble que la partie <serveur> de la ssh -S <path-to-socket> -O exit <server>commande puisse être n'importe quelle chaîne, mais elle doit être présente. C'est un peu maladroit.
Golem
1
Cette réponse et cette question sont un peu anciennes, mais je voulais souscrire à cette approche, qui est probablement la manière la plus élégante et «correcte» de traiter ce problème que j'ai vue. Merci Monsieur!
zentechinc
41

J'ai trouvé la solution ici: http://www.g-loaded.eu/2006/11/24/auto-closing-ssh-tunnels/

Le meilleur moyen - Tunnels à fermeture automatique

Comme il a été mentionné précédemment, au lieu d'utiliser la combinaison de commutateurs -f -N, nous pouvons simplement utiliser -f seul, mais également exécuter une commande sur la machine distante. Mais quelle commande doit être exécutée, puisqu'il suffit d'initialiser un tunnel?

C'est à ce moment que dormir peut être la commande la plus utile de toutes! Dans cette situation particulière, le sommeil présente deux avantages:

  • il ne fait rien, donc aucune ressource n'est consommée
  • l'utilisateur peut spécifier pendant combien de temps il sera exécuté

Comment cela aide à la fermeture automatique du tunnel SSH est expliqué ci-dessous.

Nous commençons la session SSH en arrière-plan, tout en exécutant la commande de veille pendant 10 secondes sur la machine distante. Le nombre de secondes n'est pas crucial. Dans le même temps, nous exécutons vncviewer exactement comme auparavant:

[me@local]$ ssh -f -L 25901:127.0.0.1:5901 [email protected] sleep 10; \
          vncviewer 127.0.0.1:25901:1

Dans ce cas, le client ssh doit charger la session ssh en arrière-plan (-f), créer le tunnel (-L 25901: 127.0.0.1: 5901) et exécuter la commande de veille sur le serveur distant pendant 10 secondes (veille). dix).

La différence entre cette méthode et la précédente (-N switch) est que, dans ce cas, l'objectif principal du client ssh n'est pas de créer le tunnel, mais plutôt d'exécuter la commande de veille pendant 10 secondes. La création du tunnel est une sorte d'effet secondaire, un objectif secondaire. Si vncviewer n'était pas utilisé, le client ssh se fermerait au bout de la période de 10 secondes, car il n'aurait plus de travail à faire, détruisant le tunnel en même temps.

Lors de l'exécution de la commande sleep, si un autre processus, vncviewer dans ce cas, commence à utiliser ce tunnel et le maintient occupé au-delà de la période de 10 secondes, alors, même si le client ssh termine son travail distant (exécution de sommeil), il ne peut pas sortir car un autre processus occupe le tunnel. En d'autres termes, le client ssh ne peut pas détruire le tunnel car il devra également tuer vncviewer. Lorsque vncviewer cesse d'utiliser le tunnel, le client ssh se ferme également car il a déjà atteint son objectif.

De cette façon, aucun processus ssh n'est laissé en arrière-plan.

MountainX
la source
4
Une petite remarque / correction: Autant que je sache, vous devez spécifier vncviewer 127.0.0.1::25091car vous utilisez la syntaxe du port et non la syntaxe d'affichage.
Christian Wolf
C’est une excellente idée et juxtapose un problème que j’avais sous Windows. Les versions récentes de Windows sont livrées avec un client ssh, qui prend en charge l’option -S en théorie, mais ne semble tout simplement pas fonctionner pour moi.
Keeely le
9

Pour supprimer le tunnel, utilisez ps -C sshou ps | grep sshou toute autre variante pour déterminer quel processus ssh exécute votre tunnel. Alors tuez-le.

Vous pouvez également rechercher le processus en déterminant celui qui a ce port ouvert:

netstat -lnpt | awk '$4 ~ /:1234$/ {sub(/\/.*/, "", $7); print $7}'

Si vous voulez tuer tous les clients ssh en cours d'exécution sur votre machine (en tant qu'utilisateur), vous pkill sshle ferez.

Gilles, arrête de faire le mal
la source
6

Comme l'ont répondu d'autres personnes ici, le pkill sshtue.

Pour créer un tunnel pouvant être ramené, je le lance screensans l' -foption, puis détache l'écran avec Ctrl-A D. Pour ramener le tunnel, appelez screen -r.

Haotian Yang
la source
Force brute, mais efficace
mafrose
1
Faites attention si vous vous connectez à distance. pkill ssh va même tuer votre connexion actuelle.
kennyut
@Kennyut Encore une autre raison d'utiliser screen.
Haotian Yang
0

Quand je commence un tunnel avec:

ssh -fN -D 8080 SOME_IP_HERE -l LOGIN_NAME_HERE
  • -f Demande à ssh de passer en arrière-plan juste avant l'exécution de la commande.
  • -NN'exécutez pas de commande à distance. Ceci est utile pour simplement transférer des ports.
  • -D Spécifie une redirection de port "dynamique" au niveau de l'application locale.
  • -l Spécifie l'utilisateur à connecter en tant que sur la machine distante.

Je peux le fermer avec:

ps -lef | grep ssh | grep "8080" | awk "{print \$2}" | xargs kill
numediaweb
la source
-1

La meilleure solution que j'ai trouvée pour tuer tous les tunnels en une seule ligne de commande est

ps -lef|grep ssh|grep "\-L"|awk '{print $4}'|xargs kill

pour les sessions ssh, il suffit de supprimer l'option tunnel

ps -lef|grep ssh|awk '{print $4}'|xargs kill

Philippe Gachoud
la source