Reverse SSH : accéder à un serveur derrière un NAT/Firewall

Le SSH tout le monde le sait, c’est magique. Mais malheureusement ça ne marche pas OOTB. On a tous en tête plusieurs situations où on s’est dit “Damn, si seulement j’avais un accès SSH sur cette machine”, la machine étant inaccessible parce que derrière un firewall ou routeur NAT que vous ne contrôlez pas.

Imaginez avoir accès en SSH à la machine de ce noob qui ne sait pas configurer son NAT. Ou bien vous assurer que votre laptop soit toujours joignable en SSH peu importe la connexion sur laquelle il est…

Cette conférence du DEF-Con m’a interloqué : comment le mec a repris la main sur une machine qui était probablement derrière un NAT? Peut-être grâce au reverse SSH !

Principe de fonctionnement

Le principe est assez simple : c’est l’ordinateur derrière le NAT (nous l’appellerons distant) qui doit établir la première connexion. Il établit en fait un tunnel SSH vers vous (nous l’appellerons local) et ainsi en remontant le tunnel dans l’autre sens on accède très facilement à la destination.

On suppose donc que la connexion SSH vers l’ordinateur local est aisée (serveur dédié ou NAT bien configuré).

Avantages

  • Plus besoin de connaître ou de modifier la configuration du réseau sur lequel est branché distant pour pouvoir y établir une connexion SSH. Tant que le port 22 est ouvert en outgoing ça fonctionnera (on peut même envisager de déplacer le serveur de local sur un port moins restreint tel que le 80 ou 443)
  • Plus besoin de connaître l’IP où se trouve distant, c’est lui qui établit le contact vers local

Vérifiez la configuration du serveur SSH local

Il faut que le serveur sur local autorise les tunnels (/etc/ssh/sshd_config) :
AllowTcpForwarding yes

Let’s go!

Sur distant (la machine inaccessible), créez le tunnel :
distant$ ssh -NR 22222:localhost:22 user@local
Bien entendu local est l’IP de votre machine et user est un utilisateur qui y a accès.

Une fois le tunnel établi, il ne vous reste plus qu’à remonter le tunnel pour établir la connexion SSH depuis local :
local$ ssh -p 22222 user@127.0.0.1

Service au démarrage

Avec autossh (disponible dans le package manager de votre distro préférée) et une connexion SSH sans mot de passe, vous pouvez très facilement créer un script de démarrage sur distant pour que le tunnel soit toujours récréé sans intervention humaine :
# autossh -i /path/to/privateKey.rsa -NR 22222:localhost:22 user@local

Il vous suffit d’ajouter cette commande dans vos scripts de boot (/etc/rc.local par exemple).

Aller plus loin

Ici nous utilisons du SSH pour ouvrir l’accès à un serveur SSH, mais on pourrait envisager d’ouvrir l’accès à n’importe quel serveur qui tournerait sur distant, par exemple un serveur web pour du monitoring Munin :
distant$ ssh -NR 22280:localhost:80 user@local
local$ firefox "http://127.0.0.1:22280"

Vous l’aurez compris, vous pouvez aussi centraliser sur votre serveur (“local”) des tunnels venant de tous les n00bs que vous aidez régulièrement, l’astuce est de remplacer 22222 dans les diverses commandes citées sur cette page par un autre code de port compris entre 1024 et 65535. Et de maintenir une liste exhaustive de ceux-ci !

Vus : 2518
Publié par Geekfault : 45