Monter un rebond SSH

closeCet article a été publié il y a 6 ans 11 mois 9 jours, il est donc possible qu’il ne soit plus à jour. Les informations proposées sont donc peut-être expirées.

Avec l’optique de monter plusieurs micro-VMs chez moi, donc derrière une seule adresse IP publique, je ne me vois pas m’amuser à ajouter autant de redirections de ports que j’ai de machines, d’autant plus que les mouvements seront peut-être nombreux. Alors pour me faciliter la vie, et profiter pleinement de la puissance d’SSH, je vais monter un serveur de rebond à partir duquel distribuer toutes mes connexions en fonction du nom de la machine que je choisirai.

Principes

Je l’ai expliqué, je n’ai qu’une seule adresse IPv4 publique chez moi. Si on veut donc accéder à plus d’une machine depuis l’extérieur, le plus simple est effectivement de jouer avec les redirections de ports. Mais si le nombre de dispositifs à contacter devient important, ça devient l’enfer de tout gérer.

Donc, à la manière d’un reverse-proxy qui va router vos URLs en fonction du domaine utilisé (exemple sur homeserver-diy.net), on va monter un « proxy » SSH, autrement appelé rebond, parce qu’on ne va pas simplement se connecter dessus pour ensuite lancer manuellement la connexion aux autres, mais directement « rebondir » dessus pour accéder à la machine voulue.

Vous verrez que quand on multiplie les machines, ça sera plus pratique et facile à retenir que de multiplier les alias de connexions comme je le fais actuellement. D’autant plus que les alias ne permettent de lancer qu’une seule commande, alors que là, on pourra lancer rsync et scp sans avoir à se palucher toutes les options.

Prérequis

On a donc besoin d’une machine qui va faire office de rebond. Debian 8 étant mon système de prédilection, je vais naturellement m’en servir ici, mais à partir du moment où vous pouvez utiliser OpenSSH comme serveur, donc sur n’importe quelle distribution Linux ou presque ainsi que des BSD, ça ira, à priori il n’y aura que quelques détails à modifier en fonction de la version.

Evidemment, disposer d’une clé SSH, et avoir distribué la clé publique correspondante sur les machines que vous voulez pouvoir contacter depuis l’extérieur, mais aussi sur le fameux rebond.

On peut également, pour des raisons de flexibilité, vouloir utiliser un serveur DNS ayant autorité sur une zone DNS dédiée, ça pourra être plus flexible que de passer par le panel de son fournisseur de services. En l’occurrence, j’ai toujours un domaine seboss666.ovh qui ne sert strictement à rien pour l’instant, je vais donc regarder pour l’utiliser, dans l’exemple depuis le panel OVH, mais si les mouvements sont fréquents, avoir son propre résolveur sera plus rapide (modification d’un fichier+restart, c’est plus simple que connexion panel+navigation zone+modif+valider+attendre que ça soit pris en compte, et en bonus on peut utiliser git pour versionner la zone). Dans la version finale histoire de juste pas utiliser BIND j’utilise Unbound + NSD 😛

(ndr : après de multiples attaques sur le résolveur DNS maison, j’ai décidé de laisser tomber et donc de rester sur les résolveurs OVH).

Configuration du serveur de rebond

Ben en fait cette partie c’est assez simple, ça se fait comme n’importe quel serveur SSH. Comme dit plus tôt il faut juste que la clé soit propagée sur tous les utilisateurs que vous comptez utiliser sur vos différentes machines (parce que vous n’utiliserez pas forcément le même, encore que ça serait beaucoup plus propre, et si possible, évitez root comme la peste, faites pas comme moi, même si je me soigne :P).

Pas besoin de s’étendre, à la limite je peux vous mentionner l’un des nombreux articles que l’on trouve sur le net, comme l’excellent article sur la partie sécurisation d’une installation (serveur et client) d’Abyss Project.

Une fois qu’il est prêt, il faut juste s’assurer qu’il est utilisable depuis l’extérieur, et il faut s’en assurer avec une règle NAT. Je déconseille comme d’habitude le port 22 d’origine, après, il y a toujours débat entre utiliser un port « haut » (>1024), non privilégié, et un port privilégié (<=1024). Faites comme vous le sentez, mais de toute façon, quand on voit à quelle vitesse un serveur peut se faire bruteforcer SSH quand il est sur le port par défaut, autant s’en assurer, même si Fail2ban reste une valeur sur pour limiter la casse. Dans l’exemple on va prendre le port 2222, qui redirigera vers le port 22 du rebond.

Dernier point sur lequel je reviendrai, il faudra de préférence installer netcat, si possible la version OpenBSD, notamment si vous voulez utiliser IPv6 (oui je sais ça peut paraître con, mais parfois des réseaux privés c’est pas mal comme sécurité).

Configuration du serveur final/privé

Donc, dans notre configuration, le serveur final n’est accessible que par le biais d’une adresse IP privée. Pour la partie SSH, vous pouvez, question de cohérence, appliquer les mêmes méthodes que le serveur de rebond. À la limite, si tout le monde est logé à la même enseigne, ça facilite le boulot, on peut automatiser par le biais d’un Puppet/Chef ou d’un Ansible. Donc utilisateur, clé SSH, et évidemment une adresse IP fixe (comme je l’ai dit privée ça suffit, et c’est justement le but).

Configuration des zones DNS

On va avoir besoin de deux noms : l’un pour le rebond, l’autre pour la machine finale. Après avoir tâtonné j’ai pris la décision de réserver la zone en seboss666.ovh aux adresses privées et certains services qui seront publics (comme le git qui sera géré par gogs  je pense), et placer le rebond en public sur seboss666.info. Je vais donc appeler rebond.seboss666.info le serveur sur lequel on se connecte. L’adresse IP associée sera l’IP publique de la connexion de la maison. Pour le serveur qui se trouve derrière, on lui donnera le nom de priv1. Très original, mais ça permet, pour l’exemple, de garder à l’esprit qu’il est accessible uniquement depuis l’intérieur du réseau de l’appartement en temps normal. L’adresse IP qu’on renseignera donc dans la zone seboss666.ovh sera l’adresse privée.

Au final, on aura donc deux enregistrements :

Configuration du client

C’est là que réside réellement la beauté de l’installation. J’avais déjà évoqué quelques possibilités dans un article sur SSH en mode avancé. Il va s’agir ici de réutiliser la technique du fichier ~/.ssh/config, dans lequel on va utiliser une fonction très pratique d’OpenSSH :

Évidemment, si certaines portions sont communes à tous les agents, il est possible d’utiliser un Host * pour faire le taf sans dupliquer les infos inutilement (la partie IdentityFile et suivant entre autres).

La magie du ProxyCommand

ProxyCommand est une commande pratique d’OpenSSH qui va créer au final un tunnel entre notre client et le serveur qu’on lui indique, ici le rebond, et grâce à netcat, lancer les commandes sur le serveur de destination. Comme on cherche à se connecter au serveur, SSH va d’abord lancer un tunnel sur le rebond, puis passer le reste des commandes au travers de ce tunnel, et donc initier une connexion SSH sur le serveur de destination, qui pourtant se trouve sur une IP privée.

Ici, j’ai explicitement utilisé netcat, et si vous avez besoin d’IPv6, il restera peut-être nécessaire (dans sa variante OpenBSD). Mais OpenSSH lui-même embarque un « mode netcat » intégré, dans ce cas la commande sera la suivante :

Et voilà, pour se connecter l’on n’a plus besoin que de saisir ssh priv1.seboss666.ovh et roulez jeunesse.

Ça ne dispense pas d’une bonne sécurité

En effet, les machines sont peut-être assez isolées de l’extérieur, ce n’est absolument pas une raison pour les négliger, ne serait-ce que parce que si vous vous faites trouer le rebond, c’est open bar chez vous.

Celui-ci devra donc faire l’objet d’une surveillance rapprochée si vous voulez éviter les dégâts. Au final il est là principalement pour des raisons de confort, même si ça permet de réduire la surface d’attaque sur votre réseau personnel.

Une autre méthode consisterait à tout laisser privé et se reposer sur un VPN pour ce types de connexions. Ça permet en plus de masquer les protocoles qui passent dans le tunnel, une option plus que recommandée quand les WiFi publics et réseaux mobiles peuvent pratiquer le MiTM à outrance sur des protocoles courants comme le HTTPS (et certainement de plus en plus de SSH reposant sur de vieux algos de chiffrement). Je pense que je vais pas tarder à refaire mes clés SSH pour passer à du chiffrement récent, et peut-être envisager d’isoler les VMs du reste de la maison. Comment, c’est une autre histoire.

Et vous, vous faites comment pour vous connecter à vos différentes machines persos ?

8 Commentaires
Le plus ancien
Le plus récent
Commentaires en ligne
Afficher tous les commentaires
Liandri
Liandri
10/04/2017 18:54

Guacamole pour ma part, qui permet de gérer un peu de tout, pas seulement du SSH. Script complet ici : https://www.chasewright.com/guacamole-with-mysql-on-ubuntu/

Simon
Simon
10/04/2017 21:40

Il est possible d’éviter l’utilisation de netcat:
ProxyCommand ssh -p 2222 rebond.seboss666.info -W « %h:%p »

Simon
Simon
10/04/2017 22:22
Répondre à  Seboss666

en effet, j’ai lu trop vite. Merci de partager régulièrement tes expériences.

libricoleur
libricoleur
11/04/2017 01:54

J’utilise la directive ProxyJump (et l’option -J) disponible sur les clients SSH récents, qui fait la même chose en un peu plus simple. Dans ton cas, ça donnerait :
Host *.seboss666.ovh
ProxyJump seboss666@rebond.seboss666.info:2222

Par contre, je n’utilise pas un vrai nom de domaine pour ça (comme ton .ovh), mais un domaine interne à mon LAN. Si je n’en avais pas j’aurais pu mettre des entrées dans le /etc/hosts ou le ssh_config de ma machine proxy.

Aurélien
13/06/2018 15:17
Répondre à  libricoleur

J’ai juste envie de te dire merci, tu viens de me faire gagner beaucoup de copier-coller !
Ce qui est génial c’est qu’on peut les enchaîner du coup j’ai enfin un fichier de config « propre » : https://twitter.com/LavoWeb/status/1006887619958071298

xhark
13/06/2017 11:07