J'aime beaucoup OpenSSH. C'est un très bon logiciel, au-delà des capacités de chiffrement ou de son système de transfert de fichiers. Tunnels et commandes automatisées, authentification par clés, tout est bon dans le poisson ! Comme mon billet en 3 étapes m'a semblé clair, je continue sur l'organisation énoncé - possibilités - mise en œuvre.

C'est quoi ton problème ?

Imaginons une zone réseau (au hasard une DMZ) dans laquelle il y a une ou plusieurs machines, possédant toutes un serveur OpenSSH. Une seule machine peut accéder à ce réseau, cette "passerelle" servant de rebond pour accéder aux autres serveurs en SSH. Au bout d'un certain nombre de fois, il devient rébarbatif d'avoir à se connecter d'abord à la "passerelle" puis à se connecter au serveur pour y faire les manipulations désirées. Il faudrait automatiser le rebond pour qu'il se fasse tout seul, en quelque sorte.

Et t'as quoi comme solution ?

Il en existe plusieurs. Celle que je décris ici est celle qui me convient le mieux, mais peut ne pas vous satisfaire. Ne la considérez donc pas comme LA solution. Le principe est d'utiliser le fichier de configuration "utilisateur" d'OpenSSH (~/.ssh/config)pour automatiser le rebond via la directive "ProxyCommand". Commençons d'abord par lister les logiciels nécessaires : il nous suffit d'une machine avec un client OpenSSH (disponible sur tous les unix normalement, et sous Windows avec Cygwin), et sur la machine "passerelle", en plus du serveur OpenSSH, il nous faut le client et Netcat. Notez que dans mon cas :

  • le client est sous NetBSD 5.0.1
  • la passerelle est sous CentOS 5.4
  • les serveurs accédés sous sous l'un des deux OS mentionnés ci-dessus
  • j'ai reproduit ce système avec des RHEL 4

La commande de l'outil Netcat est "nc", vérifions donc que les commandes sont disponibles, d'abord le client :

nils@client:~$ which ssh
/usr/bin/ssh

Et puis la passerelle :

nils@passerelle:~# which ssh
/usr/bin/ssh
nils@passerelle:~# which nc
/usr/bin/nc

Le chemin n'est pas forcément le même selon l'OS utilisé, l'important c'est que les outils soient installés.

On passe à l'action ?

Rentrons à présent dans le vif du sujet. La configuration ne se fait que depuis la machine cliente, commençons par configurer un accès vers la passerelle. Pour cela, il faut créer un fichier ~/.ssh/config, et l'éditer avec le logiciel qui vous conviendra le mieux : dans mon cas, il s'agit de Vim. N'oublions pas de créer le répertoire .ssh/ s'il n'existe pas :

nils@client:~$ cd ~
nils@client:~$ mkdir .ssh
nils@client:~$ chmod 600 .ssh
nils@client:~$ cd .ssh
nils@tomb:~/.ssh$ touch config
nils@tomb:~/.ssh$ chmod 644 config
nils@tomb:~/.ssh$ vim config

Note : les droits sont très importants ! La configuration pour la passerelle est la suivante :

Host passerelle
        Hostname lenomouladresseipdelapasserelle
        Port 22
        Protocol 2
        User nils
        ProxyCommand none

On remarque que cette configuration n'a pour but que de simplifier les connexions vers la machine passerelle, il devient ainsi aisé de taper ssh passerelle au lieu de ssh nils@lenomouladresseipdelapasserelle (et le numéro de port si votre serveur OpenSSH n'écoute pas sur le port 22). Passons à la configuration pour accéder au serveur nommé serveurdmz1, qu'on ajoute à la suite du fichier config en cours d'édition :

Host serveurdmz1
        Hostname lenomouladresseipduserveurdepuislapasserelle
        Port 22
        Protocol 2
        User nils
        ProxyCommand ssh nils@passerelle "nc %h %p"

On remarque que la directive ProxyCommand utilise directement le nom passerelle, grâce à la configuration précédente. On sauvegarde et on quitte (sous Vi/Vim : Echap puis ZZ). Maintenant on teste le résultat :

nils@client:~$ ssh serveurdmz1
nils@passerelle's password:
nils@serveurdmz1's password:
nils@serveurdmz1:~$

Ce résultat peut différer légèrement, je ne poste pas les acceptations de clés pour les premières connexions. Il suffit maintenant de répéter le deuxième bloc pour chaque serveur de votre "DMZ".

Observations et améliorations possibles

Après ce premier essai, on remarque qu'il y a encore de la place pour l'automatisation, en particulier le mot de passe de la passerelle qui est réclamé. Ceci peut être résolu par l'utilisation de clés de chiffrement, comme l'explique très bien Peck.

Une autre remarque, si on se connecte à deux, trois serveurs : en tapant la commande who sur la passerelle, on voit qu'on est connecté une fois sur la passerelle pour chaque connexion vers un serveur en DMZ. Par exemple, si j'ai un shell sur la passerelle et un shell sur 3 serveurs en DMZ, la commande who sur la passerelle montrera que l'utilisateur nils est connecté 4 fois ! Cela peut s'avérer gênant pour certains. Pour ceux-là, il est préférable de changer de méthode, et de créer un tunnel socks puis d'utiliser ce tunnel pour accéder aux serveurs en DMZ (via la directive ProxyCommand), ou d'essayer de mutualiser les connexions. A noter un inconvénient du tunnel socks : il faut d'abord ouvrir le tunnel (et donc un shell) avant de pouvoir se connecter aux serveurs en DMZ.