Archives du mot-clé ssh

SSH comme VPN entre serveurs

Vu le coût des machines virtuelles en ligne, il devient plus accessible d’en avoir plusieurs petites pour différents services plutôt qu’une grosse dédiée proposant de la virtualisation et disposant de multiples IP.

Mais au bout d’un moment, il devient intéressant de faire dialoguer ces serveurs de façon sécurisée.
Comme j’aime me simplifier la vie, j’ai un faible pour les solutions simples qui résolvent plusieurs problèmes.
Donc, une logique VPN permet de protéger toutes sortes de service qui ne doivent plus nécessairement l’être individuellement.

La logique

J’aurais pu implémenter OpenVPN, que j’utilise au boulot, mais mon choix s’est porté sur SSH.
Parce qu’il est tout aussi robuste sinon davantage, qu’il est installé par défaut sous Linux et que je vois son fonctionnement en port-forwarding comme une sécurité granulaire par défaut dans ce cas.

Par défaut, SSH est utilisé pour obtenir une session avec un terminal virtuel à travers un tunnel chiffré. Ce tunnel peut également servir de support de sécurité à des possibilités de transfert de fichier (SCP) voir même au montage d’un système de fichier distant (SSHFS). Il permet également de transférer les requêtes adressées à un port d’un côté du tunnel vers l’autre côté du tunnel, dans un sens ou dans l’autre.

Situation de départ

Nos deux serveurs d’exemple seront:
maitre.domaine.tld qui hébergera
un serveur MariaDB (port 3306)
et un serveur OpenLDAP (port 389).
client.domaine.tld, il doit accéder au SQL et au LDAP du maître.

Génération des clés SSH

Sur le maître, nous allons générer une paire de clés SSH.
Depuis quelques temps, je suis passé de l’algorithme RSA au ECDSA (un peu plus lent, mais semble-t-il un peu plus sûr et moins long.

On choisira un nom spécifique (pas le id_ecdsa proposé par défaut) vpn_ecdsa par exemple
et on ne choisira pas de passphrase (tapez juste <ENTER>).
Dans le cadre de l’automatisation de nos VPNs, cette clé n’a pas de passphrase, il est donc très important que personne d’autre que vous ou le système maître ne puissiez y accéder.

Il faut à présent copier la clé publique sur le serveur client. Pour ce faire, 2 possibilités :

Copie de clé automatique

… ce qui va en fait ajouter la clé publique au fichier /root/.ssh/authorized_keys de l’utilisateur root sur le serveur client. Il faudra évidemment connaître le mot de passe du compte root sur ce serveur.

Copie de clé manuelle

Cette manipulation est également réalisable à la main par un simple copier-coller (rien de chinois donc)Affichez sur le serveur maître, le contenu de la clé publique:

On se rend sur le serveur client, on crée éventuellement le fichier authorized_keys et on y colle la clé affichée par cat ci-dessus :

Sécuriser le client

Si votre système client héberge d’autres utilisateurs il vaut mieux limiter l’usage du port-forwarding à ceux qui en ont besoin et que vous controllez. Je sais qu’il n’est pas recommandé d’utiliser root, mais cela présente aussi des avantages, comme utiliser les ports reconnus (N° de ports inférieurs à 1024).

Usage du port-forwarding

Sur le client, on édite la configuration du serveur ssh

On ajoute :

Restriction de la source des connexions

on fait précéder la clé publique, ajoutée précédemment, de l’instruction de restriction from
le contenu des “” peut être une IP ou un FQDN, si vous avez besoin de plusieurs valeurs, séparez les par une virgule. Il est même possible d’utiliser des  wildcards (? *).

Création du tunnel

Nous retournons sur le serveur maître, créer la connexions SSH.

  • ssh root@client.domaine.tld crée la connexion en tant qu’utilisateur root sur la machine client.domaine.tld
  • -R crée le transfert de port depuis le distant (client) vers l’origine de la connexion (maitre)
  • 389:localhost:389 crée un port local 389 transféré à travers le tunnel vers 389
  • 3306:localhost:3306 idem avec 3306

Cette première connexion est importante, au delà du test, elle va aussi poser la question de l’ajout de l’empreinte du serveur distant, sans cela, l’automatisation future ne sera pas possible.

Une foi cette connexion établie, il est possible, sur le client de se connecter aux 2 ports ci-dessus sur l’adresse locale et d’interroger en fait les services répondant à ces ports sur le serveur maitre.

Maintenir la connexion SSH

Pour faire en sorte que les connexions SSH redémarrent automatiquement en cas de coupure, nous utilisons l’outil autossh. Nous devons donc l’installer, puis la commande devient:

  • -M 0 désactive la fonction de monitoring intégrée (on privilégie les 2 options suivantes).
  • -oServerAliveInterval=60 vérifie l’état de la connexion en envoyant un paquet null toutes les 60 sec. (sans réponse, le serveur considère que la connexion est coupée).
  • -oServerAliveCountMax=3 effectue la vérification de l’opération précédente 3X avant de considérer la perte de connexion.
  • -q active le mode silencieux.
  • -f place la connexion en tâche de fond.
  • -N n’exécute aucune commande sur le serveur distante, très utile dans notre cas puisque seul le port-forwarding nous intéresse.

Les créer automatiquement

Maintenant que nous sommes en mesure de créer cette connexion qui crée le transfert de port distant, et des les maintenir ou les rétablir, il faut les créer automatiquement au démarrage de la machine maître. Le plus simple est sans doute d’ajouter notre commande autossh dans le fichier /etc/rc.local.

ATTENTION: il est très important que la dernière ligne de /etc/rc.local soit exit 0, il faut donc ajouter notre ligne de commande autossh avant cette ligne !

Voilà, a présent, nous avons un tunnel persistant créé automatiquement et permettant à la machine cliente d’accéder aux service SQL et LDAP.