Sommaire
Avec une connexion Starlink ou 4G on ne peut plus configurer une redirection NAT car il n’y a plus d’adresse IP dite publique. Ou plutôt elle est partagée.
Avec une BOX 4G, il est possible de prendre une adresse IP fixe, mais il y a un surcoût important: On passe à un abo. type pro; Airmob propose ça avec un offre de.. 50GO par mois pour 34€ HT (à ce jour 08/02/2022) Pourtant ils sont très compétitifs…
Avec une abonnement Starlink Entreprise à 44€ par mois on peut bénéficier d’une IP Publique mais avec limitation de 50GO de téléchargement par mois.
Ces deux types de réseau n’ont pas défaut pas d’adresse IP publique dédiée, c’est le principe du CGNAT.
Alors, comment procéder pour accéder de l’extérieur à un appareil réseau situé dans une demeure connectée au réseau Starlink ou 4G? Exemple: Une Webcam ancienne, un régulateur connecté de température, une chaudière piscine en réseau. Si le propriétaire n’est pas chez lui, qu’il est en déplacement ou voyage il ne pourra pas monitorer ses IoT.
Je décris donc dans cet article la technique pour se connecter en local à un service (apache, FTP, SSH, RDP, objets IOT, etc..) sans utiliser la méthode classique de la redirection NAT d’une BOX.
Il ne s’agit pas ici de simplement contrôler un service local, mais de mettre en place un « tunnel » permanent auto-entretenu qui permet d’accéder à n’importe quel service local depuis l’extérieur, sans devoir l’initer physiquement depuis la zone dite « locale ».
NB: Pourquoi les connexions Starlink ou 4G n’ont plus d’IP publique? Plus d’infos ici.
A quoi ça sert?
Loin de se limiter aux deux exemples de cet article (SSH et RDP / bureau à distance), à peut près tous les flux réseaux peuvent cheminer en Reverse SSH: FTP; RTSP; etc. Et bien sûr tous vos I.o.t. (lampes hue, prises connectées; moniteur de PH, que sais-je?). Voir l’exemple plus bas de connexion RDP via Tunnel Reverse SSH.
Je vois un autre avantage: Beaucoup d’I.O.T. ont leurs services Cloud pour accès extérieur, mais au format abonnement payant alors si on a en domotique élargie pas mal de matériel réseau et autant de marques différentes, ça commence à faire cher les abos multiples.
Environnement de travail
Un RaspBerry avec dessus raspberry O.S. en langue Française, muni d’un port réseau, sur lequel un utilisateur en mode sudo est présent. Il n’a pas d’interface graphique. Cet appareil est pour le moment intégré dans mon atelier, connecté au réseau internet lambda (BOX Fibre), le temps de le paramétrer.
Il sera à terme installé dans le réseau local géré par un Starlink ou une BOX 4G. Cet article se base sur un PC sous Ubuntu en place d’un Raspberry (et non je ne vais pas racheter un Raspberry pour ce tuto) cependant les manipulations seront les mêmes (peut-être quelques divergences mineures dans les commandes). NB: Vérifier si l’utilisateur du Ubuntu en local est bien dans le groupe sudo (Administrateur). Dans ce tuto le Raspberry sera nommé SYSTEM_EN_LOCAL et son utilisateur, USER_SYSTEM_LOCAL.
Aucun pare-feu n’est actif sur le PC sous Ubuntu (Enfin.. Raspberry). Celui-ci doit accepter les connexions en SSH par identifiants utilisateur.
Dans le réseau de mon atelier, la BOX contient une règle NAT qui redirige les requêtes entrantes dirigées vers le port 2222 en TCP vers le port 22 TCP du SYSTEM_EN_LOCAL. On peut laisser tel quel une fois le Raspberry intégré dans le réseau CGNAT.
J’ai aussi un PC sous Windows 11 dans ce réseau atelier, pour contrôler le Raspberry en SSH ou SFTP, et manipuler plus facilement avec l’interface graphique de Windows pour -notamment- créer l’instance OVH, etc..
Le principe de nommage sera le même pour l’instance OVH. EX: l’adresse IP de l’instance OVH sera @IP_INSTANCE_OVH. Donc dans vos scripts tapez bien les vrais valeurs et pas les « alias ».
L’Instance OVH n’est pas un prérequis immédiat; Il sera activé et réglé à des étapes précises de cet article.
Sur le SYSTEM_EN_LOCAL
Je contrôle le raspberry en SSH depuis mon PC Windows: Dans une Invite de commande: ssh USER_SYSTEM_LOCAL@IP_SYSTEM_LOCAL et je rentre le mot de passe de session du SYSTEM_EN_LOCAL en acceptant le Fingerprint par YES.
Mise à jour depuis le Terminal:
Installer openssh-server
# Connexion SSH au SYSTEM_EN_LOCAL
ssh USER_SYSTEM_LOCAL@IP_SYSTEM_LOCAL
# Acceptation du fingerprint (Yes)
# Rentrer le mot de passe USER_EN_LOCAL
# Je contrôle désormais le Terminal du SYSTEM_EN_LOCAL
sudo apt update && sudo apt upgrade
sudo apt install openssh-server
sudo systemctl enable ssh.socket
sudo systemctl start ssh.socket
# (pour vérifier l'état d'activazion de SSH)
sudo systemctl status ssh.socket
Créer un jeu de clés privé / publique
Depuis un Terminal: Ne rien mettre en passphrase. La clef publique elle, est automatiquement créée dans le dossier /home/USER_SYSTEM_LOCAL/.ssh/ . Elle a pour nom id_rsa.pub par défaut.
ssh-keygen -t ed25519
Cela créé dans le répertoire .ssh de l’USER_SYSTEM_LOCAL la clé privée (id_ed25519) et la clé publique (id_ed25519.pub).
A ce stade il est bien de vérifier si SSH fonctionne en essayant de se connecter en ssh au plus près du SYSTEM_EN_LOCAL: Il m’est arrivé de ne pas faire cette vérification en continuant la procédure d’installation du reverse ssh jusqu’au bout et lancer le reverse SSH en échec, me demander si tel ou tel pare feu, tel ligne du script, etc faisait défaut alors qu’au moment où je m’arrachais les cheveux, la commande primitive ci-dessous n’aurait même pas abouti:
ssh localhost
Copier la clé publique sur Le PC Windows
Je sors du contrôle en SSH pour revenir attaquer le Raspberry en SFTP afin de rapatrier la clé publique dans le Bureau de mon utilisateur Windows
# Redémarrage du Raspberry pour appliquer les MAJ
sudo reboot
# Quitter controle terminal Raspberry
exit
# Placer le dossier actif de l'invite de commande Windows sur le Bureau
# %USERNAME% est à taper tel quel (variable contenant le nom d'utilisateur WIndows actif)
CD /D C:\Users\%USERNAME%\
# Attendre que le Raspberry soit démarré puis:
sftp USER_SYSTEM_LOCAL@IP_LOCAL
get /home/USER_LOCAL/.ssh/id_ed25519.pub pubkeylocal.txt
bye
En cheminant avec l’explorateur sous Windows, vous verrez dans C:\Users\VOTRE_NOM_D’UTILISATEUR_WINDOWS\ la clé publique de SYSTEM_EN_LOCAL copiée en tant que fichier texte pubkeylocal.txt.
On garde la fenêtre de l’explorateur ouvert pour la suite. Direction: création et paramétrage de l’Instance OVH.
Instance OVH
Création de l'instance OVH en ligne et renseignement Clé SSH
S’identifier sur OVH puis onglet Public Cloud > Créer Instance pour env. 5€ HT/mois avec le modèle DISCOVERY; Le moins onéreux vu qu’il s’agit de ne traiter que du flux réseau léger (SSH et RDP). Image choisie Ubuntu, sans réseau privé ni disque additionnel. C’est ici: Créer instance OVH.
Lors de la création de l’instance, une étape permet de renseigner la clef publique créée précédemment. Ouvrir le fichier texte pubkeylocal.txt, copier le contenu, et collez dans le champs idoine.
Si on a loupé cette étape, on est pratiquement obligé de: 1) créer une nouvelle clé public sur SYSTEM_EN_LOCAL . 2) Supprimer puis Recréer une instance car le mode « réinstallation » ne contient pas l’étape d’ajout de clef publique…
En Configuration Réseau il faut choisir Mode Public.
On va pouvoir se connecter sans mot de passe sur l’instance OVH, depuis SYSTEM_EN_LOCAL. On verra ça plus bas.
PS: Pour l’instant Ne pas configurer de Pare-Feu sur l’espace OVH (pour info c’est dans Hosted Private Cloud > Network puis IP et clique sur 3 petits points en regard de l’@IP de l’instance OVH). Dans Ubuntu sur l’Instance OVH il n’y a pas par défaut de Firewall software configuré.
NB: Cette configuration de l’Instance OVH créé automatiquement un utilisateur administrateur (sudo en language Linux) nommé ubuntu (c’est sans doute différent si on créé une instance Debian ou autre, pas testé).
Connexion SSH sans mot de passe à l'Instance OVH depuis SYSTEM_EN_LOCAL
NB: Par défaut le nom de USER_INSTANCE_OVH est ubuntu. De toute façon cette information est visible dans l’espace OVH en cliquant sur les 3 petits points à droite du nom de l’instance puis « Détails de l’instance ».
On y trouve l’adresse de notre instance OVH, de type ubuntu@IP_INSTANCE_OVH.
Alors là ça va commencer à être un gymkhana cérébral: On va contrôler en SSH le Terminal du SYSTEM_EN_LOCAL comme auparavant, ce qui va permettre de contrôler le terminal de L’Instance OVH !
Je pourrais prendre son contrôle directement depuis Windows mais l’effort d’abstraction demandé va faciliter la suite des opérations.
# Depuis la ligne de commande Windows:
ssh USER_SYSTEM_LOCAL@IP_EN_LOCAL
# Je controle alors le Terminal SYSTEM_EN_LOCAL
ssh -i ~/.ssh/id_ed25519 ubuntu@IP_INSTANCE_OVH
# Je controle en cascade le Terminal de l'Instance OVH
Un message dit de valider la connexion en tapant « Yes » ou « Fingerprint »: taper yes. Cette sécurité n’apparaît qu’une seule fois. (Valider la connexion en tapant « Fingerprint » est plus sécurisée, mais elle impose de copier-coller l’empreinte digital de la clé SSH dans le terminal, en plus si vous avez suivi les étapes de ce tutoriel, je ne l’ai pas proposé: cette suite de chiffres et de nombres apparait après la commande ssh-keygen pour info).
On est désormais connecté en SSH sur l’Instance OVH: Les commandes ne s’exécutent plus ni sur l’invite de commande Windows, ni même sur le terminal du SYSTEM_EN_LOCAL mais sur le Terminal l’instance OVH (tapez whoami (qui suis-je) vous verrez).
PS: C’est déroutant, mais à partir de là il faut penser comme si on était physiquement sur le Terminal de l’Instance OVH.
Je mets toutes les chances de mon côté pour éviter des soucis de compatibilité en mettant à jour l’Instance OVH.
sudo apt update && sudo apt ugrade
sudo reboot
Je me reconnecte en SSH à l’instance une fois celle-ci redémarrée.
ssh -i ~/.ssh/id_ed25519 ubuntu@IP_INSTANCE_OVH
Je renseigne par sécurité un mot de passe pour l’utilisateur ubuntu (au cas où je me tromperais dans les étapes d’autentification SSH). J’en profite pour changer la configuration du clavier en mode azerty. Pas d’inquiétude: Les commandes en SSH se font bien en AZERTY, mais pas depuis la console VNC de contrôle de l’instance sur OVH Cloud.
sudo passwd ubuntu
# Taper le mot de passe choisi deux fois pour confirmation
sudo dpkg-reconfigure keyboard-configuration
# Choisir:
# Generic 105-key PC
# French
# French - French (AZERTY)
# The default for the keyboard layout
# No compose key
sudo systemctl restart keyboard-setup
De là même façon qu’on a créé un jeu de clef pour authentifier la connexion du SYSTEM_EN_LOCAL vers l’Instance OVH, on va créer un autre jeu de clefs depuis le terminal de l’Instance OVH permettant l’autentification sur le système en local. Passez les étapes comme on a fait pour créer la clef dans le SYSTEM_EN_LOCAL.
ssh-keygen -t ed25519
exit
Là aussi ne rien mettre en Passphrase. Puis exit pour quitter le Terminal de l’Instance OVH et repasser au contrôle du SYSTEM_EN_LOCAL. On va se connecter à l’Instance OVH, cette fois-ci avec à la commande SFTP pour récupérer la clé SSH publique.
Rapatrier la clef publique de l’Instance OVH sur le bureau de l’utilisateur du SYSTEM_EN_LOCAL.
bye pour fermer le tunnel SFTP (un peu plus sympa que exit pour fermer le tunnel SSH). PS: Si le SYSTEM_EN_LOCAL est installé en langue Anglaise, remplacer Bureau par Desktop.
sftp -i ~/.ssh/id_ed25519 ubuntu@IP_INSTANCE_OVH
get /home/ubuntu/.ssh/id_ed25519.pub /home/USER_SYSTEM_LOCAL/Bureau/pubkeyinstance.txt
bye
Installer la clé publique de l'Instance OVH sur le SYSTEM_EN_LOCAL
PS: J’espère que votre don d’ubiquité n’est pas en surchauffe; Nous somme revenus à ce stade au contrôle du Terminal du SYSTEM_EN_LOCAL.
Créer avec TOUCH un fichier nommé authorized_keys dans le dossier .ssh. Le signe ~ représente le dossier actif de l’utilisateur du terminal c-a-d /home/USER_SYTEM_LOCAL/.
touch ~/.ssh/authorized_keys
Enfin on copie le contenu de pubkeyinstance.txt dans le fichier nouvellement créé authorized_keys avec la commande CAT. l’option >> permet d’ajouter du contenu sans effacer une éventuelle clé publique déjà existante et placer le contenu à la suite, sur une nouvelle ligne.
cat ~/Bureau/pubkeyinstance.txt >> ~/.ssh/authorized_keys
Par sécurité on s’assure que les droits sur les fichiers et dossiers nécessaire à la connexion SSH sont corrects.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Configurer le serveur SSH sur l'Instance OVH
Du coup il faut se reconnecter en SSH à l’instance OVH pour l’a contrôler:
ssh -i ~/.ssh/id_ed25519 ubuntu@IP_INSTANCE_OVH
sudo nano /etc/ssh/sshd_config
Cela lance l’éditeur de texte en ligne de commande nano (PS: là aussi le fichier sshd_config est au bout du compte un fichier texte). Se déplacer dans le texte avec les touches fléchées. Modifier les informations ainsi en décommentant si nécessaire (c-a-d en retirant le signe #):
- GatewayPorts yes (autorise la liaison d’un port à une adresse IP ou DNS).
- AllowTCPForwarding yes (permet la redirection un port vers un autre).
sudo sshd -t
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
exit
Installer autossh sur le SYSTEM_EN_LOCAL et le configurer
On s’assure de contrôler le Terminal du SYSTEM_EN_LOCAL et on installe autossh
sudo apt install autossh
On vérifie que la connexion autossh abouti avec ce test:
autossh -v -i ~/.ssh/id_ed25519 -N -R *:22222:localhost:22 ubuntu@IP_INSTANCE_OVH
Si la sortie verbeuse (induite par la commande -v) imprime sur le Terminal ce genre de logs, c’est bon signe!
S'identifier en tant que super utilisateur ROOT sur le SYSTEM_EN_LOCAL
Cela a va être nécessaire pour créer un service à démarrage automatique.
Taper su (pour changer de session sous le terminal et passer sur terminal root) et renseignez le mot de passe que vous avez choisi pour ce dernier: Nous sommes désormais en mode root et pouvons créer un service autossh à démarrage automatique.
sudo passwd root
# Rentrer mot de passe du USER_LOCAL
# Choisir un mot de passe pour root (avec confirmation)
su
# Renseigner le mot de passe root nouvellement défini
# Et là on peut créer et éditer le fichier config du service autossh
nano /etc/systemd/system/autossh.service
Remplir le nouveau fichier créé par nano ainsi:
[Unit]
Description=Tunnel permanent SSH
After=network-online.target
Wants=network-online.target
[Service]
User=USER_SYSTEM_LOCAL
WorkingDirectory=/home/USER_SYSTEM_LOCAL
Environment="AUTOSSH_LOGFILE=/home/USER_SYSTEM_LOCAL/Bureau/autossh.log"
Environment="AUTOSSH_GATETIME=0"
ExecStart=/usr/bin/autossh -M 0 -i /home/USER_SYSTEM_LOCAL/.ssh/id_ed25519 -N -R *:22222:localhost:22 ubuntu@IP_INSTANCE_OVH -o ServerAliveInterval=10 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes
Restart=always
RestartSec=10
StartLimitInterval=0
StartLimitBurst=0
KillMode=process
SuccessExitStatus=0 255
[Install]
WantedBy=multi-user.target
Comme auparavant CTRL + X pour quitter, et sauvegarder (Y ou O)
Explications:
- User= L’exécution de autossh est faite sous le compte USER_SYSTEM_LOCAL. Par sécurité je précise le dossier actif avec l’option WorkingDirectory pointée sur le dossier personnel de USER_SYSTEM_LOCAL
- AUTOSSH_LOGFILE= Un log d’autossh est créé sur le bureau pour suivi des dysfonctionnements éventuels.
- AUTOSSH_GATETIME 0= Permet d’ignorer la première erreur ssh: Utile ici vu que autossh s’exécute au démarrage de l’instance OVH et que SSH n’a pas le temps de se lancer si tôt.
- -M 0= Désactivation du port d’écoute de autossh pour détecter la bonne connexion, mais les options Serverxxx servent déjà à gérer cet aspect là de vérification.
- ServerAliveInterval et ServerAliveCountMax = Autossh vérifie si le tunnel est ouvert en envoyant un signal toutes les 10 secondes (Cf option -M). Si le tunnel ne répond pas, il essaie encore deux fois (donc 3 tentatives au total) par intervalle de 10 secondes. Si , au bout des ces 3 essais séparés par 10 secondes d’attente les signaux ne reviennent pas, autossh reboot le tunnel. Du côté de l’instance OVH nul besoin d’intaller autossh; le protocole SSH de l’instance comprend ces signaux par défaut.
- -i= Pour indiquer le chemin vers la clef privée. Normalement la clef idoine utilisée par défaut est celle de l’utilisateur indiqué en ligne « User », mais je laisse par précaution.
- -N= Dit à autossh de ne faire que rediriger les ports (ici 22222 vers 22). J’ai choisit le port d’entrée 2222 au hasard, de peur d’utiliser directement le port 22 requis pour le contrôle Reverse SSH futur du SYSTEM_EN_LOCAL.
- -R= Configuration de la redirection en reverse-ssh pour créer un tunnel « distant » (à contrario d’un tunnel local sur le même réseau). NB: Ici le reverse-ssh est sommairement configuré pour atteindre n’importe quel appareil informatique réseau en local (localhost) qui écoute sur le port 22222, mais s’il y a plusieurs appareils en local, et que l’on tient à atteindre celui qui fait tourner un service qu’on souhaite rendre accessible depuis l’extérieur, rien n’empêche de le faire. Ex: -R *:22222:192.168.1.25:22 où 192.168.1.25 est l’@IP de cet autre appareil.
- localhost: en terme simple localhost veut dire « l’adresse IP de cet ordinateur ». J’aurais pu rentrer l’@IP du SYSTEM_EN_LOCAL mais utiliser l’alias localhost me permettra si besoin de changer l’@IP du SYSTEM_EN_LOCAL sans retoucher le script.
- Signe * comme All, pour l’interface réseau: on met en écoute le port 22222 sur toutes les interfaces réseau du SYSTEM_EN_LOCAL (précaution au cas où ce dernier aurait plusieurs interfaces réseau -virtuelles ou pas).
- ubuntu@IP_INSTANCE_OVH= C’est les identifiants de connexion SSH pour se connecter à l’instance OVH depuis le Système en local.
- Les options Restart servent à la résilience du service autossh.service: Si pour une raison quelconque (processus tué, bug passager) autossh.service est arrêté, ce service est relancé, et encore relancé indéfiniment toutes les 10 s si les tentatives précédentes ont échouées.
Activer le service autossh au démarrage, et débogage au cas où
# S'assurrer d'être en mode Root
# Recharger les services
systemctl daemon-reload
systemctl restart ssh.socket
# Activer le démarrage automatique du service autossh
systemctl --now enable autossh.service
# Démarrer le service autossh sur le champ
systemctl start autossh.service
# Quitter le mode Root, pour revenir
# au Terminal du SYSTEM_EN_LOCAL en tant
# qu'USER_EN_LOCAL (PRENEZ UN CACHET)
exit
Pour connaitre l’état du tunnel SSH (ou plutôt reverse tunnel ssh) sur le SYSTEM_EN_LOCAL, on peut utiliser tail sous terminal. Cela ouvre un terminal avec le log de autossh avec défilement automatique (option -f pour défilement auto).
NB: Si tail ne se lance pas, il faut installer en ligne de commande les utilitaires Ubuntu: apt-get install coreutils .
tail -f ~/Bureau/autossh.log
Si aucun message d’erreur apparaît c’est bon signe.
NB: Touche CTRL + C dans le Terminal pour quitter le log à défilement automatique permis par la commande tail.
En cas de soucis de connexion, revoir la config. du script autossh.service avec l’éditeur nano; Mais d’abord arrêtez le service autossh.
sudo systemctl stop autossh.service
# Retouch du script avec nano ..
sudo systemctl daemon-reload
sudo systemctl start ssh.socket
sudo systemctl start autossh.service
NB: Normalement les droits de l’utilisateur par défaut suffisent pour stopper et redémarrer ce service, le cas contraire essayez en mode Root.
Pseudo-Faq
Pourquoi on installe le serveur SSH (openssh-server) sur le SYSTEM_EN_LOCAL? parce qu’il est non joignable de l’extérieur en temps normal: C’est donc lui qui doit faire tourner le serveur SSH + autossh et envoyer automatiquement et régulièrement à l’instance OVH la config. du tunnel pour ne pas que le tunnel se ferme.
Pourquoi pas de pare-feu ni de fail2ban? La configuration est assez difficile comme ça; On verra à la suite comment faire. Concernant l’outil Fail2ban il n’est utile que pour les attaques brute force avec identifiants… Comme la connexion SSH ne pourra (voir suite article) se faire qu’avec clefs SSH il est inutile.
C’est quoi ce port 22222 dans le script autossh.service? Le script autossh.service ordonne à l’Instance OVH la chose suivante: Si un PC « externe » envoie une requête sur le port 22222 du localhost (pour rappel c’est l’adresse IP du SYSTEM_EN_LOCAL) elle doit être redirigée sur le port 22 du SYSTEM_EN_LOCAL par l’Instance OVH. On comprend alors qu’il est très possible de ne pas rediriger ce flux vers le SYSTEM_EN_LOCAL mais vers l’@IP + Port d’un autre appareil du réseau local CGNAT dont fait partie le SYSTEM_EN_LOCAL, du moment que le port de cet autre appareil en local est ouvert aux flux entrants.
Oui mais l’instance OVH ne connait pas les @IP du réseau local Starlink / Box 4G? D’accord mais le SYSTEM_EN_LOCAL oui.. Il fera le nécessaire.
Se connecter en SSH via autossh au SYSTEM_EN_LOCAL depuis PC tiers
Ca y est le Raspberry est fièrement installé au sein du réseau CGNAT géré par Starlink ou BOX 4G. Je n’ai pas eu besoin d’attribuer une adresse IP fixe au Raspberry puis de modifier le fichier autossh.service pour l’a rentrer en lieu et place de la mention localhost, vu que localhost est une variable qui prend automatiquement la valeur de l’@IP du SYSTEM_EN_LOCAL.
Ce chapitre décrit la fonctionnalité la moins intelligible du Reverse SSH: Contrôler en Terminal SSH le Raspberry au travers.. D’un tunnel SSH. Mais plus loin dans l’article, je détaillerais des mises en place plus attendues et simples en l’effet de la mise en place d’un Contrôle bureau à distance RDP, et d’un serveur web Apache.
Rappel: J’ai tapé exit auparavant pour sortir du contrôle du Terminal de SYSTEM_EN_LOCAL.
Depuis mon PC sous Windows 11 (Mais ce serait pareil avec un autre PC sous Windows ou Linux placé dans n’importe quel réseau externe) depuis lequel je souhaite contrôler le SYSTEM_EN_LOCAL en SSH, je tape depuis la ligne de commande.
ssh-keygen -t ed25519
Cela crée dans le dossier utilisateur de Windows un dossier caché nommé .ssh dans lequel se trouve les fichiers id_ed25519 et id_ed25519.pub.
Je me rends dans l’interface graphique de Windows sans fermer le terminal, et copie le contenu de C:\Users\UTILISATEUR_PC_WINDOWS\.ssh\id_ed25519.pub en l’ouvrant avec l’éditeur de texte.
Je vais contrôler en SSH le SYSTEM_EN_LOCAL via le tunnel de l’Instance OVH. Et non je ne me suis pas trompé en tapant USER_SYSTEM_LOCAL : Autossh, exécuté sur le SYSTEM_EN_LOCAL a autorisé l’instance OVH à « utiliser » le compte exécutant Autossh.
ssh -p 22222 USER_SYSTEM_LOCAL@IP_INSTANCE_OVH
J’accepte le Fingerprint (Yes). Le mot de passe de l’utilisateur du SYSTEM_EN_LOCAL m’est systématiquement demandé, on va changer cela.
Je tape dans le Terminal nano ~/.ssh/authorized_keys pour éditer le-dit fichier
nano ~/.ssh/authorized_keys
Avec le clavier, je me positionne en bas à la ligne de la clé publique existante de l’Instance OVH, et je clique droit pour renseigner le contenu précédemment récupéré du fichier id_ed25519.pub sous Windows 11. Il n’y a pas de menu contextuel: Le clique droit copie directement la clé publique de mon Windows 11 (après tout c’est un terminal).
Si votre PC tiers est sous un Linux sans interface graphique, c’est que vous cherchez vraiment les comp vous pouvez réitérer en adaptant la suite de commandes vues plus haut, à coup de touch, cat, et autre joyeusetés.
exit pour sortir du terminal, puis de nouveau ssh -p 22222 USER_SYSTEM_LOCAL@IP_INSTANCE_OVH.
Le mot de passe n’est plus demandé!
ssh -i ~/.ssh/id_ed25519 -p 22222 USER_SYSTEM_LOCAL@IP_INSTANCE_OVH
Serveur Web Apache sur SYSTEM_EN_LOCAL
Configurer un tunnel pour contrôler en SSH le SYSTEM_EN_LOCAL depuis l’extérieur c’est bien, mais on peut très bien monter un serveur Web; serveur de fichier ou synchro; de backup… Que sais-je? Ici exemple avec un serveur Web Apache.
Prérequis: Installer un serveur apache2 sur le SYSTEM_EN_LOCAL (tuto ici) https://www.digitalocean.com/community/tutorials/how-to-install-the-apache-web-server-on-ubuntu-20-04-fr.
Créer un nouveau fichier de configuration nommé autossh_apache.service en le copiant d’après le modèle précédent (par commodité) et le modifier:
su
cp /etc/systemd/system/autossh.service /etc/systemd/system/autossh_apache.service
nano /etc/systemd/system/autossh_apache.service
On retrouve ce qui était précédemment sur le fichier de config « autossh.config » puis on modifie la partie redirection de port. Apache tourne par défaut sur le port 80 du SYSTEM_EN_LOCAL. On décide que le port que l’Instance OVH devra rediriger vers le port 80 sera le port 8080. Voilà à quoi le fichier autossh_apache.service doit ressembler.
[Unit]
Description=Tunnel reverse SSH accès Apache
After=network-online.target
Wants=network-online.target
[Service]
User=USER_SYSTEM_LOCAL
WorkingDirectory=/home/USER_SYSTEM_LOCAL
Environment="AUTOSSH_LOGFILE=/home/USER_SYSTEM_LOCAL/Bureau/autossh_apache.log"
Environment="AUTOSSH_GATETIME=0"
ExecStart=/usr/bin/autossh -M 0 -i /home/USER_SYSTEM_LOCAL/.ssh/id_ed25519 -N -R *:8080:localhost:80 ubuntu@IP_INSTANCE_OVH -o ServerAliveInterval=10 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes
Restart=always
RestartSec=10
StartLimitInterval=0
StartLimitBurst=0
KillMode=process
SuccessExitStatus=0 255
[Install]
WantedBy=multi-user.target
Pour rappel: CTRL + X pour sortir; Y ou O pour sauvegarder le fichier autossh_apache.service, ensuite on relance les services modifiés. Enfin, avec la commande exit on quitte le mode Root.
su
# On renseigne le mot de passe Root
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
systemctl --now enable autossh_apache.service
systemctl start autossh_apache.service
exit
Après coup le serveur Web sur le SYSTEM_EN_LOCAL sera disponible en tapant dans un navigateur: IP_INSTANCE_OVH:8080.
Exemple: 55.128.76.242:8080 à taper dans le champ URL de votre navigateur Web préféré.
Bureau à distance Windows 10 RDP avec Reverse SSH et autossh
J’ai montré comment accéder à des services sur le SYSTEM_EN_LOCAL. Mais il est possible d’accéder depuis l’extérieur à d’autres services hébergés sur d’autres machines du réseau local sous Starlink / BOX 4G. Exemple ici avec un PC sous Windows 10 dans le réseau CGNAT, auquel on souhaite accéder en Remote Desktop Protocol.
On active sous Windows 10 le bureau à distance en laissant le port par défaut 3389: Paramètres Windows 10 > Système > Bureau à distance. On note son @IP locale (ici je vais utiliser l’alias @IP_WIN10, à remplacer dans les scripts par la vrai @IP).
Normalement, une règle de pare-feu Windows 10 autorisant les connexions entrantes sur le port 3389 est automatiquement créée; Attention si vous avez une solution de sécurité autres que Windows Defender qu’elle prenne bien en compte l’autorisation.
On recréé un fichier de config: autossh_rdp.service (en copiant le modèle comme précédemment).
su
cp /etc/systemd/system/autossh.service /etc/systemd/system/autossh_rdp.service
nano /etc/systemd/system/autossh_rdp.service
Et là aussi on modifie la redirection (option -R) MAIS on va y renseigner l’adresse IP du Windows 10 au lieu de localhost !
Exemple: Dans le script ci-dessous, *:22216:IP_WIN10:3389 serait en réalité *:22216:192.168.1.25:3389
Je me répète= CTRL + X pour sortir; Y ou O pour sauvegarder le fichier autossh_rdp.service. Et ensuite relance des services.
[Unit]
Description=Tunnel reverse SSH accès RDP
After=network-online.target
Wants=network-online.target
[Service]
User=USER_SYSTEM_LOCAL
WorkingDirectory=/home/USER_SYSTEM_LOCAL
Environment="AUTOSSH_LOGFILE=/home/USER_SYSTEM_LOCAL/Bureau/autossh_rdp.log"
Environment="AUTOSSH_GATETIME=0"
ExecStart=/usr/bin/autossh -M 0 -i /home/USER_SYSTEM_LOCAL/.ssh/id_ed25519 -N -R *:22216:IP_WIN10:3389 ubuntu@IP_INSTANCE_OVH -o ServerAliveInterval=10 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes
Restart=always
RestartSec=10
StartLimitInterval=0
StartLimitBurst=0
KillMode=process
SuccessExitStatus=0 255
[Install]
WantedBy=multi-user.target
su
# De nouveau, rentrer mot de passe Root
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
systemctl --now enable autossh_rdp.service
systemctl start autossh_rdp.service
exit
Depuis un autre PC Je cherche « Connexion bureau à distance ». L’appli apparait et j’y renseigne les infos suivantes (l’@IP de l’instance OVH est cachée par confidentialité). En se connectant, accepter le certificat (il n’est pas validé par une autorité de confiance).
Exemple ici @IP_INSTANCE_OVH:22216 serait en réalité 55.128.76.242:22216
PS: Que les malveillants ne perdent pas de temps à essayer de se connecter à mon Instance OVH; Cela fait bien longtemps que j’ai changé son adresse IP.
Enième PS: J’aurais pu rentrer les différentes redirections dans un seul fichier autossh.service, mais j’ai trouvé plus claire de créer pour chaque service les fichiers autossh requis.
L’alternative compacte aurait l’apparence suivante (Extrait).
ExecStart=/usr/bin/autossh -M 0 -i /home/USER_SYSTEM_LOCAL/.ssh/id_ed25519 -N -R *:22222:localhost:22 -R *:8080:IP_SERVEUR_APACHE:80 ubuntu@IP_INSTANCE_OVH -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes
En l’état, le script autossh n’autorise pas l’escamotage des IPs par des noms d’hôtes DNS (à part le tout lettré localhost mais c’est un cas à part: Il s’agit là d’une variable malgré le sentiment premier).
Interdire la connexion par mots de passe sur Instance OVH
Là par contre il faut faire attention; En effet si on perd la clé SSH, ou qu’une mise à jour casse quelque chose, vous n’aurez plus accès à l’Instance OVH même par identifiants… Sauf à passer par la console VNC de votre espace OVH: Public Cloud > Instances > Clique droit sur les 3 petits points à droite du n° de l’Instance > Détails de l’Instance> Onglet Console VNC.
Heureux alors celui qui aura pris de temps de passer la langue du clavier de la console VNC OVH en mode AZERTY comme je l’ai présenté 3KM plus haut; Il pourra éditer plus facilement le fichier de config sshd_config pour retirer la protection star de ce chapitre.
Ici je prends le contrôle en SSH de l’Instance OVH depuis un PC quelconque; Je rentre une dernière fois le mot de passe de l’utilisateur ubuntu de l’Instance, puis je modifie le fichier sshd_config pour interdire le login via identifiants.
ssh ubuntu@IP_INSTANCE_OVH
sudo nano /etc/ssh/sshd_config
sshd_config ouvert, on modifie et décommente et / ou règle les entrées citées:
- PasswordAuthentification no
Comme toujours CTRL+X pour sortir, Y ou O pour sauvegarder le fichier, puis Entrée, enfin relancer SSH, puis exit. Après cela, Je ne pourrais plus relancer une connexion SSH depuis un PC non authentifié par jeu de clé Privé / Publique vers l’Instance OVH.
Je pourrais exagérer la sécurisation en contraignant de même le SYSTEM_EN_LOCAL mais la barrière quasi-infranchissable de cette protection sur l’Instance OVH me semble amplement suffisante pour l’heure (on reverra la config quand les pirates utiliseront un ordinateur quantique avec assez de QBits pour casser le chiffrement ed25519 basé sur les courbes elliptiques…)
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
exit
Reverse SSH utile sur une connexion internet classique?
Sur BOX 4G / Starlink on n’a pas le choix pour accéder à certains services que d’utiliser Reverse SSH. Mais sur BOX « Classique » quel intérêt ? :
- Stabilité: On ne craindra pas un reset ou changement de BOX qui casse la redirection NAT… Il n’y en pas! On peut se dire que -si on peut ouvrir un Terminal SSH en Reverse SSH- un port entrant est donc ouvert sur la BOX en NAT.. Mais non (J’ai testé).
- Sécurité: On peut traverser un pare-feu matériel local tout en verrouillant ce dernier sur une sécurité maximale.
- Sécurité: très restrictif car une clé ED25519 est plus difficile à casser qu’une clé RSA, déjà qu’il faut des millions d’années pour du RSA, ça commence à devenir un peu longuet.
- Confidentialité: Tout ce qui passe par le tunnel SSH est chiffré.
- White Hack: Sur une BOX gérée par un prestataire qui ne veut pas révéler les identifiants d’administration…
- Performance: Pas besoin de créer une interface réseau virtuelle comme avec la solution VPN, et le SSH ne tient qu’à quelques lignes de commande intrinsèquement low-usage.
- Flegmatite aigüe: Pas de solution type No-IP, Dyn DNS à mettre en place.