🐧 Edge Linux Debian · diagnostic & exploitation

Chapitre 02
SSH : gérer & sécuriser l'accès

Objectifs du chapitre

1. Clé plutôt que mot de passe

Une authentification par mot de passe est fragile (rejouable, devinable, saisie à chaque connexion) et pénible à automatiser. On lui préfère une paire de clés : une clé privée qui reste sur le laptop, une clé publique qu'on dépose sur l'edge. On génère la paire une fois :

# Sur le laptop — clé Ed25519 (moderne, courte, rapide)
ssh-keygen -t ed25519 -C "eng-laptop maint"
# → crée ~/.ssh/id_ed25519 (privée) et ~/.ssh/id_ed25519.pub (publique)

Protège la clé privée par une passphrase à la génération. Couplée à un ssh-agent (qui la garde déverrouillée le temps de la session), tu tapes la passphrase une fois par jour, pas à chaque connexion — le confort d'un mot de passe unique, la sécurité d'une clé.

On copie ensuite la clé publique sur l'edge. La façon la plus sûre :

laptop:~$ ssh-copy-id maint@192.168.0.10
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s)...
maint@192.168.0.10's password: (dernière fois qu'on le tape !)
Number of key(s) added: 1

La clé publique atterrit dans ~/.ssh/authorized_keys sur l'edge. La prochaine connexion se fait sans mot de passe :

laptop:~$ ssh maint@192.168.0.10
maint@edge-cell12:~$   # entré directement, via la clé

SSH est tatillon sur les permissions. Si ~/.ssh n'est pas en 700 ou authorized_keys pas en 600, sshd ignore silencieusement la clé et retombe sur le mot de passe. Symptôme : « ma clé est bien là mais on me demande quand même le mot de passe ». Vérifie : ls -ld ~/.ssh et ls -l ~/.ssh/authorized_keys côté edge, corrige avec chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys.

2. ~/.ssh/config : arrêter de tout retaper

Taper ssh maint@192.168.0.10 vingt fois par jour, avec des options, est vite fastidieux. Le fichier ~/.ssh/config sur le laptop mémorise tout sous un alias :

# ~/.ssh/config (sur le laptop)
Host edge12
    HostName 192.168.0.10
    User maint
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 30      # ping applicatif : détecte une coupure
    ServerAliveCountMax 3

Désormais un simple ssh edge12 suffit. ServerAliveInterval évite les sessions « gelées » quand le réseau OT hoquette : SSH envoie un petit paquet toutes les 30 secondes et ferme proprement au bout de 3 sans réponse.

Rebondir par un jump host

Souvent, l'edge n'est pas joignable directement depuis le poste bureautique : il faut d'abord passer par une machine de rebond (un bastion ou un serveur de saut sur la DMZ OT). SSH gère ce rebond nativement avec ProxyJump :

# ~/.ssh/config — rebond par un bastion
Host bastion
    HostName bastion.usine.local
    User camille

Host edge12
    HostName 192.168.0.10
    User maint
    ProxyJump bastion            # ← rebond automatique

Un ssh edge12 ouvre alors la session à travers le bastion, en une seule commande. Le trafic reste chiffré de bout en bout ; le bastion ne fait que relayer.

Laptop ssh edge12 Bastion ProxyJump Edge Debian 192.168.0.10 CPU :443 tunnel -L 8443:192.168.0.1:443
Figure 2.1. Rebond et tunnel. Le trait plein : la session ssh passe par le bastion (ProxyJump) jusqu'à l'edge. En pointillé : un tunnel local qui expose, sur localhost:8443 du laptop, le serveur web (443) du CPU — atteignable via l'edge.

3. Tunnels : atteindre ce qui est « derrière » l'edge

L'edge voit des équipements que le laptop ne joint pas directement : le serveur web du CPU S7-1500, une interface d'admin d'un conteneur qui n'écoute que sur localhost, le broker MQTT. Un tunnel local (-L) transporte un port distant jusqu'au laptop :

# Depuis le laptop : exposer le web du CPU (192.168.0.1:443) sur localhost:8443
ssh -L 8443:192.168.0.1:443 edge12
# → puis, dans le navigateur du laptop : https://localhost:8443

Lecture de -L 8443:192.168.0.1:443 : « écoute en local sur 8443, et fais ressortir la connexion depuis l'edge vers 192.168.0.1:443 ». La destination est résolue du point de vue de l'edge : c'est tout l'intérêt.

Pour une interface qui n'écoute que sur la boucle locale de l'edge (fréquent : un dashboard de conteneur bindé sur 127.0.0.1:1880), la cible du tunnel est localhost côté edge : ssh -L 1880:localhost:1880 edge12, puis http://localhost:1880 dans le navigateur du laptop. C'est la façon propre d'accéder à une UI d'admin sans jamais l'exposer sur le réseau OT.

4. Durcir le sshd de l'edge

Une fois les clés en place, on peut resserrer la configuration du serveur SSH. Elle vit dans /etc/ssh/sshd_config sur l'edge. Les réglages qui comptent :

# /etc/ssh/sshd_config (sur l'edge) — extrait durci
PermitRootLogin no              # jamais de login root direct
PasswordAuthentication no       # clés uniquement
KbdInteractiveAuthentication no
AllowUsers maint                # liste blanche de comptes
X11Forwarding no
# (Optionnel) restreindre au segment OT :
# ListenAddress 192.168.0.10

On applique sans couper la session en cours : on teste d'abord la syntaxe, puis on recharge (pas restart) le service.

maint@edge-cell12:~$ sudo sshd -t          # valide la syntaxe, ne dit rien si OK
maint@edge-cell12:~$ sudo systemctl reload ssh
# reload ré-applique la config sans fermer les connexions établies

Ne te verrouille pas dehors. Avant de couper PasswordAuthentication ou de restreindre AllowUsers, garde une deuxième session SSH ouverte en parallèle. Applique le changement dans la première ; vérifie que tu peux ouvrir une nouvelle connexion dans la seconde. Tant que tu n'as pas confirmé qu'une nouvelle session passe, ne ferme pas celle qui marche. Si tu t'es coupé l'accès sur un edge en armoire, la seule issue est un déplacement physique avec écran et clavier.

Sous Debian 12, le service SSH s'active souvent via un socket (ssh.socket) plutôt que le classique ssh.service. Si un systemctl reload ssh semble sans effet, vérifie lequel est réellement actif : systemctl status ssh.socket ssh.service. On détaille sockets et unités au chapitre 3.

5. Quand ça ne passe pas : ssh -v

Une connexion qui échoue est frustrante parce que le message par défaut est laconique. L'option -v (jusqu'à -vvv) déroule chaque étape de la négociation et montre ça bloque.

laptop:~$ ssh -v edge12
OpenSSH_9.2p1 Debian-2, OpenSSL 3.0.11
debug1: Connecting to 192.168.0.10 [192.168.0.10] port 22.
debug1: connect to address 192.168.0.10 port 22: Connection timed out

À chaque symptôme sa cause probable :

Ce que dit -vCause probablePiste
Connection timed outedge éteint, câble/réseau, mauvaise IP, pare-feuping 192.168.0.10, vérifier le VLAN/segment (cf. cours réseau)
Connection refusedon joint la machine mais sshd n'écoute pasle service SSH est arrêté ; port changé ?
Permission denied (publickey)la clé n'est pas acceptéepermissions authorized_keys, bonne IdentityFile
REMOTE HOST IDENTIFICATION HAS CHANGEDl'empreinte de l'hôte a changéedge réinstallé ? sinon, prudence (§6)

6. known_hosts et l'empreinte qui change

SSH mémorise l'empreinte de chaque hôte dans ~/.ssh/known_hosts. Si elle change, il refuse net de se connecter avec un avertissement alarmant :

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Someone could be eavesdropping on you right now (man-in-the-middle attack)!

La cause bénigne et fréquente : l'edge a été réinstallé ou son OS régénéré, donc sa clé d'hôte est neuve. Après avoir confirmé que c'est bien le cas (et pas une usurpation), on retire l'ancienne entrée :

laptop:~$ ssh-keygen -R 192.168.0.10
# retire l'ancienne empreinte ; la prochaine connexion en redemandera confirmation

Ne supprime jamais une entrée known_hosts par réflexe pour « faire taire l'avertissement ». C'est précisément la protection contre l'homme-du-milieu. On ne l'efface qu'après avoir expliqué le changement (edge réinstallé, remplacé) — sur un réseau OT, une empreinte qui change sans raison connue mérite une vraie question.

Côté automate, l'équivalent du « durcissement » existe aussi : le CPU S7-1500 gère des niveaux de protection et des utilisateurs pour son serveur web et l'accès TIA. La logique est la même — moindre privilège, accès nominatif — mais l'edge reste ta porte d'entrée shell, la seule qui te donne un vrai terminal sur la cellule.

Récapitulatif

Exercices

Exercice 1 — De 3 options à un alias

Tu te connectes cent fois par jour avec ssh -i ~/.ssh/id_ed25519 maint@192.168.0.10. Écris l'entrée ~/.ssh/config qui réduit ça à ssh edge12.

Voir la solution
Host edge12
    HostName 192.168.0.10
    User maint
    IdentityFile ~/.ssh/id_ed25519

Chaque option de la ligne de commande a son mot-clé dans le fichier : -iIdentityFile, l'utilisateur → User, l'hôte → HostName. On peut ajouter ServerAliveInterval 30 pour survivre aux hoquets du réseau OT.

Exercice 2 — Voir le web du CPU sans quitter le laptop

Le serveur web du CPU S7-1500 est en https://192.168.0.1, joignable depuis l'edge mais pas depuis le laptop. Ouvre un tunnel pour l'atteindre dans le navigateur du laptop.

Voir la solution
laptop:~$ ssh -L 8443:192.168.0.1:443 edge12

Puis dans le navigateur du laptop : https://localhost:8443. Le 192.168.0.1:443 est résolu depuis l'edge, qui a la route vers l'automate. On garde la session SSH ouverte le temps de la navigation ; la fermer coupe le tunnel. Un certificat auto-signé du CPU déclenchera un avertissement navigateur — normal.

Exercice 3 — Couper le mot de passe sans se couper l'accès

Tu veux passer l'edge en « clés uniquement ». Décris la manœuvre qui garantit que tu ne te retrouveras pas verrouillé dehors.

Voir la solution

1. Vérifier d'abord que la connexion par clé fonctionne (ssh edge12 entre sans demander de mot de passe). 2. Garder cette session ouverte. 3. Éditer /etc/ssh/sshd_configPasswordAuthentication no. 4. Valider : sudo sshd -t. 5. Recharger : sudo systemctl reload ssh. 6. Depuis un second terminal, ouvrir une nouvelle session pour confirmer qu'elle passe. 7. Seulement alors, considérer que c'est bon.

Le point clé : reload ne ferme pas les sessions établies, et on valide la nouvelle config avec une nouvelle connexion avant de lâcher la session de secours. Si la nouvelle échoue, on annule le changement depuis la session encore ouverte.