L’authentification SSH par mot de passe est la plus grande surface exposée d’un serveur ordinaire. Ni Fail2ban ni aucun seuil n’y peuvent rien : mille adresses à une tentative par heure n’atteindront jamais une limite, et elles chercheront exactement aussi longtemps que la recherche restera possible. Les clés suppriment cette possibilité même, et de toute la liste du durcissement c’est le seul réglage qui change la situation qualitativement.
Une seule chose y fait peur : couper le mot de passe et rester dehors. Voici l’ordre dans lequel cela ne peut pas arriver.
La clé
Elle se génère sur votre machine, pas sur le serveur :
ssh-keygen -t ed25519 -C "portable de travail"
ed25519 plutôt que RSA : plus court, plus rapide et sans question sur la longueur. RSA n’est nécessaire que s’il faut atteindre quelque chose de très ancien ; alors -t rsa -b 4096.
Mettre une phrase secrète sur la clé en vaut la peine : le fichier de clé peut être volé sur un portable, et sans phrase secrète il fonctionne immédiatement. Vous n’aurez pas à la saisir chaque fois — ssh-agent s’en charge, et sous macOS comme sur la plupart des Linux de bureau il tourne déjà.
La copie vers le serveur tient en une commande, tant que le mot de passe fonctionne encore :
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@203.0.113.25
Si ssh-copy-id n’est pas disponible, le contenu du fichier .pub s’ajoute en une ligne à ~/.ssh/authorized_keys sur le serveur. Les droits comptent : le répertoire .ssh en 700, le fichier en 600, appartenant à l’utilisateur lui-même. Avec d’autres droits, sshd refuse silencieusement de lire le fichier — et c’est la cause la plus fréquente du « la clé ne marche pas ».
La vérification qui tranche
Avant de couper quoi que ce soit, ouvrez une seconde connexion sans fermer la première :
ssh -o PasswordAuthentication=no user@203.0.113.25
L’option interdit au client de retomber sur un mot de passe — si la connexion aboutit, c’est donc bien par la clé. Tant que cette commande ne passe pas, n’allez pas plus loin. Et gardez la première connexion ouverte jusqu’au bout : c’est par elle que se répare tout ce que vous casserez.
La coupure et un piège peu évident
Les réglages vont dans un fichier séparé pour qu’une mise à jour du paquet ne les efface pas. Mais le nom du fichier a son importance :
sudo tee /etc/ssh/sshd_config.d/10-hardening.conf <<'EOF'
PasswordAuthentication no
PermitRootLogin no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LogLevel VERBOSE
EOF
Le fait est qu’OpenSSH retient la première valeur obtenue pour un paramètre, et non la dernière comme presque partout ailleurs. Les fichiers de sshd_config.d sont lus par ordre alphabétique, et les images cloud d’Ubuntu y déposent 50-cloud-init.conf, où figure fréquemment PasswordAuthentication yes. Votre fichier numéroté 90 ne fera alors rien : le réglage semble en place, le mot de passe continue de fonctionner. D’où le numéro 10 — il est lu plus tôt.
Ce qui en est réellement sorti se voit sans deviner :
sudo sshd -T | grep -Ei 'passwordauth|permitrootlogin|pubkeyauth'
Cette commande imprime la configuration effective après toutes les inclusions. C’est à elle qu’il faut se fier, pas au contenu des fichiers.
Ensuite, contrôle de syntaxe et rechargement en douceur du service :
sudo sshd -t && sudo systemctl reload ssh
sshd -t est obligatoire : une faute de frappe dans la configuration laissera le service à terre avec restart, et vous dehors. reload ne coupe pas non plus les sessions ouvertes.
Ubuntu 24.04 : le port n’est pas où vous croyez
Un piège propre aux Ubuntu récents : sshd y est lancé par une socket systemd. Dans ce mode, la ligne Port de sshd_config ne fait rien — c’est la socket qui écoute, pas le démon. Si vous changez le port, c’est elle qu’il faut modifier :
sudo systemctl edit ssh.socket
et ListenStream= (une valeur vide réinitialise la précédente) doit nommer le nouveau port. Le symptôme qui le trahit : la configuration est modifiée, le service redémarré, et le serveur répond toujours sur 22.
À propos du changement de port : comme protection, il ne fonctionne pas — les scanners trouvent un service sur n’importe quel port en quelques minutes. Son seul effet, ce sont des journaux plus calmes, car la recherche de masse ne vise que le 22. C’est commode, mais ne le confondez pas avec de la sécurité.
Qui a le droit de se connecter
Un complément utile est une liste explicite :
AllowUsers deploy admin
Tout ce qui n’y figure pas est écarté avant même la vérification de la clé. Cela couvre aussi le cas où un paquet crée un utilisateur système avec un shell et un répertoire personnel.
Une entrée de secours
Une clé sur un portable est un point de défaillance unique. Le disque meurt, le portable est perdu, et le serveur devient inaccessible à jamais. Un minimum raisonnable :
- une seconde clé, depuis un autre appareil, dans
authorized_keys; - une copie de la clé privée dans un gestionnaire de mots de passe ou sur une clé USB chiffrée ;
- un accès console éprouvé chez l’hébergeur — VNC ou série. Éprouvé signifie que vous vous y êtes connecté au moins une fois, pas qu’« il y a un bouton quelque part dans le panneau ».
Profitez-en pour regarder ce qui se trouve déjà dans authorized_keys — chez votre utilisateur et chez root. Une clé étrangère y survit à tout changement de mot de passe et reste un accès opérationnel.
Ensuite
La recherche de mots de passe ne disparaîtra pas, elle devient simplement inutile : les journaux garderont des milliers de lignes Failed password, dont aucune ne peut aboutir. Ce qu’il vaut désormais la peine d’observer, ce sont les connexions réussies : depuis quelle adresse, sous quel utilisateur, à quelle heure. Une connexion réussie par clé depuis une adresse inconnue est un événement bien plus important qu’un million d’échecs — et bien plus difficile à repérer dans le flot général. C’est exactement ce tableau que montre la page de démonstration ci-dessous.