Tutorial / How-To / Howto

Après l’article sur le tunneling ssh : Tunnel SSH à travers un proxy , voici une autre fonctionnalité intéressante : le "SSH Bouncing" ou le "SSH avec rebond".

Principe : on veut se connecter depuis une machine C sur internet à une machine B de son réseau interne (ex : @IP 192.168.0.10), en rebondissant sur une machine A accessible sur internet (ex : host.foobar.com)



                    |                                  
                    |      
machineC ---->----machineA=====>=====machineB
             (host.foobar.com)    (192.168.0.10)
                    |
                    |                              


\___________________/ \______________________/
      INTERNET             RESEAU INTERNE

1ère méthode : tunnel SSH avec "LocalForward"

Il est possible d’utiliser un tunnel ssh sur la machineA en redirigeant par exemple le port local 2222 de la machineC vers la machineB interne 192.168.0.10

- sur la machineC, fichier ˜/.ssh/config


Host machineA
   Hostname host.foobar.com
   LocalForward 2222 192.168.0.10:22

Host machineB
   Hostname 127.0.0.1
   HostKeyAlias machineB
   Port 2222

Il faut ouvrir alors 2 connexions ssh simultanées depuis la machineC :

  • ssh machineA => ouvre une connexion SSH sur la machineA
  • ssh machineB => ouvre une connexion SSH vers la machineB, tunnelée dans la première connexion SSH de la machineA... c’est clair ? :)

Il y a plusieurs inconvénients à cette méthode :

  • il faut que le forwarding de port soit activé sur le serveur ssh de la machineA : AllowTcpForwarding=yes
  • il faut que l’utilisateur de la machineC ait un compte/accès shell sur la machineA
  • il n’est pas possible de restreindre les ports forwardés pour l’utilisateur

2ème méthode : utilisation de SSH/ProxyCommand + netcat

Pour faire simple, on suppose que le compte de la machineB s’appelle "pierre".

On va créer le même compte "pierre" sur la machineA, en restreignant ses droits et on utilisera la même clé privée/publique pour le compte pierre sur les 2 machines machineA et machineB...

- sur machineA

  • Créer le compte pierre et créer le répertoire ˜/.ssh

# adduser pierre
# su pierre
$ mkdir ~/.ssh

- sur la machineC

  • Générer une clé publique/privée rsa 1024 bits pour le compte pierre

# su pierre
$ ssh-keygen -t rsa -b 1024 -f ~/.ssh/machineB_rsa

(mettre une passphrase vide)

=> 2 fichiers devraient être générés dans le répertoire ˜/.ssh : machineB_rsa (clé privée) et machineB_rsa.pub (clé publique)

  • Copier sa clé privée générée machineB_rsa sur la machineA dans le répertoire ˜/.ssh du compte pierre

$ scp ~/.ssh/machineB_rsa pierre@host.foobar.com:~/.ssh

- copier sa clé publique générée machineB_rsa.pub sur le compte pierre de machineA, et la rajouter dans le fichier ˜/.ssh/authorized_keys (si ce fichier n’existe pas : il faut le créer avant) puis vous pouvez effacer le fichier machineB_rsa.pub


$ scp machineB_rsa.pub pierre@machineA:~/.ssh/
$ ssh pierre@machineA "cat ~/.ssh/machineB_rsa.pub >> ~/.ssh/authorized_keys
$ ssh pierre@machineA "rm ~/.ssh/machineB_rsa.pub"
  • faire de même sur la machineA

- sur machineA


$ scp machineB_rsa.pub pierre@192.168.0.10:~/.ssh/
$ ssh pierre@192.168.0.10 "cat ~/.ssh/machineB_rsa.pub >> ~/.ssh/authorized_keys
$ ssh pierre@192.168.0.10 "rm ~/.ssh/machineB_rsa.pub"

- sur machineA (rebond SSH)

  • Configurer ssh : modifier le fichier ˜/.ssh/config

Host machineB
Hostname 192.168.0.10
       User pierre
       IdentityFile /home/pierre/.ssh/machineB_rsa
  • fichier ˜/.ssh/authorized_keys

Restreindre le shell du compte pierre, en vérifiant les commandes utilisées sur le compte pierre : rajouter command="/home/pierre/validate-ssh" dans le fichier ˜/.ssh/authorized_keys


command="/home/pierre/validate-ssh" ssh-rsa XXXX[...]XXXX pierre@localhost
  • créer le script /home/pierre/validate-ssh

#!/bin/sh

case "$SSH_ORIGINAL_COMMAND" in
       *\&*)
               echo "Rejected"
               ;;
       *\(*)
               echo "Rejected"
               ;;
       *\{*)
               echo "Rejected"
               ;;
       *\;*)
               echo "Rejected"
               ;;
       *\<*)
               echo "Rejected"
               ;;
       *\`*)
               echo "Rejected"
               ;;
       ssh\ pierre@machineB\ nc\ \-q\ 0\ 127.0.0.1\ 22*)
               $SSH_ORIGINAL_COMMAND
               ;;
       *)
               echo "Rejected"
               ;;
esac

Rq : pour un *bsd, remplacer la ligne "nc\ \-q\ 0\ 127.0.0.1" par "nc\ \-o\ 127.0.0.1"

- sur machineC

  • configurer ssh : modifier le fichier ˜/.ssh/config

Host foobar
Hostname host.foobar.com
        User pierre
        IdentityFile ~/.ssh/machineB_rsa

Host machineB_via_machineA
        User=pierre
        IdentityFile ~/.ssh/machineB_rsa
        ProxyCommand ssh foobar ssh pierre@machineB nc -q 0 127.0.0.1 22

Rq : pour un *bsd, remplacer la ligne "nc -q 0 127.0.0.1" par "nc -o 127.0.0.1"

  • et c’est tout : il ne reste plus qu’à tester !

$ ssh machineB_via_machineA

... vous devriez être connecté alors automatiquement sur la machine B :)

Documentation