Tutorial / How-To / Howto

Voici une nouvelle version plus complète/complexe de l’article précédent : SSH bouncing.

Rappel du 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)

TODO (memo pour moi)

  • peut-être rajouter le paramètre ForceCommand de ssh
  • investiguer le fichier ˜/.ssh/rc


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


\___________________/ \______________________/
      INTERNET             RESEAU INTERNE

Utilisation de SSH/ProxyCommand + netcat

On suppose que le compte de la machineB s’appelle "pierre" et qu’on utilise également le compte "pierre" sur machineC.

Voici les principales étapes :

  • On va créer un compte "pierrebounce" sur la machineA servant de rebond ssh.
  • On va créer une clé publique/privée sur machineA ˜/.ssh/machineA_vers_machineB_rsa pour se connecter sans mot de passe depuis machine A vers machineB
  • On va créer une clé publique/privée sur machineC ˜/.ssh/pierre_sur_machineC_rsa pour se connecter depuis machineC sur machineA
  • On va restreindre les droits du compte pierrebounce sur machineA et du compte pierre sur machineB en se basant sur la clé publique des comptes.

- Installer le logiciel netcat sur machineA et machineB

- sur machineA

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

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

- sur machineC

  • Générer une clé publique/privée rsa 1024 bits pour le compte pierre : elle servira à se connecter depuis machineC sur le compte pierrebounce de machineA

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

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

  • Copier sa clé publique générée pierre_sur_machineC_rsa.pub sur la machineA dans le répertoire ˜/.ssh du compte pierrebounce

$ scp ~/.ssh/pierre_sur_machineC_rsa.pub pierrebounce@host.foobar.com:~/.ssh

- sur machineA

  • Rajouter la clé publique précédemment copiée dans la liste des clés publiques autorisées du compte pierrebounce : ˜/.ssh/authorized_keys (si ce fichier n’existe pas : il faut le créer avant) puis effacer la clé publique une fois ajoutée dans la liste.

# su pierrebounce
$ cat ~/.ssh/pierre_sur_machineC_rsa.pub >> ~/.ssh/authorized_keys
$ rm ~/.ssh/pierre_sur_machineC_rsa.pub"
  • Générer une clé publique/privée rsa 1024 bits pour le compte pierrebounce : : elle servira à se connecter sans mot de passe depuis machineA sur le compte pierre de machineB

# su pierrebounce
$ ssh-keygen -t rsa -b 1024 -f ~/.ssh/machineA_vers_machineB_rsa

(mettre une passphrase vide)

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

  • Comme précédemment, copier sa clé publique générée machineA_vers_machineB_rsa.pub sur la machineB dans le répertoire ˜/.ssh du compte pierre

$ scp ~/.ssh/machineA_vers_machineB_rsa.pub pierre@192.168.0.10:~/.ssh
  • Configurer ssh pour utiliser la clé privée générée : modifier le fichier /home/pierrebounce/.ssh/config

Host machineB
   Hostname 192.168.0.10
   User pierre
   IdentityFile ~/.ssh/machineA_vers_machineB_rsa
  • On va maintenant restreindre les droits du compte pierrebounce, dans un soucis de sécurité.
  • Au cas où par défaut l’option AllowTcpForwarding est activée pour le serveur ssh, il est possible de la désactiver pour un utilisateur particulier. Il faut modifier le fichier /etc/ssh/sshd_config :

[...]

Match User pierrebounce
 X11Forwarding no
 AllowTcpForwarding no
  • Créer le script /home/pierrebounce/validate-ssh pour restreindre les droits du compte pierrebounce

#!/bin/sh
#
# only allow the following shell command for user:
# ssh pierre@machineB nc -q 0 127.0.0.1 22*)

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"

  • Lier le script précédemment créé avec la clé publique de pierre (de machineC) : il faut modifier le fichier /home/pierrebounce/.ssh/authorized_keys et rajouter le paramètre command="/home/pierrebounce/validate-ssh" dans la ligne contenant la clé publique de pierre

command="/home/pierrebounce/validate-ssh" ssh-rsa XXXX[...]XXXX pierre@machineC
  • On va effectuer les mêmes opérations sur la machineB

- sur machineB

  • Rajouter la clé publique précédemment copiée dans la liste des clés publiques autorisées du compte pierre : ˜/.ssh/authorized_keys (si ce fichier n’existe pas : il faut le créer avant) puis effacer la clé publique une fois ajoutée dans la liste.

# su pierre
$ cat ~/.ssh/machineA_vers_machineB_rsa.pub >> ~/.ssh/authorized_keys
$ rm ~/.ssh/machineA_vers_machineB_rsa.pub"
  • Créer le script /home/pierre/validate-ssh pour restreindre les droits du compte pierre

#!/bin/sh
#
# only allow the following shell command for user:
# nc -q 0 127.0.0.1 22*)

case "$SSH_ORIGINAL_COMMAND" in
       *\&*)
               echo "Rejected"
               ;;
       *\(*)
               echo "Rejected"
               ;;
       *\{*)
               echo "Rejected"
               ;;
       *\;*)
               echo "Rejected"
               ;;
       *\<*)
               echo "Rejected"
               ;;
       *\`*)
               echo "Rejected"
               ;;
       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"

  • Lier le script précédemment créé avec la clé publique de pierrebounce (de machineA) : il faut modifier le fichier /home/pierre/.ssh/authorized_keys et rajouter le paramètre command="/home/pierre/validate-ssh" dans la ligne contenant la clé publique de pierrebounce. Vous pouvez aussi rajouter l’adresse IP privée de machineA dans le paramètre fromip (par ex : 192.168.0.1)

fromip="192.168.0.1",command="/home/pierre/validate-ssh" ssh-rsa XXXX[...]XXXX pierrebounce@machineA

- C’est presque fini : il reste à configurer ssh sur machineC

- sur machineC

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

Host foobar
Hostname host.foobar.com
        User pierrebounce
        IdentityFile ~/.ssh/pierre_sur_machineC_rsa

Host machineB_via_machineA
        User=pierre
        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