SSH « Permission denied (publickey) » : diagnostiquer la clé refusée sans activer les mots de passe

« Permission denied (publickey) » ne signifie pas forcément que la clé est invalide. Le message indique que le serveur n’a accepté aucune des identités proposées pour le compte demandé. La bonne méthode consiste à déterminer successivement quelle cible est réellement contactée, quelle clé le client offre, puis pourquoi le serveur la refuse.

Activer l’authentification par mot de passe, mettre les fichiers en chmod 777 ou régénérer toutes les clés masque le diagnostic et peut affaiblir la sécurité. Voici une procédure reproductible pour Linux, macOS et les clients OpenSSH récents.

Réponse rapide : le diagnostic en quatre questions

  1. Le client vise-t-il le bon hôte, le bon port et le bon utilisateur ?
  2. Offre-t-il réellement la clé privée attendue ?
  3. La clé publique correspondante est-elle autorisée pour ce compte sur le serveur ?
  4. Les journaux et la configuration effective de sshd expliquent-ils le refus ?

Cette séquence évite de modifier plusieurs variables à la fois. Gardez une session administrateur déjà ouverte pendant les tests : elle peut sauver l’accès si une configuration distante est modifiée par erreur.

1. Distinguer transport et authentification

Si le message final est bien Permission denied (publickey), la connexion réseau et l’échange SSH ont généralement déjà eu lieu. Ce n’est donc pas le même problème qu’un Connection refused, un délai d’attente ou une erreur de résolution DNS.

Commencez par afficher la configuration réellement calculée par le client après lecture de ~/.ssh/config, de la configuration système et des blocs Host ou Match :

ssh -G mon-serveur | grep -E '^(user|hostname|port|identityfile|identitiesonly) '

Contrôlez surtout user, hostname et port. Une clé correctement installée pour admin sera refusée si le client tente de se connecter comme root ou ubuntu. Un alias peut également pointer vers une ancienne adresse ou appliquer une clé inattendue.

2. Lire la trace du client sans exposer la clé privée

Lancez ensuite une connexion très verbeuse. Les options -v, -vv et -vvv augmentent progressivement le niveau de diagnostic :

ssh -vvv utilisateur@mon-serveur

Dans la sortie, cherchez notamment :

  • Reading configuration data : indique les fichiers de configuration lus ;
  • Connecting to : confirme l’adresse et le port ;
  • Offering public key : prouve qu’une clé est réellement proposée ;
  • Server accepts key : montre que le serveur reconnaît l’identité avant la signature ;
  • No more authentication methods to try : aucune identité proposée n’a abouti.

La trace peut contenir des noms d’hôtes, d’utilisateurs et des empreintes de clés. Elle ne doit pas révéler la clé privée elle-même, mais relisez-la avant de la publier dans un ticket ou un forum.

3. Isoler une seule clé avec IdentityFile et IdentitiesOnly

Quand plusieurs identités sont chargées dans ssh-agent, le client peut proposer des clés non pertinentes avant d’atteindre la bonne. Le serveur limite par ailleurs le nombre d’essais d’authentification. Pour un test propre, imposez une seule clé :

ssh -vvv -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 utilisateur@mon-serveur

IdentityFile désigne la clé à utiliser et IdentitiesOnly=yes empêche le client d’ajouter toutes les autres identités proposées par l’agent. Si cette commande fonctionne, le problème se situe probablement dans la sélection automatique des clés ou dans ~/.ssh/config, pas sur le serveur.

Pour voir les clés chargées dans l’agent et leurs empreintes SHA-256 :

ssh-add -l -E sha256

Si l’agent répond qu’il ne contient aucune identité, cela n’empêche pas forcément OpenSSH d’utiliser une clé portant un nom par défaut. En revanche, une clé enregistrée sous un nom personnalisé devra être indiquée avec -i ou déclarée dans la configuration.

4. Comparer les empreintes, pas les commentaires

Le commentaire situé à la fin d’une clé publique est seulement une étiquette. Deux fichiers peuvent porter le même commentaire sans contenir la même clé. Comparez plutôt leurs empreintes.

Côté client, affichez l’empreinte de la clé publique :

ssh-keygen -lf ~/.ssh/id_ed25519.pub -E sha256

Si le fichier .pub manque mais que la clé privée existe, dérivez la partie publique sans régénérer la paire :

ssh-keygen -y -f ~/.ssh/id_ed25519 | ssh-keygen -lf - -E sha256

Sur le serveur, connecté par une session de secours, comparez cette empreinte avec les clés autorisées pour le compte ciblé. Ne copiez jamais la clé privée sur le serveur.

5. Vérifier authorized_keys et ses permissions

Par défaut, OpenSSH cherche les clés utilisateur dans ~/.ssh/authorized_keys et ~/.ssh/authorized_keys2, mais la directive AuthorizedKeysFile peut changer ces chemins. Avant de modifier un fichier, vérifiez donc la configuration effective du serveur.

Pour une installation classique, inspectez sans rien changer :

namei -l /home/utilisateur/.ssh/authorized_keys
stat -c '%U:%G %a %n' /home/utilisateur /home/utilisateur/.ssh /home/utilisateur/.ssh/authorized_keys

Avec StrictModes yes, qui est la valeur par défaut, sshd contrôle le propriétaire et les permissions du dossier personnel et des fichiers d’authentification. Une base courante est :

  • le dossier ~/.ssh appartient à l’utilisateur et n’est accessible qu’à lui : mode 700 ;
  • authorized_keys appartient à l’utilisateur et n’est pas modifiable par le groupe ou les autres : mode 600 ;
  • le dossier personnel ne doit pas être modifiable par le groupe ou tout le monde.

N’appliquez pas ces valeurs à l’aveugle si les clés sont fournies par un annuaire, un montage réseau, un outil de gestion de configuration ou AuthorizedKeysCommand. Dans ces cas, le chemin et le propriétaire attendus peuvent être différents.

6. Lire le motif exact dans les journaux du serveur

Le client sait seulement que la clé a été refusée. Le serveur sait souvent pourquoi. Sur une machine utilisant systemd, le nom de l’unité varie selon la distribution :

sudo journalctl -u ssh -u sshd --since "10 minutes ago" --no-pager

Selon le système, consultez également /var/log/auth.log ou /var/log/secure. Cherchez des messages comme « bad ownership or modes », « user not allowed », « key type not in PubkeyAcceptedAlgorithms » ou un chemin authorized_keys inattendu.

Effectuez une tentative pendant que vous observez les journaux afin de corréler l’heure, l’adresse source et le compte visé. Cela évite d’interpréter une ancienne erreur comme le problème actuel.

7. Contrôler la configuration effective de sshd

Lire uniquement /etc/ssh/sshd_config ne suffit pas toujours : des fichiers inclus et des blocs Match peuvent modifier les règles pour un utilisateur ou une adresse précise.

Commencez par vérifier la syntaxe :

sudo sshd -t

Puis affichez les valeurs effectives importantes :

sudo sshd -T | grep -E '^(pubkeyauthentication|authorizedkeysfile|passwordauthentication|permitrootlogin|maxauthtries) '

Pour évaluer les blocs conditionnels, OpenSSH accepte aussi un contexte avec -C. Adaptez l’utilisateur, le nom du client et l’adresse source :

sudo sshd -T -C user=utilisateur,host=poste-client,addr=203.0.113.10 | grep -E '^(pubkeyauthentication|authorizedkeysfile|authenticationmethods|allowusers|allowgroups) '

Cette étape révèle notamment une authentification par clé désactivée pour un groupe, un chemin déplacé, une combinaison imposée par AuthenticationMethods ou une restriction AllowUsers/AllowGroups.

8. Ne pas confondre clé refusée et algorithme refusé

Une ancienne clé RSA peut encore être valide cryptographiquement tout en utilisant une méthode de signature désactivée par une politique récente. La trace -vvv et le journal serveur permettent de distinguer ce cas d’une clé absente.

Évitez de réactiver globalement un algorithme ancien pour « faire marcher » la connexion. Préférez une nouvelle clé moderne, par exemple Ed25519 lorsque l’environnement le prend en charge, puis déployez sa partie publique par un canal déjà authentifié. Une exception temporaire, si elle est indispensable, doit être limitée à l’hôte concerné et documentée.

Ce qu’il ne faut pas faire

  • Ne passez pas ~/.ssh ou authorized_keys en 777 : StrictModes peut justement les refuser, et vous exposez les fichiers aux autres utilisateurs.
  • N’activez pas PasswordAuthentication yes uniquement pour contourner le diagnostic.
  • Ne désactivez pas le contrôle de clé d’hôte : il protège contre la connexion au mauvais serveur et les interceptions.
  • Ne remplacez pas toutes les clés tant que vous ignorez laquelle est réellement proposée.
  • Ne redémarrez pas sshd après une modification sans avoir exécuté sshd -t et conservé une session de secours.

Arbre de décision minimal

  • Aucune ligne Offering public key : vérifier le chemin de la clé, ssh-agent, IdentityFile et l’utilisateur local.
  • La mauvaise clé est offerte : tester avec -i et IdentitiesOnly=yes, puis corriger ~/.ssh/config.
  • La bonne clé est offerte mais refusée : comparer l’empreinte, lire le journal serveur, contrôler AuthorizedKeysFile, le compte et les permissions.
  • La clé est acceptée mais la connexion échoue ensuite : examiner la signature, la phrase secrète, les restrictions de la ligne authorized_keys et les méthodes supplémentaires imposées.

Conclusion

Une erreur SSH par clé se résout plus vite en suivant la chaîne réelle : configuration calculée, clé offerte, empreinte autorisée, décision du serveur. Les commandes ssh -G, ssh -vvv, ssh-add -l, sshd -T et les journaux fournissent généralement assez d’éléments pour corriger la cause sans affaiblir l’accès distant.

Si le diagnostic doit être mené sur une machine de production sans couper l’accès, FuretSplick propose une assistance de diagnostic et de remise en service. Conservez dans tous les cas une voie d’administration de secours avant toute modification SSH.

Sources

Publications similaires