Multiplexage des connexions SSH : risques liés aux sockets de contrôle
Le multiplexage des connexions SSH peut maintenir un accès authentifié après la fin d'une tâche. Découvrez comment isoler les sockets de contrôle, fermer les sessions et préserver les preuves.

Le multiplexage des connexions SSH peut laisser ouverte une voie authentifiée vers un hôte après le retour de la commande qui l'a créée. Ce comportement est volontaire. Il est aussi facile de mal l'interpréter lorsqu'une tâche automatisée, une exécution d'agent ou un travail de déploiement est considéré comme terminé.
J'ai vu des équipes enquêter sur une fenêtre de maintenance supposée fermée et découvrir qu'un master ssh local détenait encore un transport actif, qu'un socket acceptait toujours de nouveaux clients et qu'une commande ultérieure l'avait réutilisé sans nouvelle authentification interactive. Rien d'inhabituel ne s'était produit. La configuration faisait exactement ce que la documentation d'OpenSSH décrit. L'équipe avait confondu la fin d'une commande shell avec la fin de l'accès.
La distinction utile oppose une commande client terminée à un transport authentifié arrêté. Le multiplexage sépare ces deux événements. Si vous exécutez un travail autonome sur SSH, votre nettoyage et vos preuves doivent tenir compte de cette séparation.
Un socket de contrôle peut vivre plus longtemps que la commande qui l'a ouvert
Le multiplexage SSH utilise une connexion SSH persistante, appelée master, pour transporter le travail de processus clients SSH lancés ensuite. Ces clients ultérieurs sont souvent appelés slaves dans la documentation d'OpenSSH. Lorsqu'un slave contacte correctement le master local par son socket de contrôle, il ne répète pas la configuration normale de la connexion ni l'authentification de l'utilisateur.
Une configuration typique semble anodine :
Host build-box
HostName 192.0.2.44
User deploy
ControlMaster auto
ControlPath ~/.ssh/cm/%C
ControlPersist 20m
Le premier ssh build-box crée une connexion réseau et un socket Unix dans ~/.ssh/cm/. Des commandes ultérieures comme ssh build-box 'uname -a', scp et sftp peuvent utiliser ce socket. Avec ControlPersist 20m, le master reste disponible pendant vingt minutes après la fermeture de sa dernière session.
La séquence suivante est donc normale :
- Une tâche exécute
ssh build-box 'apply-change'et se termine avec le code zéro. - Le master reste connecté, car
ControlPersistlui demande de rester disponible. - Un autre processus local exécute
ssh build-box 'read-status'dix-neuf minutes plus tard. - Ce processus ouvre un canal sur le transport déjà authentifié.
La commande ultérieure peut être autorisée par le système d'exploitation local et les permissions du socket, mais elle ne provoque pas de nouvelle authentification SSH visible par l'hôte distant. Un observateur qui ne regarde que l'enregistrement de la connexion initiale peut facilement croire que l'activité s'est terminée bien plus tôt.
OpenSSH décrit ControlMaster dans le manuel ssh_config comme permettant plusieurs sessions sur une même connexion réseau, et ControlPersist comme maintenant le master ouvert en arrière-plan. Lisez ces deux descriptions ensemble. ControlPersist n'est pas seulement un réglage de performance. Il modifie la période pendant laquelle un processus local peut demander de nouveaux canaux sur une connexion authentifiée.
Pour une personne qui travaille sur une seule machine, ce compromis peut être raisonnable. Pour une automatisation limitée à une tâche, il mérite un responsable explicite et une action d'arrêt explicite.
Un événement d'authentification n'est pas un événement de commande
Les équipes mélangent souvent authentification, connexion, canal et commande. Dans SSH, ce sont des éléments distincts, et le multiplexage rend la différence visible.
Le master initial crée une connexion TCP vers le serveur, vérifie l'hôte, négocie la cryptographie et authentifie le compte. Une fois authentifié, il peut ouvrir des canaux SSH. Une commande shell, un shell interactif, un transfert SFTP, une demande de transfert de port local ou une demande de transfert de port distant utilisent tous des canaux ou des demandes liées aux canaux sur ce transport.
Lorsqu'une nouvelle invocation locale de ssh trouve un socket de contrôle utilisable, elle envoie une demande par ce socket. Le master décide s'il doit ouvrir le canal demandé. Il n'a pas besoin de la clé privée une seconde fois. Il n'a pas besoin d'une nouvelle invite de l'agent. Le serveur n'a pas besoin de recevoir une nouvelle tentative de connexion.
Cela ne signifie pas qu'OpenSSH stocke un mot de passe réutilisable dans le socket. Cette formulation est imprécise et conduit à de mauvaises analyses. Le problème de sécurité vient d'un transport déjà authentifié doté d'une interface locale qui peut lui demander d'agir. Un attaquant capable d'utiliser le socket peut ne pas avoir besoin de l'identifiant d'origine.
Cette distinction modifie les questions à poser lors d'un incident. « La clé est-elle restée sur le disque ? » est une question importante, mais elle ne suffit pas à déterminer si l'accès est resté possible. Posez plutôt les questions suivantes :
- Un processus master est-il resté connecté à la destination distante ?
- Un autre processus local pouvait-il atteindre son socket de contrôle ?
- Le master a-t-il accepté d'autres sessions, transferts de fichiers ou demandes de transfert de port ?
- Qui pouvait s'exécuter avec l'identité du propriétaire du socket ou traverser le répertoire du socket ?
- Quand le master s'est-il réellement arrêté ?
Le code de sortie d'une commande rapporté par un exécuteur de tâches ne répond à aucune de ces questions. Il décrit seulement le processus enfant que l'exécuteur a attendu.
Les sockets partagés transforment les limites entre processus locaux en limites d'accès
Un socket de contrôle est un socket Unix local. Son emplacement dans le système de fichiers et ses permissions déterminent quels processus locaux peuvent tenter de communiquer avec le master. C'est pourquoi un ControlPath trop large peut relier des travaux indépendants, même si les alias des hôtes distants sont bien organisés.
Prenons le cas d'un compte de runner CI configuré ainsi :
Host *
ControlMaster auto
ControlPath /tmp/ssh-%r@%h:%p
ControlPersist 1h
Le job A se connecte en tant que deploy à app.internal. Il crée un master et un socket dans /tmp. Le job A se termine ensuite. Le job B, exécuté sous le même compte local, se connecte à la même cible. Il peut réutiliser le transport authentifié du job A s'il peut nommer et atteindre ce socket.
Cette configuration est populaire parce qu'elle accélère les commandes répétées avec presque aucune modification de l'application. Elle ne convient pas à des jobs indépendants, car la limite de réutilisation dépend de l'hôte, du port et de l'utilisateur, plutôt que du job qui détient l'autorisation. Un compte de runner partagé transforme cette erreur en accès croisé courant entre les tâches.
Le répertoire compte autant que le fichier socket. Sur les systèmes Unix, un processus doit disposer du droit de recherche dans le répertoire pour atteindre un chemin. Un socket stocké dans un répertoire privé, appartenant au bon compte et doté du mode 0700, offre une limite bien plus claire qu'un répertoire temporaire partagé. Les permissions propres au socket restent importantes, mais ne les considérez pas comme l'unique contrôle.
Utilisez un répertoire créé pour la tâche et appartenant au compte qui l'exécute. Un wrapper shell peut faire cela sans dépendre d'une configuration SSH globale :
set -eu
run_id="release-4821"
cm_dir="$HOME/.ssh/task-control/$run_id"
mkdir -p "$cm_dir"
chmod 700 "$cm_dir"
socket="$cm_dir/%C"
ssh -o ControlMaster=auto \
-o ControlPersist=5m \
-o ControlPath="$socket" \
build-box 'id && hostname'
Le jeton %C évite un nom littéral trop long et réduit les collisions entre ensembles de paramètres de connexion distincts. Le manuel ssh_config d'OpenSSH le définit comme un hachage calculé à partir des détails de la connexion. Il n'inclut ni votre ticket de déploiement, ni votre session d'agent, ni l'identifiant de la tâche. Dans cet exemple, le répertoire parent fournit cette limite manquante.
Ne placez pas un socket de contrôle littéral dans une copie de travail de dépôt, un espace de travail largement accessible en écriture ou /tmp simplement parce que ces emplacements sont pratiques. C'est ainsi qu'un socket local devient une capacité partagée par accident.
ControlPersist est une politique de conservation, pas un plan de nettoyage
ControlPersist demande à SSH de maintenir un master disponible après la fermeture des sessions clientes. Il accepte yes, qui le maintient indéfiniment en arrière-plan, ou une durée comme 10m. Dans les deux cas, il s'agit d'un choix de conservation.
Un délai d'expiration aide lorsqu'un client s'arrête brutalement avant le nettoyage. Il ne prouve pas que la tâche s'est terminée en même temps que l'accès. Pendant ce délai, un processus qui possède les permissions du socket peut demander un nouveau travail. Une heure est particulièrement difficile à justifier pour une tâche de déploiement qui a duré deux minutes.
Dans certains cas, un délai court est raisonnable. Un processus d'automatisation contrôlé peut exécuter plusieurs commandes successives et tirer profit d'une connexion déjà établie. Dans ce cas, choisissez un délai plus court que l'intervalle d'inactivité prévu, isolez le socket pour cette exécution et arrêtez le master lorsque le travail réussit. Le délai sert alors de solution de secours, et non de mécanisme normal de fermeture.
Le réglage ControlPersist yes doit avoir un responsable disposant d'une raison durable de conserver l'accès. Le poste interactif d'un administrateur peut en avoir une. Une tâche éphémère, non.
Une autre erreur fréquente consiste à supposer qu'un échec de commande ferme le master. Un shell peut retourner rapidement après l'échec d'une commande distante alors que le master en arrière-plan reste actif. Une annulation de tâche peut produire le même résultat. Le nettoyage doit s'exécuter après une réussite, un échec ou une interruption, et doit enregistrer si l'arrêt a fonctionné.
Si votre automatisation utilise un trap, gardez le nettoyage ciblé et vérifiez sa cible. Ne supprimez pas aveuglément le chemin du socket en premier. Supprimer le chemin peut rendre l'analyse plus difficile alors que le processus master et la connexion continuent d'exister.
cleanup() {
ssh -S "$socket" -O exit build-box >/dev/null 2>&1 || true
rmdir "$cm_dir" 2>/dev/null || true
}
trap cleanup EXIT HUP INT TERM
Ce modèle demande au master de s'arrêter avant de tenter de supprimer le répertoire. Si ssh -O exit échoue, conservez le répertoire et enquêtez plutôt que d'effacer les preuves. En production, écrivez l'échec, l'identifiant du processus et le chemin du socket dans l'enregistrement de la tâche.
exit et stop ont des significations opérationnelles différentes
OpenSSH expose des commandes de contrôle avec ssh -O. Les opérateurs utilisent régulièrement la mauvaise, car les deux noms évoquent le nettoyage.
ssh -O check host demande si un master fonctionne et indique son identifiant de processus lorsqu'il répond. ssh -O exit host demande au master de s'arrêter. Pour une tâche terminée, exit est normalement la commande voulue, car elle met fin au transport réutilisable.
ssh -O stop host demande au master de ne plus accepter de nouvelles sessions multiplexées. Les sessions existantes continuent. Cela peut être utile pour laisser finir un travail actif, mais ne permet pas d'affirmer que tout accès SSH a pris fin avec la tâche. Un master actif avec des canaux ouverts possède toujours une connexion réseau active.
Utilisez explicitement le chemin du socket lorsque le diagnostic ne doit pas dépendre de la configuration courante de l'utilisateur :
ssh -S "$socket" -O check build-box
# Master running (pid=41782)
ssh -S "$socket" -O exit build-box
# Exit request sent.
ssh -S "$socket" -O check build-box
# Control socket connect(...): No such file or directory
Les mots et le texte exact des erreurs varient selon la plateforme et la version d'OpenSSH. Capturez donc la sortie standard et la sortie d'erreur au lieu de traiter une phrase comme un contrat. La forme des preuves compte : une vérification réussie identifie un master actif, un exit réussi envoie la demande d'arrêt et une vérification ultérieure qui échoue étaye l'affirmation selon laquelle aucun socket de contrôle n'a répondu.
Un cas délicat mérite d'être pris en compte. Le socket peut rester après le crash du master, et un identifiant de processus peut disparaître entre deux vérifications. Un chemin obsolète ne prouve pas qu'un accès existe encore. Inversement, une vérification sans réponse ne prouve pas que la connexion distante a pris fin si vous avez supprimé le chemin avant l'examen. Vérifiez la table des processus et les sockets Unix ouverts avant toute suppression.
Sur macOS, lsof est souvent l'outil d'inspection local le plus rapide :
lsof -nP -U | grep '/.ssh/task-control/'
ps -p 41782 -o pid=,ppid=,lstart=,etime=,command=
Capturez la sortie dans l'enregistrement de la tâche. La première commande associe un socket Unix à un processus. La seconde fournit le processus parent, l'heure de démarrage, le temps écoulé et les détails de l'invocation. Considérez grep comme une aide interactive, pas comme un contrôle d'audit. Un véritable collecteur doit interroger et stocker directement les enregistrements pertinents.
Le transfert de port rend un master inactif plus important qu'il n'y paraît
Un master qui semble inactif peut encore transporter un état de transfert de port ou accepter une nouvelle demande de transfert. C'est pourquoi compter uniquement les commandes shell donne une image incomplète.
Le transfert local expose un écouteur local qui envoie le trafic par la connexion SSH. Le transfert distant demande au serveur d'écouter et de renvoyer les connexions par le client. Le transfert dynamique crée un proxy SOCKS. Chacun peut survivre à la commande qui l'a établi, selon la manière dont la session et le master ont été lancés.
Les manuels d'OpenSSH documentent des commandes de contrôle comme forward et cancel pour les demandes de transfert lorsque le multiplexage est actif. C'est utile en exploitation. Cela signifie aussi qu'un processus capable d'atteindre le socket peut demander des chemins réseau qui dépassent une commande shell ordinaire, sous réserve de la politique du serveur et de l'état du master.
Pour les tâches automatisées, faites du transfert une exception explicite. Enregistrez l'adresse d'écoute, le port local ou distant, l'hôte et le port de destination, ainsi que le résultat du nettoyage. Ne laissez pas un wrapper SSH générique hériter silencieusement de directives LocalForward, RemoteForward ou DynamicForward provenant d'une configuration utilisateur générale Host *.
Inspectez les réglages résolus avant de faire confiance à un alias :
ssh -G build-box | grep -E '^(controlmaster|controlpath|controlpersist|localforward|remoteforward|dynamicforward) '
ssh -G affiche la configuration effective après application des correspondances d'hôtes et des valeurs par défaut d'OpenSSH. Cette vérification détecte un problème étonnamment courant : une tâche utilise un simple alias d'hôte, mais un fichier de configuration inclus active le multiplexage ou le transfert très loin de la configuration propre à la tâche. La commande peut afficher davantage de champs selon les versions. Stockez donc toute la sortie de ssh -G, plutôt que les seules lignes attendues.
Un système distant peut enregistrer une seule connexion source alors que plusieurs connexions applicatives transférées la traversent. La télémétrie réseau, les journaux SSH du serveur et les journaux de la tâche répondent à des parties différentes de cette histoire. Aucun ne remplace les autres.
Les journaux du serveur ne peuvent pas reconstituer seuls les décisions locales
Le serveur SSH distant voit le transport et ce que sa configuration de journalisation enregistre au sujet des canaux et des commandes. Il ne peut pas déterminer de manière fiable pourquoi un processus local a reçu l'autorisation d'utiliser un socket de contrôle, quelle tâche possédait le répertoire du socket ou si un autre processus local l'a réutilisé après la fin de la tâche initiale.
Ce n'est pas un reproche envers les journaux du serveur. Ils se situent à un autre point du système. sshd peut enregistrer les événements d'authentification et de connexion. Un wrapper de commande forcée ou un sous-système d'audit peut enregistrer les commandes distantes. Ces informations restent utiles. Par défaut, elles n'identifient pas chaque client local du multiplexage, car le serveur peut voir tous les canaux comme appartenant à un seul transport déjà authentifié.
Conservez les preuves des deux côtés de la limite. Un enregistrement utile de la tâche comprend :
- la configuration client résolue complète issue de
ssh -G, sans les secrets ; - le nom d'hôte distant, l'adresse, le compte, le résultat de la vérification de l'empreinte de l'hôte et l'identifiant du processus master initial ;
- le chemin du socket de contrôle, le répertoire parent privé et les heures observées de création et de fin ;
- chaque commande distante, transfert ou opération de transfert de port demandé, avec son code de sortie ;
- le résultat de
checkavant le nettoyage, le résultat deexitet l'inspection des processus et des sockets après le nettoyage.
Ajoutez l'identifiant de la tâche au nom du répertoire et à l'enregistrement, pas à un chemin de socket global partagé par toutes les tâches. L'identifiant relie les événements locaux sans prétendre constituer à lui seul une limite de sécurité.
Hacher ou signer l'enregistrement après sa collecte aide à détecter une modification ultérieure, mais ne répare pas les événements manquants. Collectez les événements du cycle de vie au moment où ils se produisent. Un enregistrement reconstitué à partir de l'historique shell après un incident constitue une preuve faible, en particulier lorsque des masters en arrière-plan et des tentatives répétées interviennent.
Pour un travail piloté par un agent, distinguez l'intention de l'agent de l'action SSH exécutée. « Déployer la version X » est une intention. ssh build-box 'sudo systemctl restart api' est une action. L'enregistrement de la réutilisation du socket indique si cette action a obtenu un nouveau transport ou utilisé un transport existant. Ce sont deux faits d'audit différents.
Les sockets propres à une tâche donnent un responsable au nettoyage
Pour un travail automatisé de courte durée, le modèle le plus sûr est simple : utilisez un répertoire de socket de contrôle unique pour chaque tâche, autorisez la réutilisation uniquement dans cette tâche et envoyez une demande exit explicite avant de signaler que la tâche est terminée.
Un wrapper pratique a besoin d'un cycle de vie clair. Il doit créer le répertoire avec des permissions restrictives, écrire un enregistrement avant la première connexion, exécuter les commandes avec le même ControlPath explicite, arrêter le master, vérifier le résultat et ne supprimer le répertoire vide qu'ensuite. Une tâche qui ne peut pas vérifier le nettoyage doit signaler un échec du nettoyage même si la commande distante a réussi.
Cet exemple utilise mktemp pour éviter de deviner un nom de répertoire unique :
set -eu
base="$HOME/.ssh/task-control"
mkdir -p "$base"
chmod 700 "$base"
cm_dir=$(mktemp -d "$base/run.XXXXXX")
chmod 700 "$cm_dir"
socket="$cm_dir/%C"
finish() {
status=$?
ssh -S "$socket" -O exit build-box >>"$cm_dir/cleanup.log" 2>&1 || \
printf '%s\n' 'master exit request failed' >>"$cm_dir/cleanup.log"
ssh -S "$socket" -O check build-box >>"$cm_dir/cleanup.log" 2>&1 || true
exit "$status"
}
trap finish EXIT HUP INT TERM
ssh -o ControlMaster=auto \
-o ControlPersist=2m \
-o ControlPath="$socket" \
build-box 'deployctl apply release-4821'
La valeur courte de ControlPersist couvre le cas où un processus meurt avant l'exécution de son trap. Elle ne doit pas être interprétée comme une autorisation pour une autre tâche de réutiliser le master. Le répertoire aléatoire empêche cette réutilisation, car la deuxième tâche ne connaît pas le chemin de la première et ne l'hérite pas.
Une correction s'impose avant d'adopter cet exemple tel quel. Ne consignez pas dans cleanup.log les arguments sensibles des commandes, les valeurs d'environnement ou des données privées copiées. Les enregistrements d'audit doivent fournir assez de détails pour établir qui a fait quoi, sans devenir un nouveau coffre à secrets. Masquez les arguments à la frontière du wrapper, lorsqu'il est encore possible d'en comprendre le sens.
Sallyport fait passer les actions SSH par son utilitaire sans état intégré sp-ssh, tout en conservant les clés SSH dans son coffre chiffré au lieu de les exposer à l'agent. Cela élimine une cause fréquente de mauvaise gestion des identifiants, mais les équipes doivent tout de même définir la limite de l'action et conserver des enregistrements indiquant quand l'exécution s'est terminée.
Les réglages pratiques globaux contournent les limites des tâches
Une section globale Host * active souvent le multiplexage pour chaque shell humain, script, dépôt et processus enfant d'automatisation exécuté sous un compte. C'est trop large lorsque le même compte exécute des tâches soumises à des autorisations ou à des responsables différents.
Le réglage peut provenir de fichiers Include, d'un outil de gestion de configuration, des fichiers personnels d'un développeur ou d'une image de build. La ligne de commande peut aussi le remplacer. Ne déduisez jamais le comportement actif à partir d'un seul fichier de configuration visible. Utilisez ssh -G avec l'alias d'hôte exact et le contexte utilisateur que la tâche utilisera.
Si un environnement d'automatisation ne peut pas garantir un chemin de contrôle privé, désactivez le multiplexage pour cette action :
ssh -o ControlMaster=no \
-o ControlPath=none \
build-box 'maintenancectl status'
Cela impose une nouvelle connexion et une nouvelle authentification à chaque invocation. C'est un coût raisonnable pour les actions à conséquences importantes, les accès d'urgence rares ou les travaux qui franchissent des limites de tâche et de confiance. La répétition de l'authentification fournit un événement d'autorisation plus clair et rend le raisonnement sur le cycle de vie beaucoup moins ambigu.
Ne confondez pas ControlMaster=auto avec la garantie qu'un processus ne réutilisera que sa propre connexion. auto signifie que le client essaiera de trouver un master au chemin configuré et en créera un s'il n'en trouve pas. Le chemin configuré détermine quelle connexion il peut trouver.
Certaines équipes estiment qu'un socket partagé ne pose aucun problème, car tous leurs jobs s'exécutent sous un même compte de service. Cet argument ne tient que si chaque job utilisant cette identité Unix possède la même autorité pour atteindre chaque cible avec ce compte, et si l'équipe accepte qu'un job puisse hériter du transport actif d'un autre. Dans la plupart des environnements matures, ce n'est pas réellement souhaité.
Une fin de tâche propre doit prouver la fermeture du transport
Ne déclarez pas une tâche SSH terminée lorsque la dernière commande distante retourne. Déclarez-la terminée lorsque la tâche a soit fermé son master et enregistré les preuves, soit signalé qu'elle n'a pas pu le faire.
L'enregistrement final doit indiquer à l'enquêteur si une commande ultérieure pouvait encore réutiliser la connexion. Il lui faut l'identité de la tâche, la configuration SSH résolue, le chemin du socket, les détails du processus master, les enregistrements d'activité, les résultats explicites des commandes de contrôle et l'observation effectuée après le nettoyage. Il lui faut aussi les preuves distantes des changements qui se poursuivent indépendamment de SSH, comme le redémarrage d'un service ou un processus détaché.
Établissez une procédure que les opérateurs peuvent appliquer sous pression : isolez le socket, inspectez-le avant le nettoyage, demandez exit, vérifiez qu'aucun master ne répond et conservez le résultat. Cette procédure est plus utile qu'un long délai par défaut, car elle transforme une supposition sur l'accès en un fait vérifiable.
Lorsque le risque lié à un transport authentifié restant ouvert est trop élevé, n'optimisez pas l'opération avec un master partagé. Ouvrez une nouvelle connexion, exécutez l'action, fermez-la et conservez l'enregistrement. Les quelques secondes supplémentaires coûtent moins cher que d'avoir à expliquer pourquoi une voie d'accès a survécu alors que la tâche était censée être terminée.
FAQ
ControlMaster peut-il maintenir une connexion authentifiée après la fin de ma commande ?
Oui. Une connexion ControlMaster s'authentifie une fois, puis les clients SSH suivants peuvent demander au master local d'ouvrir de nouveaux canaux. Si ControlPersist maintient le master en vie, ces canaux peuvent être ouverts après la fin de la commande initiale et de la tâche qui l'a lancée.
Quelle est la différence entre une connexion SSH master et slave ?
Le processus master est la connexion SSH initiale qui possède le transport réseau et le socket de contrôle local. Un processus slave est une commande ssh lancée ensuite, qui contacte ce socket et demande au master d'ouvrir une session, un transfert ou un autre canal.
Comment fermer correctement un socket de contrôle SSH partagé ?
Utilisez ssh -O exit host-alias lorsque votre configuration associe l'alias à la ControlPath voulue. Si vous devez désigner directement le socket, utilisez ssh -S /path/to/socket -O exit host. Vérifiez d'abord avec -O check pour éviter d'arrêter la mauvaise connexion.
Le multiplexage SSH est-il sûr pour l'automatisation ?
Cela réduit les authentifications répétées et accélère de nombreuses commandes SSH courtes. Le multiplexage devient dangereux quand personne ne gère sa durée de vie, quand plusieurs tâches indépendantes partagent un même répertoire de sockets ou quand une tâche peut continuer à ouvrir des canaux après l'expiration de l'autorisation.
Les journaux du serveur SSH montrent-ils toutes les commandes envoyées par multiplexage ?
Le serveur SSH distant enregistre souvent une seule connexion de transport et peut ne pas identifier chaque commande locale ultérieure comme un nouvel événement d'authentification. Si vous avez besoin d'un compte rendu fiable, collectez les informations sur les processus clients, la configuration du multiplexage, le cycle de vie du socket de contrôle et les journaux de commandes de la tâche.
Dois-je compter sur le délai de ControlPersist pour nettoyer SSH ?
Un délai d'expiration constitue une limite supérieure, pas la preuve que la connexion s'est terminée avec la tâche. Utilisez ssh -O exit lors du nettoyage, puis vérifiez que le socket a disparu et que ssh -O check échoue. Le délai reste un filet de sécurité utile lorsque les clients se terminent brutalement.
Où stocker les sockets de contrôle SSH ?
Traitez les sockets de contrôle comme des identifiants locaux. Placez-les dans un répertoire privé appartenant au compte qui exécute la tâche, utilisez un chemin propre à chaque tâche, évitez les répertoires temporaires partagés et ne supprimez les anciens chemins qu'après avoir vérifié qu'aucun processus master ne les possède encore.
Que signifie %C dans SSH ControlPath ?
ControlPath définit le chemin du socket Unix. %C devient un hachage dérivé des attributs de la connexion et évite de nombreux problèmes de longueur et de collision de noms. Il ne crée toutefois pas à lui seul une identité distincte pour chaque tâche.
La fermeture du master SSH annule-t-elle le travail déjà lancé sur l'hôte distant ?
Non. Fermer un transport multiplexé met fin à cette connexion authentifiée côté client, mais cela n'annule pas les fichiers modifiés à distance, n'arrête pas un processus distant détaché et ne révoque pas les identifiants qu'une autre session peut encore utiliser. Le travail distant doit faire l'objet d'un nettoyage séparé.
Quelles preuves conserver après la fin d'une tâche SSH automatisée ?
Commencez par un relevé reproductible : configuration SSH entièrement résolue, identifiant du processus master, chemin du socket, destination distante, heures de début et de fin, ainsi que résultat d'une commande d'arrêt explicite. Conservez ce relevé avec la transcription des commandes de la tâche et les journaux pertinents de l'hôte distant.