Sécuriser SSH : authentification par clé, blocage du login root, mot de passe désactivé

Publié le 18 min de lecture

ed25519 sous Linux, macOS et Windows, le piège cloud-init dans /etc/ssh/sshd_config.d, l'activation par socket sous Ubuntu 24.04, la preuve par sudo sshd -T et la voie de secours par la console.

Un serveur fraîchement installé figure dans les listes des scanners quelques minutes seulement après être devenu joignable. Ce qui arrive alors est presque toujours identique : des essais automatisés de noms d'utilisateur et de mots de passe sur le port 22. En désactivant l'authentification par mot de passe et en n'autorisant plus que les clés, vous retirez toute base à cette classe d'attaques entière. Non pas atténuée, mais totalement.

La plupart des administrateurs connaissent les étapes de base. Ce qui manque dans les tutoriels habituels, c'est la suite : pourquoi PasswordAuthentication no reste régulièrement sans effet sur les images cloud, pourquoi un systemctl reload ssh ne fait plus ce que vous attendez sur un serveur où ssh.socket est actif, et comment prouver au lieu d'espérer que la modification a bien pris. C'est exactement le sujet ici. Toutes les indications valent pour Debian 13, Debian 12, Ubuntu 24.04 et Ubuntu 22.04.

La règle qui sauve tout : deux sessions

Avant de modifier quoi que ce soit dans la configuration SSH, ouvrez une deuxième fenêtre de terminal et connectez-vous également au serveur. Cette deuxième session reste ouverte jusqu'à ce que vous ayez testé avec succès la nouvelle configuration au moyen d'une troisième connexion, entièrement nouvelle.

La raison est technique : le redémarrage du service SSH ne met pas fin aux sessions existantes. Les connexions en cours sont servies par des processus enfants déjà détachés et survivent au redémarrage du processus parent. Vous ne remarquerez donc une configuration cassée qu'au prochain établissement de connexion, et l'ancienne session sera alors votre seul chemin de retour. Ceux qui la ferment pour « se reconnecter proprement une bonne fois » le regrettent avec une certaine régularité.

Vérifiez par ailleurs quelle version d'OpenSSH vous avez devant vous, car plusieurs détails en dépendent :

ssh -V
SystèmeOpenSSHListener par défaut
Debian 13 (trixie)10.0p2ssh.service
Debian 12 (bookworm)9.2p1ssh.service
Ubuntu 24.04 LTS9.6p1ssh.socket
Ubuntu 22.04 LTS8.9p1ssh.service

Si le service serveur est totalement absent, par exemple dans une image minimale, installez-le :

sudo apt update
sudo apt install -y openssh-server

Générer une clé : ed25519 sous Linux, macOS et Windows

Prenez ed25519. Courte, rapide à vérifier, avec une grande marge de sécurité, et toutes les versions d'OpenSSH traitées ici la prennent en charge. RSA ne vous sert plus que pour de vieux systèmes qui n'acceptent rien d'autre, et dans ce cas avec 4096 bits au minimum.

Linux et macOS

ssh-keygen -t ed25519 -a 100 -C "hani@notebook" -f ~/.ssh/id_ed25519

-a 100 augmente le nombre de tours KDF pour la phrase de passe et rend nettement plus coûteuses les attaques hors ligne contre le fichier de clé. -C définit un commentaire qui figurera plus tard dans authorized_keys et vous indiquera quelle clé provient de quel appareil. Attribuez une phrase de passe. Une clé sans phrase de passe n'est qu'un fichier, que peut emporter quiconque s'assied un instant devant votre machine.

Pour ne pas avoir à saisir la phrase de passe à chaque connexion, l'agent se charge de la mettre en cache :

eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519

Sous macOS, vous placez plutôt la phrase de passe dans le trousseau. L'ancienne option -K s'appelle --apple-use-keychain depuis macOS 12 :

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Pour que cela survive à un redémarrage, il faut ajouter ceci dans ~/.ssh/config :

Host *
    UseKeychain yes
    AddKeysToAgent yes
    IdentityFile ~/.ssh/id_ed25519

Windows

Windows 10 à partir de la version 1809, Windows 11 et Windows Server à partir de 2019 embarquent le client OpenSSH. Dans PowerShell :

ssh -V
ssh-keygen -t ed25519 -a 100 -C "hani@windows"

La clé atterrit dans C:\Users\VotreNom\.ssh\. Si le client est absent, installez-le comme fonctionnalité Windows :

Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

Sous Windows, l'agent est un service système, désactivé dans l'état de livraison :

Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519

Transférer la clé publique sur le serveur

Seul le fichier portant l'extension .pub a sa place sur le serveur. Le fichier sans extension est la clé privée et ne quitte jamais votre machine.

La méthode confortable sous Linux

ssh-copy-id -i ~/.ssh/id_ed25519.pub root@203.0.113.10

ssh-copy-id crée ~/.ssh, positionne correctement les droits, ajoute la clé à authorized_keys et vérifie au passage si elle s'y trouve déjà. Sous macOS, l'outil n'est pas inclus dans toutes les versions. Vérifiez rapidement avec command -v ssh-copy-id et repliez-vous sinon sur la méthode manuelle.

La méthode Windows, sans ssh-copy-id

Le client OpenSSH de Microsoft ne contient pas ssh-copy-id. L'original est un script shell et n'a jamais été porté. Vous obtenez le même résultat avec un tube :

type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh root@203.0.113.10 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Un détail se cache ici, qui coûte de nombreuses heures : quand elle transmet des données à un programme externe, PowerShell ajoute des fins de ligne au format Windows. authorized_keys contient alors un retour chariot invisible en fin de ligne. Tant que vous avez commenté la clé avec -C, ce caractère atterrit dans le champ de commentaire et ne gêne pas. Sans commentaire, il se colle au bloc Base64, et la connexion échoue sans message exploitable. D'où la règle : toujours définir un commentaire, et en cas de doute, faire une fois le ménage sur le serveur.

sed -i 's/\r$//' ~/.ssh/authorized_keys

La méthode manuelle, qui fonctionne partout

mkdir -p ~/.ssh && chmod 700 ~/.ssh && touch ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys

Ajoutez ensuite le contenu du fichier .pub sur une seule ligne. Si le fichier se trouve déjà sur le serveur, parce que vous l'y avez téléversé par exemple, cela se fait directement :

cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys

Contrôlez ensuite ce qui a réellement atterri dans le fichier :

ssh-keygen -lf ~/.ssh/authorized_keys

La sortie liste l'empreinte et le commentaire de chaque entrée valide. Ce qui n'apparaît pas ici a subi un retour à la ligne ou est endommagé. Comparez l'empreinte avec celle de votre clé locale :

ssh-keygen -l -f ~/.ssh/id_ed25519.pub

Si les deux correspondent, le transfert s'est déroulé proprement. Testez maintenant, avant de désactiver quoi que ce soit, si l'authentification par clé fonctionne réellement. Ne continuez que lorsqu'une nouvelle connexion aboutit sans demande de mot de passe.

Le piège : /etc/ssh/sshd_config.d et cloud-init

C'est l'endroit où la plupart des tutoriels s'arrêtent, et la raison la plus fréquente de la phrase « je l'ai désactivé, et ça marche quand même ».

Depuis Debian 11 et Ubuntu 22.04, une ligne tout en haut de /etc/ssh/sshd_config lit un répertoire entier. Vérifiez vous-même à quelle position :

grep -n Include /etc/ssh/sshd_config

Sur les quatre systèmes traités ici, la ligne Include se trouve au début, pas à la fin. Et voici la particularité d'OpenSSH que l'on ne connaît presque d'aucun autre langage de configuration : c'est la première valeur trouvée qui l'emporte, pas la dernière. Ce qui figure dans un fichier sous /etc/ssh/sshd_config.d/ est donc lu avant le fichier principal et bat toute ligne ultérieure de sshd_config.

Cloud-init utilise précisément ce répertoire. Au premier démarrage, il écrit /etc/ssh/sshd_config.d/50-cloud-init.conf, et selon le mode de mise à disposition on y trouve PasswordAuthentication yes. Vous pouvez ensuite inscrire PasswordAuthentication no dans sshd_config aussi souvent que vous voulez : l'authentification par mot de passe reste ouverte. Commencez par faire le tour de la situation :

ls -la /etc/ssh/sshd_config.d/
sudo grep -riE 'passwordauthentication|permitrootlogin|kbdinteractive' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/

D'où la recommandation véritable : ne touchez pas du tout à sshd_config. Créez à la place votre propre fichier, dont le nom se classe alphabétiquement avant tout ce que l'automatisation dépose à cet endroit. Les fichiers sont lus dans l'ordre trié, 01- vient avant 50-, et comme la première valeur l'emporte, cloud-init peut ensuite réécrire son fichier autant de fois qu'il veut sans annuler votre durcissement. C'est la différence avec la recommandation très répandue de créer un 99-hardening.conf : celui-ci perd contre cloud-init, et en silence. La même mécanique peut cependant se retourner contre vous : un fichier portant un numéro plus petit, par exemple 00-cloud.conf, l'emporte sur votre 01-, puisque OpenSSH retient la valeur lue en premier. Un coup d'œil dans le répertoire vaut donc aussi la peine après le durcissement.

Écrire le durcissement, avec une minuterie comme filet de retour

Construisez d'abord le filet de sécurité. La commande suivante supprime automatiquement votre nouveau fichier dans dix minutes et redémarre SSH, si vous n'avez pas annulé d'ici là :

sudo systemd-run --on-active=10min --unit=ssh-rollback /bin/sh -c 'rm -f /etc/ssh/sshd_config.d/01-hardening.conf; systemctl try-restart ssh.socket ssh.service'

Maintenant la configuration proprement dite :

sudo tee /etc/ssh/sshd_config.d/01-hardening.conf >/dev/null <<'EOF'
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
PermitEmptyPasswords no
MaxAuthTries 3
EOF
sudo chmod 644 /etc/ssh/sshd_config.d/01-hardening.conf

Deux lignes méritent une explication. KbdInteractiveAuthentication no n'est pas un accessoire : si elle reste sur yes, PAM peut continuer à proposer la demande de mot de passe par le détour de la saisie clavier interactive, alors même que PasswordAuthentication est sur no. C'est exactement pour cette raison que certains serveurs réclament un mot de passe malgré une authentification par mot de passe désactivée.

Et PermitRootLogin prohibit-password au lieu de no : l'accès en tant que root par clé reste ainsi possible, tandis que les mots de passe sont exclus pour root. Si vous avez mis en place un utilisateur dédié avec sudo et que vous avez testé son authentification par clé de façon vérifiable, mettez plutôt PermitRootLogin no. Pas avant.

Ce que vous ne devriez pas reprendre, bien que cela figure dans d'anciens tutoriels : ChallengeResponseAuthentication. Depuis OpenSSH 8.7, l'option n'est plus qu'un alias obsolète de KbdInteractiveAuthentication et produit un message de dépréciation dans le journal des versions actuelles. Laissez-la de côté.

Vérification de la syntaxe avant l'activation, sans exception :

sudo sshd -t

Aucune sortie signifie que le fichier est syntaxiquement en ordre. Cela ne signifie pas qu'il fait sur le fond ce que vous voulez. C'est le rôle de sudo sshd -T, juste après.

Si le test signale au contraire Missing privilege separation directory: /run/sshd, c'est que sshd n'a pas tourné une seule fois depuis le démarrage du système, car ce répertoire n'est créé qu'avec ssh.service. Cela touche surtout Ubuntu 24.04 avec l'activation par socket et se règle avec sudo mkdir -p /run/sshd ou sudo systemctl start ssh.service. Sur un serveur où vous êtes justement connecté en SSH, le cas ne se présente de toute façon pas.

Activer : ssh.service, ssh.socket et les différences selon la distribution

Ici, les quatre systèmes divergent, et la vieille habitude systemctl reload ssh est la mauvaise réponse partout où ssh.socket détient le port.

Ubuntu mise sur l'activation par socket depuis la 22.10, et Ubuntu 24.04 la livre par défaut : ssh.socket y est activé et ssh.service désactivé. Debian fait exactement l'inverse en sortie d'usine. Debian 13 et Debian 12 livrent ssh.service activé et ssh.socket désactivé, contrairement à l'idée répandue selon laquelle Debian 13 basculerait sur le socket lors d'une nouvelle installation. Avec l'activation par socket, systemd écoute lui-même sur le port 22 et ne démarre un sshd frais qu'à l'arrivée d'une connexion. Cela a un effet secondaire agréable : les modifications de sshd_config prennent effet dès la connexion suivante, puisque chaque processus de connexion relit la configuration. Vous n'avez besoin d'un rechargement que pour les réglages qui concernent le listener lui-même, à savoir Port et ListenAddress.

Ne devinez donc pas, demandez plutôt au système quelle unité assure le service chez vous :

systemctl is-enabled ssh.socket ssh.service
Systèmessh.socketssh.serviceParticularité
Ubuntu 24.04 LTSenableddisabledActivation par socket par défaut, ListenStream sur 0.0.0.0:22 et [::]:22
Debian 13 (trixie)disabledenabledAccept=no
Debian 12 (bookworm)disabledenabledAccept=no
Ubuntu 22.04 LTS (et de même Debian 11)disabledenabledAccept=yes, donc un processus propre par connexion via ssh@.service

Et voici une commande qui est correcte sur les quatre systèmes :

sudo sshd -t && sudo systemctl try-restart ssh.socket ssh.service

try-restart ne redémarre une unité que si elle est effectivement active, et laisse l'autre intacte. Vous n'avez donc rien à deviner. Les deux parties exigent root : sshd se trouve sous /usr/sbin et n'est pas dans le PATH d'un utilisateur normal sous Debian, et try-restart s'adresse de toute façon à systemd. Sans sudo, l'appel se termine selon le système par sshd: command not found ou par sshd: no hostkeys available, car les clés d'hôte sous /etc/ssh ne sont lisibles que par root.

Tout aussi délibérément, pas de systemctl restart ssh.socket isolé, même si cette commande figure dans de nombreux tutoriels. Sur Debian 13 et Debian 12, elle s'interrompt avec Job failed. See journalctl -xe for details., et le journal indique à ce sujet ssh.socket: Socket service ssh.service already active, refusing. La nouvelle configuration n'est alors pas activée, et le contre-test signale toujours Permission denied (publickey,password). Sur Ubuntu 22.04 et Debian 11, elle passe certes sans message d'erreur, mais elle arrête au passage ssh.service et bascule l'hôte sur l'activation par socket. Comme ssh.socket y reste désactivé, c'est ssh.service qui redémarre au prochain redémarrage : le mode de fonctionnement change donc de l'un à l'autre sans que personne ne le remarque. Un try-restart sur les deux unités évite les deux problèmes.

Délibérément pas de reload non plus : sur un système où ssh.socket détient le port, un systemctl reload ssh répond par

fatal: Cannot bind any address.

Le service se retrouve ensuite en état d'erreur et a lâché son port. Un redémarrage n'a pas ce problème et ne met pas davantage fin aux sessions existantes.

Si vous voulez déplacer le port, la différence suivante entre distributions apparaît. Ubuntu 24.04 génère la configuration du socket à partir de sshd_config via un générateur systemd ; après le changement de port, il suffit d'y lancer :

sudo systemctl daemon-reload
sudo systemctl try-restart ssh.socket ssh.service

Si en revanche vous êtes délibérément passé à ssh.socket sous Debian, le port se trouve dans l'unité elle-même et une modification dans sshd_config reste sans effet. Vous l'enregistrez par un fichier complémentaire via sudo systemctl edit ssh.socket, avec un ListenStream= vide pour réinitialiser et une seconde ligne portant la nouvelle valeur. Contrôlez ensuite le résultat sur la réalité, pas sur la configuration :

sudo ss -tlnp

La preuve : sshd -T et le contre-test

Une commande qui passe sans erreur n'est pas une preuve. La preuve, c'est la configuration globale résolue, dans laquelle tous les fichiers inclus sont déjà pris en compte :

sudo sshd -T | grep -E '^(passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|permitrootlogin|usepam|port|authorizedkeysfile)'

On attend une sortie de ce genre :

port 22
permitrootlogin prohibit-password
pubkeyauthentication yes
passwordauthentication no
kbdinteractiveauthentication no
usepam yes
authorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2

Si vous y lisez passwordauthentication yes malgré votre fichier, c'est qu'un fichier du répertoire se classe alphabétiquement avant le vôtre. Retour à la section sur l'ordre de lecture.

Pour une interrogation ponctuelle, la même commande suffit avec un filtre plus étroit :

sudo sshd -T | grep -i passwordauthentication

Deux raisons plaident pour le sudo en préfixe. Premièrement, sshd -T lit les clés d'hôte, qui ne sont lisibles que par root sous /etc/ssh. Deuxièmement, sshd lui-même se trouve sous /usr/sbin, et ce répertoire ne fait pas partie du PATH d'un utilisateur normal sous Debian, raison pour laquelle l'appel sans sudo s'y termine par sshd: command not found. Qui veut éviter le détour par sudo écrit le chemin complet /usr/sbin/sshd.

À partir d'OpenSSH 9.3, donc sur Ubuntu 24.04 (9.6p1) et Debian 13 (10.0p2), il existe en plus sshd -G. L'option évalue la même configuration, mais n'exige ni clés d'hôte lisibles ni /run/sshd existant, ce qui la rend utilisable pour des vérifications en automatisation et dans des conteneurs (containers). Sur Debian 12 (9.2p1), Ubuntu 22.04 (8.9p1) et Debian 11 (8.4p1), l'option n'existe pas encore : sshd la refuse comme option inconnue. Pour un tutoriel valable partout, sudo sshd -T reste donc le bon choix.

Passons au contre-test, depuis un nouveau terminal, pendant que l'ancienne session reste ouverte. Forcez une authentification par mot de passe et désactivez les clés pour cet essai :

ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password,keyboard-interactive root@203.0.113.10

Le résultat est correct lorsque vous êtes refusé immédiatement et sans la moindre demande de mot de passe :

root@203.0.113.10: Permission denied (publickey).

Le contenu entre parenthèses est décisif. S'il indique (publickey,password) ou si une demande de mot de passe apparaît, l'authentification par mot de passe est toujours ouverte. Ce n'est que lorsque le contre-test échoue proprement et qu'une connexion par clé normale continue d'aboutir que vous fermez l'ancienne session et arrêtez la minuterie :

sudo systemctl stop ssh-rollback.timer

Les messages d'erreur, mot pour mot

Permission denied (publickey). Le serveur n'accepte que des clés, et la vôtre ne convient pas. Lancez ssh -v et regardez quel fichier a réellement été proposé. Causes les plus fréquentes : mauvais nom d'utilisateur, clé dans le authorized_keys du mauvais utilisateur, ou bien vous avez bloqué root et vous continuez à vous connecter en tant que root.

Authentication refused: bad ownership or modes for directory /home/hani/.ssh Cette ligne ne s'affiche pas sur votre écran, mais dans le journal du serveur, visible via sudo journalctl -u ssh -n 50 --no-pager. Ne filtrez pas à cette occasion sur -t sshd : à partir d'OpenSSH 9.8, donc en sortie d'usine sur Debian 13, les sessions tournent dans leur propre processus sshd-session, et sous le tag sshd ne restent que les messages du listener, sans la moindre procédure d'authentification. Qui veut filtrer par tag prend sudo journalctl -t sshd -t sshd-session -n 50 --no-pager. OpenSSH refuse les clés lorsque le répertoire personnel, .ssh ou authorized_keys sont accessibles en écriture au groupe ou aux autres. La correction :

chmod go-w ~ && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

WARNING: UNPROTECTED PRIVATE KEY FILE! ou bien Load key "/home/hani/.ssh/id_ed25519": bad permissions. Le même problème du côté client. chmod 600 ~/.ssh/id_ed25519 le résout.

Too many authentication failures Votre agent propose tour à tour toutes les clés chargées et dépasse ainsi MaxAuthTries. Limitez la connexion à une seule clé : ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 hani@203.0.113.10.

sign_and_send_pubkey: no mutual signature supported Une ancienne clé RSA avec signature SHA-1 rencontre un serveur qui ne l'accepte plus. Générez une clé ed25519 au lieu de bricoler PubkeyAcceptedAlgorithms.

Bad owner or permissions on C:\Users\hani\.ssh\config Le client Windows vérifie les droits d'accès de son fichier de configuration. Dans les propriétés du fichier, sous Sécurité, supprimez l'héritage ainsi que toutes les entrées à l'exception de votre compte utilisateur et de SYSTEM.

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! La clé d'hôte du serveur diffère de celle de la dernière fois. Après une réinstallation, c'est attendu, sinon non. Supprimez l'ancienne entrée de manière ciblée avec ssh-keygen -R 203.0.113.10, et uniquement si vous en connaissez la raison.

Bloqué dehors : la console dans l'espace client

Si les deux sessions ont disparu et qu'aucune connexion n'aboutit plus, ce n'est pas une perte de données, seulement un détour. Chaque serveur root KVM et chaque serveur dédié chez KernelHost dispose dans l'espace client d'une console qui est branchée sur la sortie écran du système et reste indépendante de la pile réseau du serveur. Vous entrez donc même lorsque SSH n'écoute plus du tout.

  1. Connectez-vous à l'espace client, ouvrez le serveur concerné et démarrez la console.
  2. À l'invite de connexion, identifiez-vous en tant que root avec le mot de passe attribué lors de la mise à disposition. La connexion par console ne passe pas par SSH et n'est pas concernée par PermitRootLogin.
  3. Annulez la modification : sudo rm /etc/ssh/sshd_config.d/01-hardening.conf
  4. Vérifiez et redémarrez : sudo sshd -t && sudo systemctl try-restart ssh.socket ssh.service
  5. Si SSH ne tourne pas du tout, sudo systemctl status ssh.socket ssh.service et un coup d'œil dans sudo journalctl -u ssh -n 50 --no-pager vous aident. Le code de retour 3 de status signifie seulement que l'une des deux unités est inactive, ce qui sous Debian, avec ssh.socket désactivé, est le cas normal.

Deux précautions vous épargnent ce détour presque à tous les coups. Notez le mot de passe root avant de désactiver l'authentification par mot de passe, car la console en a besoin. Et vérifiez un éventuel pare-feu actif avant de déplacer le port SSH. Un changement de port sans règle d'ouverture correspondante vous met dehors aussi sûrement qu'une sshd_config cassée, mais l'aspect diffère : au lieu de Permission denied, vous obtenez Connection timed out.

En bref

  • Laissez une deuxième session ouverte jusqu'à ce qu'une troisième connexion, entièrement nouvelle, fonctionne de façon vérifiable.
  • ed25519 avec -a 100 et phrase de passe, clé publique via ssh-copy-id, sous Windows via un tube.
  • Testez l'authentification par clé avant de faire tomber l'authentification par mot de passe.
  • Durcissement dans /etc/ssh/sshd_config.d/01-hardening.conf, pas dans sshd_config. La première valeur trouvée l'emporte, d'où le numéro bas.
  • N'oubliez pas KbdInteractiveAuthentication no, sinon le détour par PAM reste ouvert.
  • Activez avec sudo sshd -t && sudo systemctl try-restart ssh.socket ssh.service, ni avec reload ni avec un restart ssh.socket isolé.
  • Clarifiez d'abord avec systemctl is-enabled ssh.socket ssh.service quelle unité est réellement active. Ubuntu 24.04 utilise le socket, Debian 13 et Debian 12 le service.
  • Preuve par sudo sshd -T et par une tentative de mot de passe forcée depuis une nouvelle session.
  • La voie de secours est la console dans l'espace client, tenez le mot de passe root prêt pour cela.

Les couches suivantes les plus évidentes sont décrites dans nos articles sur fail2ban et sur le pare-feu UFW. Plus important que ces deux couches : ce que vous venez d'accomplir.

Questions fréquentes

Pourquoi l'authentification par mot de passe reste-t-elle active malgré PasswordAuthentication no ?
Presque toujours à cause d'un fichier dans /etc/ssh/sshd_config.d/, le plus souvent 50-cloud-init.conf. Sous Debian et Ubuntu, la ligne Include se trouve au début de sshd_config, et OpenSSH retient la première valeur trouvée, pas la dernière. Ce qui se trouve dans le répertoire l'emporte donc sur le fichier principal. Vérifiez avec sudo sshd -T ce qui s'applique réellement, et créez votre propre fichier sous le nom 01-hardening.conf pour qu'il soit lu avant tous les fichiers générés automatiquement.
Dois-je redémarrer le service après une modification de sshd_config ?
Sur Debian 13, Debian 12 et Ubuntu 22.04 oui, car ssh.service y est activé en sortie d'usine et ssh.socket désactivé. Sur Ubuntu 24.04, systemd écoute par défaut via ssh.socket et démarre un nouveau sshd par connexion, qui relit de toute façon la configuration. Seuls Port et ListenAddress concernent le listener lui-même. La commande systemctl is-enabled ssh.socket ssh.service montre quelle unité est active chez vous. La commande sudo sshd -t && sudo systemctl try-restart ssh.socket ssh.service est correcte sur les quatre systèmes, un systemctl restart ssh.socket isolé ne l'est pas : sur Debian 13 et Debian 12 il échoue et la nouvelle configuration n'est pas activée, sur Ubuntu 22.04 il bascule l'hôte sur l'activation par socket sans que cela se remarque.
Pourquoi devrais-je éviter reload ?
Sur les systèmes où ssh.socket est actif, donc par défaut sous Ubuntu 24.04, systemctl reload ssh s'interrompt avec le message fatal: Cannot bind any address, le service passe en état d'erreur et libère son port. Un redémarrage n'a pas ce problème et ne met pas davantage fin aux sessions existantes, car les connexions en cours sont servies par leurs propres processus enfants.
Comment transférer ma clé depuis Windows vers le serveur, puisque ssh-copy-id n'existe pas là-bas ?
Par un tube : type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh utilisateur@serveur "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys". Veillez à avoir commenté la clé avec -C, sinon un retour chariot ajouté par PowerShell peut endommager le bloc Base64. Sur le serveur, sed -i 's/\r$//' ~/.ssh/authorized_keys nettoie cela.
Comment prouver que l'authentification par mot de passe est vraiment fermée ?
En deux étapes. Premièrement sudo sshd -T, qui affiche la configuration globale résolue et doit montrer passwordauthentication no ainsi que kbdinteractiveauthentication no. Deuxièmement un contre-test depuis une nouvelle session : ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password,keyboard-interactive utilisateur@serveur doit être refusé immédiatement avec Permission denied (publickey). Si la parenthèse indique publickey,password, l'accès est encore ouvert.
Que faire si je me suis bloqué dehors ?
Connectez-vous à l'espace client, ouvrez le serveur et démarrez la console. Elle est branchée sur la sortie écran du système et reste indépendante de SSH. Identifiez-vous là en tant que root, supprimez votre propre fichier avec sudo rm /etc/ssh/sshd_config.d/01-hardening.conf, vérifiez avec sudo sshd -t et redémarrez avec sudo systemctl try-restart ssh.socket ssh.service. Tenez le mot de passe root prêt avant de désactiver l'authentification par mot de passe.
PermitRootLogin no ou prohibit-password : quel est le meilleur choix ?
prohibit-password autorise toujours root par clé et exclut uniquement les mots de passe, ce qui préserve l'accès en cas de mauvaise configuration. no est plus strict, mais suppose qu'un second utilisateur avec sudo existe et que son authentification par clé fonctionne déjà de façon vérifiable. Ne basculez qu'une fois ce test réussi.

SSH Sécurité des serveurs Linux Debian Ubuntu OpenSSH ed25519 systemd cloud-init Tutoriel