Chapitre 1215 minIntermédiaire
SSH : connexion par clé, configuration et durcissement
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- expliquer comment SSH authentifie le serveur et l'utilisateur ;
- créer une paire de clés et se connecter sans mot de passe ;
- configurer le client : alias, rebond par un bastion, transferts, tunnel ;
- durcir le serveur OpenSSH sans se bloquer dehors.
4 exercices corrigés1 schéma
SSH (Secure Shell) est le protocole qui permet d'ouvrir une session en ligne de commande sur une machine distante, à travers une connexion chiffrée, et d'y transférer des fichiers. Ce chapitre explique comment SSH vérifie l'identité du serveur et celle de l'utilisateur, comment créer une paire de clés et s'en servir à la place d'un mot de passe, comment configurer le client (alias, rebond par un bastion, transferts) et comment durcir le serveur OpenSSH de Debian 13.
Le principe
Le serveur OpenSSH (sshd) écoute sur le port TCP 22. Le client (ssh, présent sur Linux, macOS et Windows 10 et 11) s'y connecte. Une connexion se déroule en trois temps :
- Négociation et chiffrement. Client et serveur choisissent leurs algorithmes et établissent une clé de session. OpenSSH 10, celui de Debian 13, utilise par défaut un échange hybride,
mlkem768x25519-sha256, conçu pour résister aussi aux futurs ordinateurs quantiques. - Authentification du serveur. Le serveur prouve son identité avec sa clé d'hôte (
/etc/ssh/ssh_host_ed25519_key). La première fois, le client affiche son empreinte et demande si tu la reconnais ; ensuite, il la retrouve dans~/.ssh/known_hostset refuse la connexion si elle a changé. - Authentification de l'utilisateur, par mot de passe ou par clé.
clambert@poste-admin:~$ ssh clambert@192.168.10.225
The authenticity of host '192.168.10.225 (192.168.10.225)' can't be established.
ED25519 key fingerprint is SHA256:p3Vb0c1K9xYkQ7o5Hc2mWq8tLr4nZs6fJd1uEa0iGbM.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Ne réponds pas yes par réflexe : compare l'empreinte avec celle du serveur, lue sur sa console (ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub) ou dans la documentation de l'infrastructure. C'est ce contrôle qui empêche un attaquant placé entre toi et le serveur de se faire passer pour lui.
L'authentification par clé
Une paire de clés est faite d'une clé privée, qui reste sur ton poste, protégée par une phrase de passe, et d'une clé publique, que tu déposes sur chaque serveur dans ~/.ssh/authorized_keys. À la connexion, le serveur envoie un défi ; le client le signe avec la clé privée ; le serveur vérifie la signature avec la clé publique. La clé privée ne quitte jamais le poste, et rien de ce qui circule ne permet de la retrouver.
Créer la paire, sur le poste d'administration :
clambert@poste-admin:~$ ssh-keygen -t ed25519 -C "clambert@poste-admin"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/clambert/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/clambert/.ssh/id_ed25519
Your public key has been saved in /home/clambert/.ssh/id_ed25519.pub
Le type Ed25519 est le choix par défaut d'OpenSSH depuis la version 9.5 : clés courtes, rapides et sûres. RSA reste possible pour les vieux équipements, avec au moins 3072 bits conseillés (-t rsa -b 4096) ; DSA n'est plus pris en charge par OpenSSH 10. La phrase de passe chiffre la clé privée sur le disque : un vol du fichier ne suffit pas à l'utiliser.
Déposer la clé publique sur le serveur, en s'y connectant une dernière fois avec le mot de passe :
ssh-copy-id clambert@192.168.10.225
ssh-copy-id ajoute la clé à ~/.ssh/authorized_keys sur le serveur et règle les droits. Depuis Windows, où cette commande n'existe pas, on envoie la clé par un tube :
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | ssh clambert@192.168.10.225 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Ne pas retaper la phrase de passe à chaque connexion : l'agent SSH la garde en mémoire pour la session. eval "$(ssh-agent)" le lance s'il ne tourne pas, ssh-add y charge la clé, ssh-add -l liste les clés chargées.
Le client SSH au quotidien
Le fichier ~/.ssh/config évite de retaper adresses, comptes et options :
# ~/.ssh/config du poste d'administration
Host bastion
HostName 192.168.10.210
User clambert
Host srv-web
HostName 192.168.10.225
User clambert
ProxyJump bastion
Host srv-journaux
HostName 192.168.10.180
User clambert
ProxyJump bastion
Host *
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
ssh srv-web suffit alors. ProxyJump fait passer la connexion par le bastion : le client ouvre une session sur bastion, puis, à travers elle, une seconde connexion chiffrée de bout en bout jusqu'à srv-web. Le pare-feu n'a plus qu'à autoriser SSH vers les serveurs depuis le bastion. En une commande, sans fichier : ssh -J clambert@192.168.10.210 clambert@192.168.10.225. Le rôle du bastion dans l'architecture est expliqué dans le cours Cybersécurité des infrastructures.
Transférer des fichiers. Trois outils passent par SSH :
scp rapport.pdf srv-web:/tmp/ # copier vers le serveur
scp srv-journaux:/srv/journaux/export.csv . # copier depuis le serveur
sftp srv-web # session interactive : ls, cd, get, put
rsync -avz --delete site/ srv-web:/srv/www/suivi/ # synchroniser un dossier, seulement les différences
Un tunnel. ssh -L 8080:127.0.0.1:8080 srv-web redirige le port 8080 de ton poste vers le port 8080 de srv-web, vu depuis srv-web lui-même : tu testes l'API, qui n'écoute qu'en local, avec curl http://127.0.0.1:8080 sur ton poste, sans ouvrir aucun port dans le pare-feu.
Une commande à distance, sans session : ssh srv-web "df -h /".
Durcir le serveur OpenSSH
Sur Debian 13, la configuration du serveur est dans /etc/ssh/sshd_config, qui commence par Include /etc/ssh/sshd_config.d/*.conf. Pour chaque option, la première valeur lue gagne : un fichier de sshd_config.d/ l'emporte sur les lignes du fichier principal, qu'on laisse intact pour les mises à jour.
# /etc/ssh/sshd_config.d/10-sorbier.conf
# Pas de connexion directe en root : chacun se connecte sous son nom, puis sudo
PermitRootLogin no
# Clés uniquement : aucun mot de passe à deviner
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
# Seuls les membres de ce groupe peuvent se connecter
AllowGroups admins-ssh
# Limiter les essais et le temps pour s'authentifier
MaxAuthTries 3
LoginGraceTime 30
# Fonctions inutiles sur un serveur
X11Forwarding no
AllowAgentForwarding no
| Option | Défaut d'OpenSSH | Pourquoi la changer |
|---|---|---|
PermitRootLogin | prohibit-password (root par clé seulement) | Aucune connexion en root : chaque action est faite sous un nom, puis tracée par sudo |
PasswordAuthentication | yes | Un mot de passe peut être deviné, volé ou réutilisé ; une clé ne se devine pas |
AllowGroups | Aucune restriction | Un compte créé pour un service ou un prestataire n'a pas accès à SSH par erreur |
MaxAuthTries | 6 | Moins d'essais par connexion |
LoginGraceTime | 120 secondes | Moins de connexions laissées ouvertes sans authentification |
Appliquer sans se bloquer dehors. Avant de recharger, crée le groupe et mets-y les administrateurs, vérifie que ta clé fonctionne, puis :
sudo addgroup admins-ssh
sudo adduser clambert admins-ssh # et mdiallo, amercier
sudo sshd -t # aucune sortie = syntaxe correcte
sudo sshd -T | grep -Ei 'permitrootlogin|passwordauthentication|allowgroups'
sudo systemctl reload ssh
sshd -T affiche la configuration effective, après lecture de tous les fichiers : c'est la seule façon sûre de savoir quelle valeur s'applique. Garde ta session ouverte et teste depuis un second terminal : si la nouvelle configuration te refuse, la session existante te permet encore de corriger.
Restreindre les sources. SSH ne doit être joignable que depuis le réseau d'administration et le bastion : c'est le rôle du pare-feu du réseau et du pare-feu local du serveur. Fail2ban ajoute un bannissement temporaire des adresses qui accumulent les échecs. Les deux sont présentés dans le cours Cybersécurité des infrastructures.
Exercices
Exercice 1 sur 4 Une clé refusée Réussi À revoir
Moussa Diallo a déposé sa clé publique sur srv-journaux, mais SSH lui demande toujours un mot de passe. Sur le serveur, ls -la dans son dossier personnel affiche drwxrwxr-x 2 mdiallo support 4096 … .ssh et -rw-rw-r-- 1 mdiallo support 98 … authorized_keys. Le journal contient « Authentication refused: bad ownership or modes for file /home/mdiallo/.ssh/authorized_keys ». Explique et corrige.
Voir la réponseMasquer la réponse de l'exercice 1
~/.ssh (775) et authorized_keys (664) sont modifiables par le groupe support, dont d'autres comptes sont membres. Avec StrictModes yes, le serveur considère que l'un d'eux aurait pu y ajouter sa clé, et ignore le fichier : il retombe sur le mot de passe. (Debian tolère l'écriture par le groupe seulement quand ce groupe ne contient que le propriétaire, son groupe personnel.) Correction, sous le compte de Moussa :
chgrp mdiallo ~/.ssh ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Le dossier personnel lui-même ne doit pas être modifiable par le groupe ou les autres (chmod go-w ~).
Tu avais trouvé ?
Exercice 2 sur 4 L'empreinte a changé Réussi À revoir
Après la réinstallation de srv-web, Chloé Lambert obtient :
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
...
Host key verification failed.
- Pourquoi ce message ?
- Que doit-elle faire avant de se reconnecter ?
Voir la réponseMasquer la réponse de l'exercice 2
- La réinstallation a généré de nouvelles clés d'hôte : l'empreinte présentée ne correspond plus à celle enregistrée dans
~/.ssh/known_hosts. Le client ne peut pas distinguer ce cas d'une interception (une machine qui se ferait passer poursrv-web), il refuse donc la connexion. - Vérifier la nouvelle empreinte par un autre canal : sur la console Proxmox de
srv-web,ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub. Si elle correspond, retirer l'ancienne entrée avecssh-keygen -R 192.168.10.225(etssh-keygen -R srv-websi elle se connectait par le nom), puis se reconnecter et accepter la nouvelle empreinte. Si l'empreinte ne correspond pas, ne pas se connecter et alerter : la connexion est peut-être détournée.
Tu avais trouvé ?
Exercice 3 sur 4 Relire une configuration SSH (type E7) Réussi À revoir
L'audit de srv-web relève ce fichier /etc/ssh/sshd_config.d/local.conf :
PermitRootLogin yes
PasswordAuthentication yes
MaxAuthTries 10
Port 2222
- Relève les faiblesses et leur risque.
- Propose la configuration corrigée.
- Donne les commandes pour l'appliquer sans risque de perdre l'accès, et pour vérifier ce qui s'applique réellement.
Voir la réponseMasquer la réponse de l'exercice 3
PermitRootLogin yes: connexion directe enroot, la cible la plus visée, sans trace de la personne.PasswordAuthentication yes: les mots de passe peuvent être devinés par essais répétés ou réutilisés après une fuite.MaxAuthTries 10: beaucoup d'essais par connexion.Port 2222: sans effet sur la sécurité, il donne une fausse impression de protection.-
Le port peut revenir à 22 ; le filtrage des sources (réseau d'administration, bastion) se fait au pare-feu, et Fail2ban bannit les adresses insistantes.
PermitRootLogin no PasswordAuthentication no KbdInteractiveAuthentication no PubkeyAuthentication yes AllowGroups admins-ssh MaxAuthTries 3 LoginGraceTime 30 X11Forwarding no - Vérifier que les administrateurs ont une clé fonctionnelle et sont dans
admins-ssh;sudo sshd -tpour la syntaxe ;sudo systemctl reload sshen gardant la session ouverte ; tester depuis un second terminal ;sudo sshd -T | grep -Ei 'permitrootlogin|passwordauthentication|allowgroups|maxauthtries'pour la configuration effective.
Tu avais trouvé ?
Exercice 4 sur 4 Administrer à travers le bastion Réussi À revoir
Le pare-feu de Sorbier n'autorise SSH vers srv-web et srv-journaux que depuis le bastion 192.168.10.210. Écris le fichier ~/.ssh/config de Moussa Diallo (compte mdiallo partout) pour qu'il tape seulement ssh srv-web, puis la commande pour copier /var/log/nginx/error.log de srv-web vers son poste.
Voir la réponseMasquer la réponse de l'exercice 4
Host bastion
HostName 192.168.10.210
User mdiallo
Host srv-web
HostName 192.168.10.225
User mdiallo
ProxyJump bastion
Host srv-journaux
HostName 192.168.10.180
User mdiallo
ProxyJump bastion
Puis scp srv-web:/var/log/nginx/error.log . : scp lit le même fichier de configuration et passe aussi par le bastion. Moussa doit pouvoir lire ce fichier sur srv-web (membre du groupe adm), et sa clé publique doit être déposée sur le bastion et sur srv-web.
Tu avais trouvé ?