Patrice Ferlet
Patrice Ferlet
Créateur de ce blog.
Publié le mai 30, 2015 Temps de lecture: 6 min

Me suivre sur Mastodon

OpenSSH et les socket de contrôle

Garder une connexion SSH active en arrière plan et pouvoir la stopper quand on veut, sans garder son PID, quelle idée merveilleuse hein ? Personnellement j’en avais besoin. Autre possibilité, se connecter une fois à un serveur et ne pas avoir à se reloguer à chaque fois que je veux retourner sur le serveur, pareil ce serait bien. Et bien c’est possible. Suffisait de lire la doc en fait. Voilà un petit billet qui va vous parler de tout ça.

Clairement j’avais besoin de lancer un tunnel SSH et le garder ouvert un certain temps, puis le couper à la volée. Et ce sans avoir un terminal ouvert dans un coin. Oui vous allez me dire “l’option -f de ssh sert à mettre en background la connexion”, mais pour fermer la connexion il faut alors passer par “ps” pour trouver le PID, et se débrouiller par des moyens détournés. Je me doutais bien que OpenSSH proposait quelque chose pour ça, et j’ai visé juste.

Il suffit de chercher sur le net des articles et documentations parlant de “multiplexed ssh connections” par exemple pour trouver son bonheur.

La page qui m’a été super utile est OpenSSH/Cookbook/Multiplexing - mais la “manpage” a aussi pas mal d’infos.

Comment ça marche ?

L’idée est qu’en se connectant à un serveur SSH, un fichier “socket unix local” soit créé. Ce socket permet de faire pas mal de choses:

  • se reconnecter au serveur dans une autre session sans avoir à recréer l’appel complet (donc pas de mot de passe demandé)
  • pouvoir couper toutes les connexions au serveur (si elles utilisent ce socket)
  • pouvoir vérifier si des connexions sont actives
  • et j’en passe

Il y a deux façon (au moins, à ma connaissance) pour paramétrer cette fameuse création de socket:

  • soit dans la ligne de commande
  • soit dans la config ssh

Il faut aussi prendre en compte qu’une connexion sera considérée comme “maitresse” (master) et que si celle-ci est coupée alors les autres connexions “esclaves” vont se couper, par défaut. On peut tout à fait éviter cette coupure des esclaves en manipulant un peu les options. On va en parler, n’ayez pas peur.

Voyons comment ça se passe.

Explication avec la ligne de commande

Créons une connexion à serveur en la spécifiant comme “maitresse” (via l’iption -M). L’option -S spécifie le chemin du socket unix.

$ ssh -M -S /tmp/test.ssh.sock user@server.tld

Normalement votre connexion fonctionne et un fichier /tmp/test.ssh.sock vient d’apparaitre. Dans un autre terminal, sans couper cette connexion, vous allez pouvoir vous reconnecter au même serveur en utilisant cette socket unix et sans demande de mot de passe. Cette fois on ne demande pas à devenir “maitre”, donc on supprime l’option -M:

$ ssh -S /tmp/test.ssh.sock user@server.tld

Alors faites cette expérience; retourner sur le premier terminal et coupez la connexion en tapant “exit”. Ce terminal reste bloqué, et pour cause ! Cette connexion est “maitre”, elle attend la coupure des autres esclaves. Donc allez dans le second terminal où vous avez lancé une seconde connexion SSH et faites pareil: “exit”. Là, enfin, les deux connexions sont coupées.

Les commandes de socket

Cette socket unix ne sert pas seulement à multiplexer les connexions. On peut y passer des commandes.

Recommençons l’expérience précédente:

  • un terminal avec ssh -M -S /tmp/test.ssh.sock user@server.tld
  • un second terminal avec ssh -S /tmp/test.ssh.sock user@server.tld

Ouvrons un troisième terminal et tapons:

$ ssh -S /tmp/test.ssh.sock user@server.tld -O check
Master running (pid=5764)

Intéressant - nous pouvons savoir le PID du processus maitre. C’est le PID de la commande ssh qui utilise l’option -M. Mais ce n’est pas tout, on sait qu’elle est active !

Le prototype de l’appel est simplement: ssh -S chemin_socket -O commande user@server.ssh

L’option -O (la lettre “O”) permet de passer des commandes de contrôle. Ici on utilise “check” mais on peut aussi utiliser:

  • stop - qui dit au socket de ne plus prendre d’autres connexions et de se couper après fermeture des maitres et esclaves - la socket disparait quand aucune connexion n’est présente (c’est le mode soft)
  • exit - qui demande à couper toutes les connexions en cours sur ce socket (donc coupe les connexion ssh au serveur, c’est le mode “bourinasse”)

Ainsi, tapez:

$ ssh -S /tmp/test.ssh.sock user@server.tld -O exit

Regardez les deux autres terminaux, la connexion SSH est coupée, maitre et esclave compris !

C’est donc super pratique, par exemple pour lancer un tunnel SSH qu’on peut stopper quand on veut:

$ ssh -M -S /tmp/tunnel.sock -N -L :8889:localhost:10085 root@server.tld 

Et pour le couper, plus tard:

$ ssh -S /tmp/tunnel.sock -O exit root@server.tld 

Utiliser la conf

C’est bien sympa de mettre des options en ligne de commande, mais peut-on configurer SSH pour qu’il fasse ça tout seul ? La réponse est “oui” (sinon j’aurais pas fait cette section hein).

Ouvrons notre fichier ~/.ssh/config et paramétrons un service:

Host server.tld
	ControlPath /tmp/%r@%h:%p
	ControlMaster auto

Voilà, la prochaine connexion au serveur “server.tld” va créer un socket /tmp/user@host:port (en remplacant user, host et port par les valeurs qui vont bien).

Une nouvelle connexion au serveur, alors que l’autre est active, va fonctionner comme précédemment, et comme d’habitude vous pourrez utiliser l’option -O pour passer des commandes de contrôle.

Une autre option super intéressante est “ControlPersist” qui, si elle vaut “yes”, va laisser la socket même si aucun maitre n’est présent.

Host server.tld
	ControlPath /tmp/%r@%h:%p
	ControlMaster auto
	ControlPersist yes

C’est plutôt sympa et ça permet de vraiment accélérer les nouvelles connexions au serveur. Si vous désirez forcer la fermeture de ce socket c’est simple:

$ ssh user@server.tld -O stop

Aucune connexion ne sera acceptée, et quand tous les esclaves auront quitté, la socket sera supprimée.

Plutôt que de mettre yes, vous pouvez aussi donner une valeur de temps: 10m pour 10 minutes, 1h pour une heure… la socket va donc persister le temps donné si aucune connexion maitresse n’est en cours. C’est un chouillat plus sécurisé.

Utilité

On parle de pouvoir contrôller des connexions à un serveur. Si vous sauvez une configuration dans /etc/ssh/ssh_config alors toutes les connexions de n’importe quel user sur le poste seront accélérées et contrôllables, donc par exemple vous pourrez fermer toutes les connexions à un serveur en particulier simplement en utilisant le socket adéquat.

L’autre utilité est clairement la possibilité de créer des tunnels et de les couper rapidement sans passer par la case “ps”, trouver le pid etc. Une commande “exit” dans le socket et le tour est joué.

Il y a bien d’autres options et utilités, je vous laisse regarder la page que j’ai donné en haut de l’article.

Bref, encore une option OpenSSH que je suis content d’avoir découvert. Entre le tunnelling, la création de pseudo VPN, les sockets de contrôle et tous les outils qui suivent, y’a pas, SSH c’est le pied.

comments powered by Disqus