Groupe d'Utilisateurs de Logiciels Libres
de Nancy et ses environs

MirabellugWiki

PresentationSSH

PagePrincipale :: DerniersChangements :: ParametresUtilisateur :: Vous êtes ec2-50-17-174-94.compute-1.amazonaws.com

Présentation de SSH


Secure SHell : http://www.openssh.org

Ssh permet d'exécuter un shell à distance, d'échanger des fichiers et de connecter des ports locaux et distants en cryptant tout les échanges entre la machine locale et la machine distante. Le mécanisme des clefs publiques/privées permet également de garantir dans une certaine mesure l'identitée des utilisateurs qui se connectent.

Connexion à un shell distant

Par défaut, on se connecte au shell distant grâce au nom d'utilisateur/mot de passe.

urba@mirabelle:~$ ssh root@distant
root@distant's password: 
Last login: Fri Mar  4 19:41:12 2005 from 10.0.0.1
distant:~#


Création d'une paire de clefs

On crée pour tester une clef de type rsa (l'autre option est dsa) sans mot de passe.

urba@mirabelle:~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/urba/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/urba/.ssh/id_rsa.
Your public key has been saved in /home/urba/.ssh/id_rsa.pub.
The key fingerprint is:
c6:42:ce:6d:57:e3:c1:ab:85:5f:a9:58:f7:79:4c:4b urba@mirabelle


Ceci crée deux fichiers : ~/.ssh/id_rsa qui est la clef privée à conserver secrète et ~/.ssh/id_rsa.pub et qui la clef publique à installer sur les serveurs distants.

On peut changer le mot de passe et la description par la suite :
urba@mirabelle:~$ ssh-keygen -p
Enter file in which the key is (/home/urba/.ssh/id_rsa): 
Key has comment '/home/urba/.ssh/id_rsa'
Enter new passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved with the new passphrase.

Installation de la clef publique sur le serveur distant :

On utilise ici une des commandes fournie avec ssh : scp, qui permet de copier des fichiers d'une machine à l'autre.
urba@mirabelle:~$ scp ~/.ssh/id_rsa.pub root@distant:/root/.ssh/authorized_keys
Password: 
id_rsa.pub


Maintenant, à la connexion, ssh ne nous demande plus d'abord le mot de passe distant mais le mot de passe de la clef privé qui correspond à la clef publique que nous venons d'envoyer sur le serveur distant.

urba@mirabelle:~$ ssh root@distant
Enter passphrase for key '/home/urba/.ssh/id_rsa': 
Last login: Thu Mar  3 21:27:54 2005 from 10.0.0.1
distant:~#


Si nous n'avions pas mis de mot de passe sur notre clef, nous nous serions connecté immédiatement sans mot de passe.

Utilisation de ssh-agent

ssh-agent est un démon qui permet de mémoriser les mots de passe des clefs ssh que l'on utilise, ce qui évite de le resaisir à chaque fois.
Le mot de passe est stocké de façon sécurisé en RAM et n'est jamais écris sur le disque.

urba@mirabelle:~$ ssh-agent 
SSH_AUTH_SOCK=/tmp/ssh-HkQoPp1286/agent.1286; export SSH_AUTH_SOCK;
SSH_AGENT_PID=1287; export SSH_AGENT_PID;
echo Agent pid 1287;


La commande ssh-add permet d'ajouter des clefs à celles gérées par ssh-agent :
urba@mirabelle:~$ ssh-add
Enter passphrase for /home/urba/.ssh/id_rsa: 
Identity added: /home/urba/.ssh/id_rsa (/home/urba/.ssh/id_rsa)


On peut lister les clefs gérées par ssh-agent à chaque instant :
urba@mirabelle:~$ ssh-add -l
1024 c6:42:ce:6d:57:e3:c1:ab:85:5f:a9:58:f7:79:4c:4b /home/urba/.ssh/id_rsa (RSA)


Maintenant que la clef est enregistrée, on peut se connecter sur la machine distant (ou faire scp) sans saisir de mot de passe.
urba@mirabelle:~$ ssh root@distant
Last login: Thu Mar  3 21:32:04 2005 from 10.0.0.1
distant:~#

Attention : mal utilisée, cette fonctionnalité peut aussi être une faille de sécurité !

Lorsqu'on en a plus besoin, on peut supprimer la clef courant de l'agent :
urba@mirabelle:~$ ssh-add -D
All identities removed.
urba@mirabelle:~$ ssh-add -l
The agent has no identities.

Le X11 forwarding

Lorsqu'on se connecte à une machine distante, on peut même utiliser un environnement graphique.
Pour cela il faut :
  • que certains packages soient installé sur la machine distante (les bases de X11, xauth, etc ...)
  • que le serveur sshd ait l'option X11Forwarding à yes
  • que l'on lance le client ssh dans une session graphique, cad avec un serveur X de lancé.
  • que côté client l'option ForwardingX11? soit positionnée à yes dans /etc/ssh/ssh_config.

Un netstat --inet -lnp en local nous prouve que notre serveur X est lancé et en écoute sur le port 6000 :
tcp        0      0 0.0.0.0:6000            0.0.0.0:*               LISTEN      26721/X


La variable d'environnement DISPLAY est utilisée par les applications graphiques pour trouver le serveur X.
urba@mirabelle:~$ echo $DISPLAY
:0.0


Sur la machine distante, on se rend compte alors que sshd écoute sur le port 6010 (par défaut). Ceci correspond aux ports 6000 utilisés par X et 10 représente le "décalage" par défaut du DISPLAY sur la machine distante (cf. l'option "X11DisplayOffset 10" de sshd_config). Ce décalage permet de ne pas être gèner par un serveur X qui tournerait déjà sur la machine distante.

distant:~# netstat -lnp | grep ssh
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     403/sshd            
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN     7413/sshd: root@tty


ssh positionne également dans ce cas la variable d'environnement DISPLAY en tenant compte du décalage.
distant:~# echo $DISPLAY
localhost:10.0
distant:~# xeyes


L'application s'ouvre dans le serveur X local parceque ssh a "tunnelisé" dans le flux crypté la connection entre le port 6010 distant (qu'utilisent les applications clientes distantes pour envoyer leur affichage) et le port 6000 local utilisé par notre serveur X qui va effectuer l'affichage réel.

X11 forwarding simplifié

Une méthode très simple de faire de l'X11 forwarding consiste à utiliser la syntaxe suivante:
jml@jml3$ ssh -X jml@pc_distant

L'option -X met ici les mains dans le camboui à votre place et vous débarasse de la contrainte des différents réglages. Elle fonctionne à la condition que X11Forwarding et ForwardingX11? soient bien réglés à "yes". L'identification se fait simplement par mot de passe associé au compte auquel on se connecte.
C'est la méthode qu'on pourra utiliser de façon privilégiée dans le cas de l'utilisation d'une distribution sur live CD côté utilisateur pour se connecter sur un serveur distant. Dans ce cas on ne souhaite généralement pas mettre en place toute l'authentification décrite ci-dessus.

Copie de fichiers via SSH

Le flux SSH peut très bien servir à faire de la copie de fichier. Exemple pour copier un fichier du PC distant vers le PC local:
jml@jml3$ ssh jml@pc_distant "cat fichier_distant" > fichier_local

Cet exemple montre comment combiner ssh et redirection de flux pour obtenir une copie.
Une variante plus académique serait:
jml@jml3$ scp jml@pc_distant:fichier_distant fichier_local

ou alors (dans l'autre sens):
jml@jml3$ scp fichier_local jml@pc_distant:fichier_distant

Ces deux syntaxes utilisent scp, la commande de copie associée à ssh. Voir les pages man qui vous permettrons de découvrir d'autres fonctionnalités comme sftp, un ftp via ssh.

Le forwarding de port

Le "X11 forwarding" est une utilisation particulière du "port forwarding" possible avec ssh :

Ici on connecte le port 80 de la machine distante au port 1080 de la machine locale.
Note : il aurrait fallu être root en local pour pouvoir utiliser le port 80 local (cf. <1024).

urba@mirabelle:~$ ssh root@distant -L 1080:distant:80
Password: 
Last login: Thu Mar  3 21:49:11 2005 from mirabelle
distant:~#


On voit alors que ssh écoute en locale sur le port 1080 :
urba@mirabelle:~$ netstat --inet -lnp
(Tous les processus ne peuvent être identifiés, les infos sur les processus
non possédés ne seront pas affichées, vous devez être root pour les voir toutes.)
Connexions Internet actives (seulement serveurs)
Proto Recv-Q Send-Q Adresse locale          Adresse distante        Etat        PID/Program name   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     -                   
tcp        0      0 127.0.0.1:1080          0.0.0.0:*               LISTEN     1379/ssh            
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN     -                   
udp        0      0 0.0.0.0:68              0.0.0.0:*                          -


On peut alors accèder au serveur web distant (port 80) en se connectant en local sur le port 1080.
urba@mirabelle:~$ http_proxy= lynx localhost:1080


On peut même "rebondir" sur notre serveur distant pour accèder à une machine qui ne serait pas joingnable directement :
urba@mirabelle:~$ ssh root@distant -L 1080:autre-machine:80

Fichier de configuration ~/.ssh/config

ssh et scp connaissent l'option -p pour se connecter à un port non standard (autre que 22), mais d'autres outils (svn notamment) n'ont pas cette capacité. Le fichier ~/.ssh/config permet (entre autres) de pallier à ce problème.

On va essayer avec le serveur svn du mirabellug
deplagne@cochire2:~$ ssh -p 10022 deltree@svn.mirabellug.org
( success ( 1 2 ( ANONYMOUS EXTERNAL ) ( edit-pipeline svndiff1 absent-entries ) ) )
Cette réponse étrange signifie que la commande svnserve -t est lancée automatiquement, nous n'avons pas accès en shell au serveur, c'est normal.

Mais svn ne sait pas spécifier le port 10022, en effet svn+ssh://deltree@svn.mirabellug.org:10022 ne donne rien
deplagne@cochire2:~$ svn co svn+ssh://deltree@svn.mirabellug.org:10022/var/lib/svn/mirabellug
ssh: svn.mirabellug.org:10022: Name or service not known
svn: Connexion fermée de façon inattendue

On va donc créer un fichier ~/.ssh/config
deplagne@cochire2:~$ cat .ssh/config
host svnlug
   Hostname svn.mirabellug.org
   Port 10022

Essayons d'abord avec ssh
deplagne@cochire2:~$ ssh deltree@svnlug
( success ( 1 2 ( ANONYMOUS EXTERNAL ) ( edit-pipeline svndiff1 absent-entries ) ) )
Ça semble bien.

Est-ce que svn est content ?
deplagne@cochire2:~$ svn co svn+ssh://deltree@svnlug/var/lib/svn/mirabellug
A    mirabellug/bac_a_sable
Révision 1 extraite.
C'est tout bon.