web-dev-qa-db-fra.com

Comment tuer la session SSH qui a été lancée avec l'option -f (exécutée en arrière-plan)

Je suis assez perdu là-dessus. Depuis la page de manuel:

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

Après avoir démarré SSH avec l'option -f, J'ai un tunnel qui fonctionne. Mais après avoir fini de l'utiliser, je ne sais pas comment approfondir l'interaction avec lui. Par exemple, je ne peux pas fermer le tunnel SSH quand j'en ai fini avec lui.

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

Cependant, pgrep me dit que le tunnel SSH fonctionne toujours (après avoir fermé le terminal, etc.). Comment puis-je interagir avec elle? Comment le fermer?

59
MountainX

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

La meilleure façon - Tunnels à fermeture automatique

Comme cela 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, car il suffit d'initialiser un tunnel?

C'est alors que le sommeil 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 la durée de son exécution

La manière dont ces informations aident à fermer automatiquement le tunnel ssh est expliquée ci-dessous.

Nous démarrons la session ssh en arrière-plan, tout en exécutant la commande sleep pendant 10 secondes sur la machine distante. Le nombre de secondes n'est pas crucial. En même temps, nous exécutons vncviewer exactement comme avant:

[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 est invité à bifurquer la session ssh en arrière-plan (-f), à créer le tunnel (-L 25901: 127.0.0.1: 5901) et à exécuter la commande sleep sur le serveur distant pendant 10 secondes (sleep dix).

La différence entre cette méthode et la précédente (commutateur -N) 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 sleep 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 après la période de 10 secondes, car il n'aurait plus de tâches à faire, détruisant le tunnel en même temps.

Pendant 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 à distance (exécution de sleep), il ne peut pas quitter car un autre processus occupe le tunnel. En d'autres termes, le client ssh ne peut pas détruire le tunnel car il devrait é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 exécuté en arrière-plan.

47
MountainX

Une solution particulièrement bonne pour l'écriture de 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'ID de processus et tout problème de synchronisation qui pourrait être associé à d'autres approches.

78
Brian H

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

Alternativement, vous pouvez rechercher le processus en déterminant lequel a ce port ouvert:

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

Si vous souhaitez tuer tous les clients ssh exécutés sur votre machine (en tant qu'utilisateur), pkill ssh le fera.

Comme d'autres l'ont répondu ici, pkill ssh le tue.

Pour créer un tunnel qui pourrait être ramené, je le démarre dans screen sans le -f option, puis détachez l'écran avec Ctrl-A D. Pour ramener le tunnel, appelez screen -r.

9
Haotian Yang

Quand je démarre 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.
  • -N N'exécute pas de commande à distance. Ceci est utile uniquement pour le transfert de ports.
  • -D Spécifie une redirection de port locale "dynamique" au niveau de l'application.
  • -l Spécifie l'utilisateur pour se connecter en tant que sur la machine distante.

Je peux le fermer avec:

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

J'ai trouvé une solution robuste chez SO, voir: https://stackoverflow.com/a/26470428 . Tout le mérite revient à @ghoti.

J'espère que je serai pardonné de ne pas avoir répété toute l'histoire. Il est basé sur l'option de configuration SSH ControlMaster "avancée", que vous devez mettre dans votre ~/.ssh/config fichier. Voici comment je l'ai fait pour VNC sur SSH (le VPN de mon employeur a tous les ports fermés, sauf SSH et HTTPS).

~/.ssh/config part (notez les entrées ControlMaster et ControlPath:

Host vnc
    HostName    my.desktop.internal.within.company
    User    laryx
    IdentityFile ~/.ssh/id_ecdsa
    LocalForward 5999 127.0.0.1:5900
    RequestTTY no
    ExitOnForwardFailure yes
    ControlMaster auto
    ControlPath ~/.ssh/control_sockets%r@%h:%p

Je me connecte/déconnecte avec un petit script Bash:

#!/bin/bash
if [ $# -lt 1 ]; then
    echo "This script creates an SSH tunnel to my desktop"
    echo "so that I can share its screen via VNC-over-SSH"
    echo "Usage: $0 start|stop"
    echo "Remember to start VPN first!"
    exit 1
fi

if [ $1 == "start" ]; then
    # Assuming that the VPN connection has been established
    # 1) Start the tunnel with
    ssh -f vnc -N
    # 2) check it
    ssh -O check vnc
    echo "Now share the screen by connecting to 'vnc://localhost:5999'"
    exit 0
fi

if [ $1 == "stop" ]; then
    ssh -O exit vnc
    echo "Now you may exit the VPN"
    exit 0
fi

Le tunnel est contrôlé via le ssh -O commandes.

0
Laryx Decidua