Skip to content

Linux Attitude

Le libre est un état d'esprit

Archive

Tag: Ssh

Niveau : Star Star Empty Empty Empty
Résumé :

Aujourd'hui nous allons mettre en valeur deux articles précédents. J'espère que vous avez déjà mis votre home sous un système de suivi de version pour suivre ses évolutions. J'ai déjà décrit à dans un article précédent. En résumé :

$ cd
$ git init
$ git add .bashrc # et tout ce que vous voulez
$ git commit

Le but étant de propager tout cela automatiquement sur différentes machines. Il est difficile de toujours penser à mettre a jour lorsqu'on fait une modification. C'est pourquoi nous allons mettre à profit l'article précédent et intercepter ssh. Grâce à cela le home de toutes nos machines seront à jour sans qu'on ait à s'en préoccuper.

Mise en place

Cette fois nous allons modifier le script en question pour lancer automatiquement une mise à jour de git de façon furtive à chaque connexion ssh. La méthode run était prévue pour :

# test permettant de savoir qu'on est bien sur le bon dépôt git pour les mises à jour (id du premier commit)
MASTER=11edf02e95ceac1fa58d4444f82f8cd4ae9c1cf5
# command tu run via the ssh socket
run()
{
    # no test if running init
    if [ "$MASTER" != "" ]
    then
        # test if distant has OUR git
        ssh -S "$1" XXX '[ -e /usr/bin/git ] && [ -d .git ] && git rev-list --reverse master 2>/dev/null | head -1' | grep "$MASTER" > /dev/null
    else
        ssh -S "$1" XXX '[ -e /usr/bin/git ]'
    fi
    if [ $? -eq 0 ]
    then
        # if yes push updates
        tmp=$(mktemp ~/.sshgit.XXXXXX)
        echo "#!/bin/sh" > $tmp
        echo "exec ssh -S $1 \"\$@\"" >> $tmp
        chmod +x $tmp
        GIT_SSH=$tmp git push --all ssh://XXX/~ > /dev/null 2> /dev/null
        rm -f $tmp
        ssh -S "$1" XXX 'git checkout -f > /dev/null'
    fi
}

De plus j'ai ajouté un paramètre spécial permettant d'initialiser le dépôt de la machine en face. En effet, on ne va pas forcer la mise à jour si le home en face n'a pas de dépôt, il se peut que l'utilisateur ne le veuille pas. C'est aussi pour ce qu'on vérifie que le dépôt git utilisé contient bien le bon commit initial.

            ssh -S "$2" XXX '[ -e /usr/bin/git ] && [ ! -d .git ] && git init > /dev/null'

Le script complet.

Usage

Pour que ça fonctionne on ajoute un alias et tant qu'à faire, on ajoute le script au dépôt :

$ alias ssh='~/.sshgit' # à mettre aussi dans le .bashrc
$ git add .sshgit
$ git commit

Et maintenant on initialise la machine en face :

$ ssh -= autremachine.net

Et voila, tout ssh ultérieur résultera en un git push suivi d'un git checkout, plus besoin de réfléchir. Ce qui veut dire qu'au fur et à mesure de vos ssh votre home se propagera un peu partout, que le réseau où vous êtes soit privé ou non car c'est la connexion normale du ssh qui est empruntée. Reste juste à faire un ssh de temps en temps un peu partout pour mettre à jour :-)

Autre

Si vous n'avez pas git sur toutes les machines, vous pouvez aussi utiliser autre chose pour synchroniser automatiquement vos home. rsync par exemple (regardez l'option -u pour les mises à jour) ou scp.

Mais pour le coup je vous laisse écrire la méthode :)

Niveau : Star Star Star Star Empty
Résumé :alias ssh='ssh macommande && ssh'

Aujourd'hui interceptons les commandes ssh. Alors ne commencez pas à penser que je suis passé du côté obscur de la force. Il y a des usage bien pratique ce script et je vous en proposerai un dans le prochain article.

Tout d'abord le problème : on veut pouvoir intercepter une commande ssh de façon silencieuse pour pouvoir utiliser la connexion qui va s'établir et lancer les commandes qu'on veut sur la machine distante. Cela implique une acceptation implicite de l'utilisateur puisqu'on va utiliser un simple alias pour "intercepter" la commande. Bien sûr rien ne vous empêche de modifier l'alias d'un ami selon les moyens qui sont à votre disposition ;-)

Principe de fonctionnement

Vous vous dites qu'il suffit de reprendre les paramètres de la commande et de la relancer. Non, habitués que vous êtes à l'agent ssh, vous avez oublié qu'en son absence l'utilisateur devra taper un mot de passe pour que la commande passe.

Pour récupérer la connexion ssh, openssh met à notre disposition tout ce qu'il faut. L'option s'appelle ControlMaster, elle crée une socket sur laquelle ssh peut ensuite se connecter pour ouvrir un nouveau terminal sans repasser toute la chaine de connexion au serveur.

La méthode est donc fait simple :

  • on intercepte la commande ssh (alias)
  • on lance notre script en background ($0 &)
  • on ajoute un option -M et -S si besoin à la commande ssh pour créer la socket
  • on garde les options originales et le processus original (exec ssh -M -S "$@")
  • dans le script en background on peut ensuite utiliser directement la socket en question pour faire ce qu'on veut

Résultat

Donc résumons : un alias

alias ssh='~/.sshalias'

Et un script nommé ~/.sshalias (commentaires en anglais par habitude). Modifiez la commande run pour metre ce que vous voulez dedans

#!/bin/sh

# GPLv2 
# author : peck

#  command tu run via the ssh socket
run()
{
        # example ssh command
        ssh -S "$1" XXX 'hostname'
}

# test if we are the child which can connect via the master
if [ "$1" == "-=0" ]
then
    go=0
    # limit to 60 retries x 1s
    for i in $(seq 1 60)
    do
        sleep 1
        # try to connect via master
        ssh -S "$2" -O check xxx 2>/dev/null
        if [ $? -eq 0 ]
        then
            go=1
            break
        fi
    done
    # run the stealth command
    if [ $go -eq 1 ]
    then
        sleep 1 # bug if we go too fast
        run "$2"
    fi
    # remove master socket if we created it
    if [ "$3" == "0" ]
    then
        rm -f "$2"
    fi
    exit 0
fi

# we are in a real ssh command
master=0
sock=""
for i in "$@"
do
    # test if master is already provided
    if [ "$i" == "-M" ]
    then
        master=1
    fi
    # retrieve socket if provided
    if [ "$i" == "-S" ]
    then
        sock=".";
    fi
    if [ "$i" == "." ]
    then
        sock="$i"
    fi
done

# create socket name if needed
if [ "$sock" == "" ]
then
    sock=$(mktemp -u -t sshx.XXXXXX)
fi

# launch child which will use our master socket
$0 -=0 "$sock" "$master" &

# run original command adding a master socket
if [ $master -eq 1 ]
then
    exec ssh "$@"
else
    exec ssh -S "$sock" -M "$@"
fi

Niveau : Star Star Star Star Empty
Résumé : SSH et certificats x509

Vous avez une ferme de serveurs ? Vous avez une ferme d'utilisateurs ? Vous avez déjà une infrastructure de gestion de clés pour des certificats x509 (ssl) ?

Si vous répondez oui à deux de ces points alors cet article va vous intéresser.

Sachez qu'il est possible d'utiliser des certificats x509 avec ssh. Quel intérêt ? Tout simplement vous pouvez réutiliser votre PKI si vous en avez déjà une en x509. Ensuite les certificats fonctionnent par un système de signature hiérarchisée, donc il n'est plus nécessaire de mettre en place un système de distribution des clés des utilisateurs sur les machines. Et inversement, les utilisateurs n'auront plus à se reposer sur leur pifomètre pour accepter les clés des serveurs à leur première connexion.

Maintenant qu'on sait qu'on va pouvoir vendre de la sécurité à notre boss tout en évitant de se farcir des systèmes de synchronisation, on va pouvoir se lancer dans les choses sérieuses.

Compilation

Tout d'abord il nous faut une version de ssh qui supporte ce mode de fonctionnement. On la trouvez chez un certain Roumen Petrov. Bon, petite déception, il ne fournit que des patchs. A nous d'en faire un vrai ssh compilé. Pour une fois, ça va être une peu plus difficile pour les debianistes. Pour ceux qui recompilent leur ssh directement :

# à adapter à vos besoins et à votre version
$ wget http://www.roumenpetrov.info/openssh/x509-6.1.1/openssh-5.1p1+x509-6.1.1.diff.gz
$ cd openssh-source
$ zcat ../openssh-5.1p1+x509-6.1.1.diff.gz | patch -p1
$ ./configure
$ make
$ make install

Pour ceux qui sont sur debian, il serait quand même plus sympa de se refaire un paquet. Le problème est que le patch de Roumen Petrov s'applique mal sur des sources debian. Il y a donc 3 rejets à appliquer avant de pouvoir lancer la compilation :

# récupération des sources debian
$ apt-get source openssh
# récupération du patch
$ wget http://www.roumenpetrov.info/openssh/x509-6.1.1/openssh-5.1p1+x509-6.1.1.diff.gz
$ cd openssh-5.1p1
$ zcat ../openssh-5.1p1+x509-6.1.1.diff.gz | patch -p1

# ICI relisez les fichiers .rej et appliquez à la main, c'est assez simple

# recompilation
$ dpkg-buildpackage -rfakeroot -b
# installation
$ cd ..
$ su
$ dpkg -i openssh-client*.deb openssh-server*.deb

Pour ceux qui sont toujours en etch vous pouvez soit upgrader ssh en récupérant le paquet source de lenny soit utiliser la version etch avec une version plus ancienne du patch.

Pour la méthode upgrade avec etch, modifiez le fichier debian/control qui se trouve dans le répertoire source ssh et supprimez les versions de libssl et lsb-base indiquées dans les dépendances avant de compiler. Cela marche très bien.

Pour ceux qui voudraient rester en ssh4.1, appliquez le patch de Roumen Petrov et forcez l'application du patch avec les erreurs. Ensuite listez les fichier .rej (ils sont tous à la racine) et appliquez les à la main (retrouver la bonne ligne, ajouter ...). C'est un peu plus long.

Utilisation

Ça y est le nouveau ssh est installé sur le serveur et sur le client. Maintenant utilisons un certificat pour se connecter au serveur et prouver que ça marche.

Tout d'abord il nous faut une autorité de certification, c'est à dire un certificat qui a le droit de signer d'autres certificats et que nous installerons partout (l'article explique comment la créer et l'utiliser). Avec cette autorité, il faut générer deux paires de clés : une paire pour le serveur, une paire pour le client. Rien n'oblige à avoir la même autorité pour les deux, mais cela simplifie les exemples, c'est donc ce que je vais faire.

On a donc :

  • ca.crt : le certificat de l'autorité
  • server.crt et server.key : le certificat et la clé à utiliser sur le serveur ssh
  • client.crt et client.key : le certificat et la clé à utiliser sur le client ssh

Authentification du serveur

Commençons par configurer l'authentification du serveur par le client. Le client sera sûr que le serveur est reconnue par une autorité.

Côté serveur

Installons le certificat sur le serveur ssh. On place la clé dans un nouveau fichier pour le serveur :

$ cat server.key server.crt > /etc/ssh/ssh_host_x509_key
$ chmod 600 /etc/ssh/ssh_host_x509_key
# mise à jour de la clé publique pour la forme
$ ssh-keygen -y -f /etc/ssh/ssh_host_x509_key > /etc/ssh/ssh_host_x509_key.pub

Et on ajoute cette clé à celle que le serveur envoie au client pour authentification en ajoutant une ligne/etc/ssh/sshd_config :

HostKey /etc/ssh/ssh_host_x509_key

Vous pouvez même commenter les anciennes lignes HostKey si vous voulez forcer l'utilisation de x509, mais je ne pense pas que ce soit judicieux (par contre ça permet d'être sur de ce qu'on teste). Et hop on relance le serveur.

# n'ayez pas peur cela ne coupe pas les connexions existantes
$ /etc/init.d/ssh restart

Côté client

Maintenant il faut que le client accepte cette clé. On va lui dire qu'il peut accepter tout ce qui a été signé par notre autorité. Pour cela, il suffit de copier le certificat de l'autorité dans /etc/ssh/ca/ca-bundle.crt (vous pouvez mettre toutes les autorités que vous voulez dans ce fichier) :

$ cp ca.crt /etc/ssh/ca/ca-bundle.crt

Attention : ssh vérifie que le certificat est bien signé par une autorité valide mais cela ne veut pas dire qu'il accepte directement la clé. Il passe toujours par une vérification utilisateur comme expliqué dans un autre article. Attention : ssh refuse les clés mal signées mais autorise les clés sans certificat. A l'utilisateur d'accepter ou refuser la clé. Attention : ssh vérifie la chaine de certification, mais ne vérifie pas que le cn correspond au nom du serveur.

A noter qu'il est dommage que la vérification de la chaine de certification se fasse après l'acceptation par le client.

Authentification du client

Cette fois c'est le serveur qui va vérifier que le client dispose d'un certificat vérifié par une autorité.

Côté client

Pour utiliser notre certificat comme identité, on le copie sur le client :

$ cat client.key client.crt > ~/.ssh/id_x509
$ chmod 600 ~/.ssh/id_x509
# on met a jour la clé publique
$ ssh-keygen -y -f ~/.ssh/id_x509 > ~/.ssh/id_x509.pub

Et on configure le client pour qu'il l'utilise (au choix dans /etc/ssh/ssh_config ou dans ~/.ssh/config) :

Host *
        IdentityFile ~/.ssh/id_x509

Côté serveur

Maintenant il faut que le serveur accepte cette clé. On va lui dire qu'il peut accepter tout ce qui a été signé par notre autorité. Pour cela, il suffit de copier le certificat de l'autorité dans /etc/ssh/ca/ca-bundle.crt (vous pouvez mettre toutes les autorités que vous voulez dans ce fichier) :

$ cp ca.crt /etc/ssh/ca/ca-bundle.crt

Et on adapte l'authorized_keys sur le serveur. Pour cela deux solutions, la première est de copier tel quel le fichier id_x509.pub généré précédemment. Ça marche, mais ce n'est pas très intéressant. Puisqu'on a des certificats qui sont vérifiés autant en profiter et ne donner que le DN ce qui nous permettra de le changer.

# on réutilise le certificat pour sortir le dn au bon format
$ openssl x509 -noout -subject -in client.crt -nameopt RFC2253 >> ~/.ssh/authorized_keys

Attention : ssh refuse les clés mal signées mais autorise les clés sans certificat. A l'utilisateur de remplir son authorized_keys correctement

Conclusion

Cet article commence à être long, je vais donc m'arrêter ici. Vous voyez qu'il est possible de mettre en place des certificats pour ssh sans trop se forcer. Le patch de Roumen Petrov est bien fait puisqu'il ajoute beaucoup d'options (je les ai laissé ici à leur valeur par défaut pour simplifier l'article) et surtout, elles sont toutes documentées dans les pages de manuel. De plus le support de x509 est étendu à tous les outils ssh, c'est à dire le client, le serveur, mais aussi ssh-keygen et ssh-agent. En dehors du man, la meilleure documentation c'est le README.

Tout cela est bien pratique mais seul un usage basique a été couvert ici. Un des gros avantages de l'utilisation des certificats est de pouvoir gérer des listes de révocation pour interdire automatiquement des certificat qui ne sont plus valides (l'utilisateur est parti, la clé est trop vieille ...). Nous en parlerons surement dans un prochain article.

Niveau : Star Star Star Empty Empty
Résumé : sshd -T ; ssh -l

I'm back ! Ca y est j'ai déménagé. Je peux maintenant reprendre mon activité normale ...

Au cas où vous ne le sauriez pas, la dernière version de openssh vient de sortir, la 5.1. La lecture du changelog est très instructive. On y découvre entre autre deux nouveautés ben sympathiques.

Serveur

Commençons par une nouvelle option de sshd :

$ sshd -T

Cette option permet de tester la configuration du serveur. Ce genre d'option devrait être disponible sur tous les softs, grâce à elle, vous pourrez savoir du premier coup d'oeil si vous avez bien écrit votre configuration et si sshd a bien compris la même chose que ce que vous vouliez lui dire.

Client

Ensuite, une nouvelle option de ssh (qui n'est pas activée par défaut) :

$ ssh -o "VisualHostKey true" mamachine.net

Cette option affiche une interprétation du fingerprint de la machine distante sous forme d'ASCII art. Il est ainsi beaucoup plus facile de comparer 2 clés (il suffit de les regarder).

Cette fonction répond au problème de la confiance au serveur ssh. Lorsque vous vous connectez, ssh vérifie que le serveur distant est connu, si vous vous y êtes déjà connecté et que la clé n'a pas changé, on peut faire confiance en son identité. Mas lorsque c'est la première fois que vous vous connectez, il faut vérifier manuellement que la clé est ben la bonne. Avec cette option la vérification est simplifiée, on espère donc que les gens la feront plus souvent ...

Niveau : Star Star Empty Empty Empty
Résumé : clusterssh, clusterm, konsole, dsh, pssh

Bonjour à tous, très honoré d'être à la tribune de ce blog, mais on m'a forcé la main !

Pour rebondir sur un post récent (tout juste un an !), voici quelques outils pour travailler efficacement sur un groupe de machines.

Konsole et dsh, les ancêtres

Comme Peck l'avait présenté, pour envoyer une même suite de commandes sur un groupe de machines, on peut soit le faire à l'aveugle avec Konsole (si on supporte KDE), soit lancer ses commandes coûte que coûte avec dsh, mais sans contrôle encore une fois sur le déroulement.

Avec Konsole : préparez dans une même fenêtre une machine à contrôler par onglet, puis dans les menus : View > Send Input to All Sessions. Désormais, tout ce que vous tapez est répété dans toutes les fenêtres.

Avec dsh :

 dsh -m machine1 -m machine2 commande

Attention, n'oubliez pas que votre commande est d'abord interprétée par votre shell. Ainsi, comparez :

 dsh -m machine1 -m machine2 -m ... "echo $HOSTNAME"
 dsh -m machine1 -m machine2 -m ... 'echo $HOSTNAME'

Relisez l'article pour apprendre comment créer des groupes de machines avec dsh.

clusterssh et clusterm

Mais si on désire surveiller ce qui se passe sur toutes les machines, et ainsi avoir un contrôle visuel, et au besoin effectuer une correction sur une machine en particulier, alors des outils graphiques rendent bien service, en affichant dans un terminal distinct chacune des machines que l'on contrôle. Par ici pour des captures d'écran, et un petit article de présentation de clusterssh !

Vous pouvez définir vos groupes de machines dans le fichier /etc/clusters :

groupe1 machine1 machine2 machine3 machine4 machine5 machine6 machine7 machine8 machine9
groupe2 machine10 machine11 machine12 machine13 machine14 machine15
all groupe1 groupe2

Dès lors, un

cssh groupe1 # vous ouvre un terminal sur machine1 à machine 9
cssh groupe2 # vous ouvre un terminal sur machine10 à machine15
cssh all # pour machine1 à machine15

Si vous avez des ports particuliers, des utilisateurs particuliers à utiliser sur certaines machines, pensez à votre ~/.ssh/config :-)

Et comme indiqué dans les commentaires, une alternative à clusterssh est clusterm, qui est un peu plus eye-candy et offre en plus la merveilleuse fonctionnalité d'afficher les différences entre les écrans, à la vimdiff, très pratique pour comparer rapidement des fichiers de configuration entre n machines distinctes ! Malheureusement, ce programme n'est pas packagé pour Debian, libre à vous de lancer une ITP dessus ;-)

Toutefois, des paquets pour ubuntu existent (ils marchent aussi sous debian), il suffit de récupérer les 2 .deb proposés et de les installer à coup de dpkg -i.

Pas de fichier de configuration de groupe pour ce programme, mais plusieurs options :

 alias clusterm-groupe1='clusterm machine1 machine2 machine3 machine4 machine5 machine6 machine7 machine8 machine9'

ou bien constituer votre groupe "à la main" dans l'interface, en ouvrant successivement vos shells sur chacune des machines indiquées, puis enregistrer votre session (menu fichier) sous forme d'un raccourci à placer sur votre bureau :-)

pssh

Une autre petite suite d'outils bien sympathique est pssh, qui propose diverses commandes comme parallel-ssh (équivalent de dsh -c), parallel-nuke, parallel-scp ou parallel-slurp (son contraire).

Le plus simple est de lire ce qu'indique la description du paquet (apt-cache show pssh) :

  • Parallel ssh (parallel-ssh, upstream calls it pssh), executes commands on multiple hosts in parallel
  • Parallel scp (parallel-scp, upstream calls it pscp), copies files to multiple remote hosts in parallel
  • Parallel rsync (parallel-rsync, upstream calls it prsync), efficiently copies files to multiple hosts in parallel
  • Parallel nuke (parallel-nuke, upstream calls it pnuke), kills processes on multiple remote hosts in parallel
  • Parallel slurp (parallel-slurp, upstream calls it pslurp), copies files from multiple remote hosts to a central host in parallel
# Tout d'abord, constituer un fichier groupe1.txt contenant une machine par ligne
parallel-ssh groupe1.txt uptime

# Récupérer dans des répertoires relatifs au nom des serveurs un fichier donné sur chacun des serveurs
mkdir -p /tmp/slurp
parallel-slurp -h groupe1.txt -L /tmp/slurp /etc/hostname hostname
ls -lR /tmp/slurp

# Tuer apache* sur tout un groupe de machines
parallel-nuke -h groupe1.txt apache

# Pousser un fichier localement sur toutes les machines
parallel-scp -h groupe1.txt toto.pl ~/toto.pl

Ailleurs

Autrement, d'autres outils du même acabit existent, vous trouverez ici une liste non exhaustive. N'hésitez pas à partager ici vos découvertes !

À plus peut être pour une nouvelle aventure, si vous le voulez bien :-)

Niveau : Star Star Star Empty Empty
Résumé : locale ; export LANG ; AcceptEnv ; SendEnv

Je vais devoir arrêter les voyages, hier, je change de locale, aujourd'hui je me connecte ... rien !

Une locale c'est tout un ensemble de choses qui permettent de faire en sorte que les logiciels s'affichent dans la langue qui vous convient. Pour les développeurs, j'ai un début d'explication sur la technique.

Et ça commence par des variables locales. La première c'est LANG, qui définit la façon par défaut d'afficher les informations. Cette méthode peut ensuite être surchargée finement avec les variables LC_*, par exemple LC_MONETARY permet de changer spécifiquement l'affichage de la monnaie. Et enfin, toutes ces valeurs peuvent encore être surchargées globalement et d'un coup par la variable LC_ALL.

Étant des variables d'environnement, ces infos sont transmises de processus en processus. Donc de shell en commande. Pour connaître la locale en cours, c'est simple :

$ locale

Pour la changer :

# on liste les locales disponibles
$ locale -a
# on en choisit une
$ export LANG=fr_FR

À ajouter dans votre .bashrc pour conserver la chose un peu plus longtemps (attention, gnome et kde et caetera sont à configurer séparément).

Pour changer ceci de façon globale, ben c'est pas gagné, selon les distributions et les softs, tous n'utilisent pas les même fichiers de configuration. Tout d'abord, il y a l'historique /etc/environment, pour les shells on peut aussi chercher dans /etc/profile. Et ensuite, mais c'est spécifique debian, il y a /etc/default/locale.

Pour les systèmes utilisant pam (su, login, kdm, gdm, ...) vous pouvez aller lire les /etc/pam.d/XXX qui peuvent contenir une ligne du type :s

auth    required        pam_env.so readenv=1 envfile=/etc/default/locale

indiquant où chercher vos variables.

Et enfin, parlons ubiquité, je ne sais pas vous, mais moi je suis partout, j'ai un compte sur toutes les machines (si je n'en ai pas chez vous, appelez-moi, j'accepterai volontiers un compte, de préférence root, mais je ne voudrais pas déranger). Je suis tout d'abord chez moi, avec ma locale, et donc mon terminal adapté à cette locale (hé oui, pensez iso vs utf8) et je me connecte en ssh sur un de mes comptes. Je voudrais bien rester moi-même et garder mes locales et non pas prendre celle du système ou devoir configurer chacun des shells de destinations à la main. Heureusement, ssh a aussi prévu ce cas. Il permet la transmission des locales s'il est configuré correctement.

Sur le serveur, dans /etc/ssh/sshd_config :

# on autorise le client a jouer avec les locales à la connexion
AcceptEnv LANG LC_*

Sur le client, de préférence dans /etc/ssh/ssh_config :

Host *
# on envoit nos locales au serveur
    SendEnv LANG LC_*

Et voilà, pour peu que votre /etc/pam.d/ssh ne contienne pas de référence à un fichier qui forcerait les locales, vous êtes chez vous.

Niveau : Star Star Empty Empty Empty
Résumé : ssh -M -S

Si vous faites de nombreuses connexions ssh à une machine, soit pour lancer plusieurs shells, soit pour exécuter des séries de commandes, votre client ssh va initialiser une nouvelle connexion à chaque fois. Ceci peut devenir très lourd pour une machine un peu ancienne. En effet, ceci implique le handshake tcp, la négociation du cryptage, l'échange de clés et donc un certain temps de calcul.

Il est plus judicieux de ne faire qu'une seule connexion ssh et de multiplexer toutes vos commandes par dessus (soit à cause de la faiblesse de la machine, soit parce que vous faites un grand nombre de connexions). Heureusement, ssh a tout prévu :

# première connexion
$ ssh -M -S /tmp/master mamachine.net

# deuxième connexion
$ ssh -S /tmp/master mamachine.net

La deuxième connexion est infiniment plus rapide (ajoutez l'option -v pour en être convaincu). De plus notez que même si vous terminez la commande (ou le shell) de la première connexion, celle-ci ne sera vraiment terminée que lorsque la deuxième commande le sera aussi. Vous pouvez ainsi multiplexer autant de connexions que vous voulez, l'option -M ne sert qu'une fois pour la création du master de connexion.

Remarquez que vous pouvez utiliser n'importe quel nom de machine pour les connexions slave, c'est la syntaxe ssh qui vous force à en utiliser un, mais il n'est pas réellement utilisé, exemple :

$ ssh -M -S /tmp/master mamachine.net
# mamachine.net ou azerty c'est pareil
$ ssh -S /tmp/master azerty