Permission denied (publickey) est l’erreur SSH la plus fréquente qui soit, et le message ne vous rend aucun service. Il ne signifie pas « votre clé est mauvaise ». Il signifie : le serveur a rejeté toutes les méthodes d’authentification que vous avez proposées, et la clé publique était la seule méthode qu’il acceptait d’envisager. La parenthèse est la liste des méthodes encore ouvertes côté serveur — (publickey) signifie que l’authentification par mot de passe est désactivée, donc une clé doit fonctionner, et aucune des vôtres n’y est parvenue.
La liste peut être plus longue, et il vaut la peine de la lire. Permission denied (publickey,password) signifie que le serveur accepterait aussi un mot de passe — donc si vous comptiez en taper un et qu’aucune invite n’est apparue, votre client a abandonné les clés et aurait dû basculer ; forcez l’invite avec -o PubkeyAuthentication=no pour tester. Permission denied (publickey,keyboard-interactive) est la même idée avec une méthode interactive (souvent une invite PAM ou une 2FA) toujours sur la table. Quel que soit le contenu des parenthèses, c’est l’ensemble complet des portes que le serveur a laissées ouvertes ; si celle que vous attendiez n’y figure pas, le serveur n’allait jamais l’accepter.
Le filet est large : un mauvais nom d’utilisateur produit cette erreur. De même qu’une clé que le client n’a jamais proposée, une clé que le serveur n’a jamais reçue, un problème de permissions que sshd refuse silencieusement de laisser passer, et une étiquette SELinux dont vous n’avez jamais entendu parler. La correction est méthodique, pas une devinette — voici la boucle, puis les coupables classés selon la fréquence à laquelle ils sont réellement la réponse. (Vous poussez vers GitHub ou GitLab ? C’est une autre liste de contrôle — clé SSH GitHub/GitLab qui ne fonctionne pas.)
La boucle de diagnostic : lisez ce que le client a tenté
Relancez la connexion qui échoue avec le maximum de verbosité (et si le mur de sortie ressemble à du bruit, comment lire ssh -vvv (en anglais) décode les lignes qui comptent) :
ssh -vvv user@host
Trois choses à repérer dans la sortie :
Authentications that can continue: publickey— la liste des méthodes du serveur. Sipasswordest absent, aucun mot de passe ne sera jamais demandé ; une clé doit réussir.Offering public key: /home/you/.ssh/id_ed25519— chaque clé que le client a tentée. Si la clé que vous visiez n’est pas dans cette liste, le problème est côté client (coupable 2). Si elle y est —- ce qui est revenu.
Server accepts keysuivi d’un échange de signature signifie que la clé a correspondu et que quelque chose a échoué plus tard (rare). Le cas habituel, c’est l’offre suivie immédiatement de la clé suivante ou dePermission denied— le serveur a regardé la clé et a haussé les épaules, ce qui pointe du côté serveur (coupables 3 à 8).
Si vous avez un autre moyen d’entrer sur la machine (console web du fournisseur, un autre utilisateur, un autre administrateur), le journal du serveur nomme la vraie raison sans détour :
sudo journalctl -u sshd -f # systemd distros
sudo tail -f /var/log/auth.log # Debian/Ubuntu
sudo tail -f /var/log/secure # RHEL/Alma/Rocky
Des lignes comme Authentication refused: bad ownership or modes for directory /home/deploy closent l’enquête sur-le-champ.
Coupable 1 : mauvais utilisateur
La cause la plus répandue de toutes, surtout sur les images cloud (c’est le premier mur d’une première connexion à un EC2 ou un VPS (en anglais)), parce que l’utilisateur de connexion n’est pas celui qu’on devinerait : ubuntu sur les images Ubuntu, ec2-user sur Amazon Linux, admin sur les AMI Debian, root sur la plupart des VPS nus, azureuser sur les valeurs par défaut d’Azure. La bonne clé avec le mauvais nom d’utilisateur produit exactement cette erreur — le serveur vérifie ~wronguser/.ssh/authorized_keys, ne trouve rien, refuse.
Avant de toucher à quoi que ce soit d’autre, confirmez l’utilisateur que documente votre image, et fixez-le dans ~/.ssh/config pour ne plus jamais le retaper (le guide ssh_config (en anglais) détaille le schéma) :
Host web1
HostName 203.0.113.10
User ubuntu
Coupable 2 : votre clé n’a jamais été proposée
Si ssh -vvv ne montre pas votre clé dans une ligne Offering public key, le client ne la connaît pas. Désignez-la explicitement :
ssh -i ~/.ssh/id_ed25519 user@host
Si ça marche, rendez-le permanent avec IdentityFile dans le bloc de configuration ci-dessus. Deux pièges connexes : un agent bourré de nombreuses clés peut déclencher la limite de tentatives du serveur avant d’atteindre la bonne (Too many authentication failures — à corriger avec IdentitiesOnly yes), et une clé dont vous avez annulé l’invite de phrase secrète est silencieusement ignorée. Vérifiez ce que l’agent détient réellement :
ssh-add -l
Sous Windows, cette liste peut sembler vide alors que vous venez de charger une clé — Git Bash, le service OpenSSH et WSL font tourner chacun un agent distinct, et ssh-add -l ne répond que pour le ssh que vous utilisez réellement ; ssh-agent sous Windows démêle les trois.
Coupable 3 : la clé publique n’est pas sur le serveur
La moitié publique doit être une ligne dans ~user/.ssh/authorized_keys — pour cet utilisateur, dans le répertoire personnel de cet utilisateur. La manière fiable de l’y mettre (utilise l’authentification par mot de passe ou une clé existante pour la copie) :
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
À la main — par exemple via une console de fournisseur — ajoutez la ligne unique et n’écrasez jamais le fichier :
mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys
# paste the one line from id_ed25519.pub, Enter, Ctrl-D
Ratés classiques : la clé a atterri dans le fichier de root alors que vous vous connectez en tant que deploy ; la ligne a été coupée par un éditeur et tient désormais sur deux lignes ; vous avez collé la clé privée (le fichier commence par ssh-ed25519 AAAA… — si vous voyez -----BEGIN, c’est la mauvaise moitié).
Coupable 4 : permissions et appartenance
Le StrictModes de sshd (activé par défaut) refuse d’honorer authorized_keys si le chemin qui y mène est accessible en écriture à quelqu’un d’autre que le propriétaire. C’est le classique « j’ai copié la clé et ça ne marche toujours pas ». Le correctif complet, à exécuter en tant qu’utilisateur cible :
chmod go-w ~
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R $USER:$USER ~/.ssh
La ligne du répertoire personnel compte et s’oublie : un /home/deploy accessible en écriture au groupe échoue au contrôle tout aussi sûrement qu’un fichier de clé lisible par tous. La ligne bad ownership or modes du journal du serveur vous dit exactement quel répertoire le dérange.
Coupable 5 : mauvais format de clé ou phrase secrète
OpenSSH ne sait pas lire les fichiers .ppk de PuTTY — pointer -i vers l’un d’eux échoue avec invalid format dans la sortie détaillée. Exportez une clé au format OpenSSH depuis PuTTYgen (Conversions → Export OpenSSH key), ou générez une clé moderne toute neuve et ajoutez-la (Ed25519, dans la quasi-totalité des cas (en anglais)). Si vous êtes sous Windows et toujours coincé dans PuTTYgen, un client SSH pour Windows qui importe les sessions PuTTY et utilise directement les clés OpenSSH vous épargne cette étape de conversion. Pour vérifier qu’un fichier de clé privée est lisible et que la phrase secrète est bien celle que vous croyez, demandez-lui d’afficher sa moitié publique :
ssh-keygen -y -f ~/.ssh/id_ed25519
Si cela affiche une clé, le fichier et la phrase secrète sont bons — et vous pouvez comparer la sortie à la ligne d’authorized_keys pour confirmer qu’il s’agit bien de la même clé.
Coupable 6 : la configuration du serveur l’interdit
Moins fréquent, mais rapide à vérifier quand vous avez accès au serveur. Demandez à sshd avec quoi il tourne réellement :
sudo sshd -T | grep -Ei 'pubkeyauthentication|authorizedkeysfile'
PubkeyAuthentication doit valoir yes (par défaut, mais les scripts de durcissement l’inversent parfois), et AuthorizedKeysFile vous dit où sshd regarde — si quelqu’un l’a pointé vers /etc/ssh/authorized_keys/%u, votre ~/.ssh/authorized_keys soigneusement placé est ignoré. Après toute modification de /etc/ssh/sshd_config :
sudo systemctl reload sshd
Coupable 7 : contextes SELinux (famille RHEL)
Sur RHEL, Alma, Rocky, Fedora et consorts, un ~/.ssh créé par des moyens inhabituels — restauré depuis une sauvegarde, copié en tant que root, créé sur un volume monté — peut porter la mauvaise étiquette SELinux, et sshd se voit refuser l’accès en lecture à un fichier aux permissions parfaites. Tout ce qui précède est en ordre, l’erreur persiste, et ls -Z ~/.ssh affiche autre chose que ssh_home_t. Une seule commande répare les étiquettes :
restorecon -R -v ~/.ssh
Si vous êtes à court d’idées sur une machine de la famille RHEL, lancez-la quand même — elle est inoffensive quand les étiquettes étaient déjà correctes.
Coupable 8 : la connexion root est désactivée
Les valeurs par défaut modernes règlent PermitRootLogin prohibit-password (clé uniquement) ou no (jamais). Si vous essayez root@host et que la clé est réellement dans /root/.ssh/authorized_keys, vérifiez :
sudo sshd -T | grep -i permitrootlogin
Avec no, aucun identifiant ne fonctionnera jamais pour root — connectez-vous en tant qu’utilisateur non privilégié puis sudo, c’est de toute façon l’organisation vers laquelle la valeur par défaut vous pousse.
Réponses rapides
Permission denied (publickey) signifie-t-il que ma clé est corrompue ?
Presque jamais. Cela signifie que le serveur n’a accepté aucune des méthodes que vous avez proposées — en général le mauvais utilisateur ou la mauvaise clé, pas une clé cassée. Confirmez que la clé est lisible et que la phrase secrète est la bonne avec ssh-keygen -y -f ~/.ssh/id_ed25519.
Quelle est la différence entre (publickey) et (publickey,password) ?
Les parenthèses listent les méthodes que le serveur autorise encore. (publickey), c’est les clés uniquement ; (publickey,password) signifie qu’un mot de passe fonctionnerait aussi, vous auriez donc dû être invité — si vous ne l’avez pas été, votre client a abandonné après avoir épuisé les clés.
Ça marchait hier et ça échoue maintenant — qu’est-ce qui a changé ?
Un serveur reconstruit, une clé renouvelée, ou un agent qui a lâché la clé après un délai. Lancez d’abord ssh-add -l pour voir ce qui est chargé, puis vérifiez si la machine a été réinstallée (ce qui déclenche aussi host key verification failed (en anglais)).
Faites que ça cesse
Presque chaque coupable ci-dessus est un fait propre à l’hôte que vous ne devriez pas avoir à redéduire : quel utilisateur, quelle clé, quel port. Fixez-les dans ~/.ssh/config et cette classe d’erreurs disparaît en grande partie — et pour les erreurs qui restent, le décodeur couvre les neuf autres que vous rencontrerez.
Ces mêmes faits peuvent vivre dans un client plutôt que dans un fichier caché. Termalin stocke l’utilisateur, le port et la clé avec l’hôte enregistré, déverrouille vos clés une fois via son agent intégré (plus d’annulation de phrase secrète qui saute silencieusement une clé), vérifie l’identité du serveur à la première connexion, et affiche un état en direct par hôte — si bien que « est-ce seulement en ligne ? » et « est-ce que j’utilise la bonne clé ? » cessent d’être des étapes de diagnostic. Il importe aussi les sessions PuTTY (en anglais) directement, ce qui retire définitivement le coupable 5.
Termalin est un client SSH gratuit et multiplateforme qui garde les utilisateurs, ports et clés propres à chaque hôte avec l’hôte, et vérifie les serveurs à la première connexion — téléchargez-le, ou lisez comment il gère les clés en toute sécurité.