CyberSDF

Reprenez la main sur votre numérique

Permission denied (publickey) : diagnostiquer la clé SSH

un poste de travail sobre vu de trois quarts, ecran eteint, clavier mecanique, carnet ouvert

Une connexion par clé qui échoue se termine par la ligne alice@192.0.2.10: Permission denied (publickey)., écrite par le client alors que la décision est prise par le serveur : sshd a reçu une clé publique et n’a validé aucune ligne des fichiers autorisés. Debian 12 fournit OpenSSH 9.2p1 (paquet 1:9.2p1-2+deb12u6), Ubuntu 24.04 LTS fournit OpenSSH 9.6p1 (paquet 9.6p1-3ubuntu13) ; sur ces deux systèmes, la cause se lit en croisant la trace ssh -v du client et le journal /var/log/auth.log du serveur.

Sommaire
  1. La clé publique est testée avant d’être signée, et un test refusé ne s’écrit pas dans le journal
  2. Arbre des huit causes, dans l’ordre où les tester
  3. StrictModes refuse l’écriture de groupe, pas la lecture
  4. Le piège : avec LogLevel INFO, une clé inconnue ne laisse aucune ligne
  5. Depuis OpenSSH 8.8, la signature ssh-rsa (SHA-1) n’est plus acceptée par défaut
  6. MaxAuthTries à 6 : un agent chargé coupe la connexion avant la bonne clé
  7. Cinq questions qui reviennent

La clé publique est testée avant d’être signée, et un test refusé ne s’écrit pas dans le journal

Avant de produire une signature, ssh envoie la clé publique seule, en « test », et le serveur répond s’il l’accepte ou non. Une clé absente des fichiers autorisés reçoit une réponse négative que sshd n’enregistre pas au niveau de journalisation par défaut, LogLevel INFO. Le premier relevé utile est donc la trace du client, complétée par la configuration que le serveur applique réellement.

  1. Rejouer la connexion avec le détail de niveau 1.

    ssh -v alice@192.0.2.10
    

    Deux lignes commandent le diagnostic : debug1: Offering public key: /home/alice/.ssh/id_ed25519 ED25519 SHA256:... indique une clé proposée, et debug1: Server accepts key: ... indique que sshd a reconnu cette clé publique dans un fichier autorisé. Sans la seconde ligne, la panne est dans le fichier ou dans les droits, côté serveur. Avec la seconde ligne, la clé est connue et le refus vient d’ailleurs : options de la ligne, compte, agent.

  2. Interroger le serveur sur sa configuration effective, en root.

    sudo sshd -T | grep -iE 'pubkeyauthentication|authorizedkeysfile|strictmodes|pubkeyacceptedalgorithms|permitrootlogin'
    

    sshd -T valide le fichier puis imprime la configuration retenue. Sur une installation Debian ou Ubuntu non modifiée, la sortie contient pubkeyauthentication yes, authorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2, strictmodes yes et un permitrootlogin à prohibit-password. Ces valeurs sont celles documentées par sshd_config(5) ; si l’une diffère, le refus vient de là.

  3. Rejouer la même commande avec les paramètres d’une connexion, pour voir l’effet d’un bloc Match.

    sudo sshd -T -C user=alice,addr=203.0.113.5,host=portable
    

    L’option -C applique les blocs Match correspondants avant l’affichage. Un pubkeyauthentication no ou un authorizedkeysfile déplacé peut apparaître ici alors qu’il est invisible dans la lecture du fichier global, puisque la première valeur rencontrée l’emporte dans sshd_config.

Arbre des huit causes, dans l’ordre où les tester

Les huit branches ci-dessous couvrent les cas rencontrés sur un serveur Debian ou Ubuntu standard. Chaque question se tranche avec la sortie de ssh -v, et chaque feuille correspond à une ligne précise du journal serveur ou du client.

« Offering public key » apparait ?
├─ NON
│   ├─ « Will attempt key » absent ..................... 1. aucune clé candidate (agent vide, IdentityFile)
│   ├─ « Permissions ... are too open » ................ 2. clé privée locale ignorée
│   └─ « no mutual signature algorithm » ............... 3. algorithme ssh-rsa retiré des défauts (OpenSSH >= 8.8)
└─ OUI
    └─ « Server accepts key » apparait ?
        ├─ NON
        │   ├─ rien dans auth.log sauf [preauth] ........ 4. clé absente du fichier lu (compte ou chemin)
        │   ├─ « Authentication refused: bad ownership ... » . 5. droits du home, de ~/.ssh ou du fichier
        │   ├─ « correct key but not from a permitted host » . 6. option from= sur la ligne
        │   └─ « Invalid user » ou « not listed in AllowUsers » . 7. compte refusé
        └─ OUI
            └─ « agent refused operation » ............. 8. phrase secrète, agent qui refuse de signer
Cas Message côté client Message côté serveur Vérification Correction
1. Aucune clé candidate Will attempt key absent de la trace aucune ligne liée à une clé ls -l ~/.ssh/id_* générer une clé avec ssh-keygen -t ed25519
2. Clé privée ignorée Permissions 0644 for '...' are too open. rien, le client n’envoie pas la clé stat -c '%a %n' ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519
3. Algorithme refusé no mutual signature algorithm userauth_pubkey: signature algorithm ssh-rsa not in PubkeyAcceptedAlgorithms ssh -Q PubkeyAcceptedAlgorithms | grep -c '^ssh-rsa$' (attendu : 0) clé ed25519, ou PubkeyAcceptedAlgorithms +ssh-rsa en dépannage
4. Clé absente du fichier Server accepts key absent connexion terminée par [preauth] sans ligne Failed publickey grep -c "$(cut -d' ' -f2 ~/.ssh/id_ed25519.pub)" /home/alice/.ssh/authorized_keys (attendu : 1) réinstaller la clé avec ssh-copy-id -i ~/.ssh/id_ed25519.pub alice@192.0.2.10
5. Droits refusés trace inchangée, aucun message spécifique Authentication refused: bad ownership or modes for directory /home/alice ls -ld /home/alice /home/alice/.ssh chmod go-w sur les trois niveaux
6. Ligne restreinte Server accepts key absent Authentication tried for alice with correct key but not from a permitted host grep -n 'from=' /home/alice/.ssh/authorized_keys assouplir ou retirer l’option from=
7. Compte refusé Server accepts key absent ou suivi d’un refus Invalid user alice from 203.0.113.5 port 51234 ou not allowed because not listed in AllowUsers getent passwd alice et sudo sshd -T -C user=alice,addr=203.0.113.5,host=portable corriger le nom du compte, la règle AllowUsers ou supprimer /etc/nologin
8. Signature refusée par l’agent sign_and_send_pubkey: signing failed for RSA "..." from agent: agent refused operation Failed publickey for alice from 203.0.113.5 port 51234 ssh2 une fois le compteur d’échecs à trois ssh-add -l déverrouiller la clé, ou contourner l’agent avec -o IdentitiesOnly=yes -i

StrictModes refuse l’écriture de groupe, pas la lecture

Le contrôle de droits ne compare pas le mode à 0600 : il refuse toute écriture par le groupe ou par les autres. Dans le code d’OpenSSH, la fonction safe_path() rejette un composant dont le mode contient les bits 022, et safe_path() remonte du fichier jusqu’au répertoire personnel inclus. Un authorized_keys en 0644 et un ~/.ssh en 0755 sont donc acceptés, alors qu’un répertoire personnel en 0775 (fréquent sur un groupe partagé ou après un chmod -R trop large) fait échouer l’authentification. Le répertoire /home lui-même n’est pas vérifié, la boucle s’arrêtant au répertoire personnel.

Le message n’apparaît que dans le journal du serveur, en clair :

Authentication refused: bad ownership or modes for directory /home/alice

La variante vise le fichier quand c’est lui qui est concerné :

Authentication refused: bad ownership or modes for file /home/alice/.ssh/authorized_keys

La vérification tient en deux commandes, à lancer sur le serveur avec le compte concerné.

ls -ld /home/alice /home/alice/.ssh
ls -l /home/alice/.ssh/authorized_keys

Attendu sur Debian et Ubuntu : drwxr-xr-x pour le répertoire personnel, drwx------ pour .ssh, -rw------- pour le fichier. Aucun w en deuxième ou troisième position ne doit apparaître. La correction rétablit la propriété puis retire l’écriture collective :

sudo chown -R alice:alice /home/alice/.ssh
chmod go-w /home/alice /home/alice/.ssh /home/alice/.ssh/authorized_keys

Aucun redémarrage n’est nécessaire : sshd ouvre authorized_keys et recontrôle les droits à chaque tentative d’authentification, la connexion suivante suffit. Le comportement est réglable par la directive StrictModes, dont la valeur par défaut est yes.

Le piège : avec LogLevel INFO, une clé inconnue ne laisse aucune ligne

Le journal d’authentification est souvent vide alors que la connexion échoue à répétition, et ce n’est pas une anomalie. Dans auth.c, sshd écrit les échecs d’authentification au niveau VERBOSE et ne remonte au niveau INFO que dans quatre cas : authentification réussie, utilisateur inexistant, méthode mot de passe, ou nombre d’échecs supérieur ou égal à la moitié de MaxAuthTries. Comme MaxAuthTries vaut 6 par défaut, les deux premiers échecs d’une clé sont perdus, et un test de clé refusé n’incrémente même pas le compteur.

Pour rendre ces refus visibles, la journalisation se relève temporairement dans /etc/ssh/sshd_config :

LogLevel VERBOSE

Puis on recharge le service, ce qui revient à envoyer un SIGHUP, signal sur lequel sshd relit sa configuration :

sudo systemctl reload ssh

La tentative suivante laisse cette ligne dans /var/log/auth.log lorsque la clé n’est pas dans le fichier :

Failed publickey for alice from 203.0.113.5 port 51234 ssh2

Quand une signature a réellement été tentée et refusée, la même ligne porte l’empreinte :

Failed publickey for alice from 203.0.113.5 port 51234 ssh2: RSA SHA256:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU

L’empreinte affichée ici est celle de la clé publique proposée, et elle se compare à celle du client avec ssh-keygen -lf ~/.ssh/id_ed25519.pub, qui affiche le SHA256 par défaut. À l’inverse, une réussite produit Accepted publickey for alice from 203.0.113.5 port 51234 ssh2: ED25519 SHA256:.... Remettre ensuite LogLevel INFO : les niveaux DEBUG, eux, ne sont pas recommandés pour un usage courant.

Depuis OpenSSH 8.8, la signature ssh-rsa (SHA-1) n’est plus acceptée par défaut

Les notes de version d’OpenSSH 8.8, publiées le 26 septembre 2021, annoncent que cette version « disables RSA signatures using the SHA-1 hash algorithm by default ». Le changement ne supprime pas les clés RSA, qui continuent de signer avec rsa-sha2-512 ou rsa-sha2-256 depuis OpenSSH 7.2, mais il casse le dialogue avec un client ou un serveur ancien qui ne sait signer qu’en SHA-1. Les deux traces sont alors :

userauth_pubkey: signature algorithm ssh-rsa not in PubkeyAcceptedAlgorithms
debug1: no mutual signature algorithm

La liste effectivement acceptée par le client se lit avec ssh -Q PubkeyAcceptedAlgorithms ; la liste serveur figure dans la sortie de sshd -T à la ligne pubkeyacceptedalgorithms. Le remède durable est une clé dont l’algorithme n’est pas en cause :

ssh-keygen -t ed25519

Le dépannage temporaire, recommandé par les notes de version elles-mêmes, s’écrit dans ~/.ssh/config et ne concerne que l’hôte ancien :

Host vieux-serveur
    PubkeyAcceptedAlgorithms +ssh-rsa
    HostkeyAlgorithms +ssh-rsa

Un second écart de version mérite d’être connu : OpenSSH 10.0, publié en avril 2025 et livré par Debian 13 sous la version 1:10.0p1-7, retire complètement le support des clés DSA, désactivées par défaut depuis 2015. Sur Debian 12 et Ubuntu 24.04, une clé ssh-dss reste refusée en pratique, l’algorithme ayant disparu des listes par défaut bien avant la suppression du code.

MaxAuthTries à 6 : un agent chargé coupe la connexion avant la bonne clé

Chaque clé proposée consomme une tentative, et le serveur coupe la connexion au sixième échec, valeur par défaut de MaxAuthTries. Un agent qui contient huit clés épuise le quota avant d’atteindre celle qui est installée. Le serveur écrit alors :

maximum authentication attempts exceeded for alice from 203.0.113.5 port 51234 ssh2

et le client affiche Received disconnect from 192.0.2.10 port 22: Too many authentication failures. La liste des clés chargées se lit avec ssh-add -l. Le correctif côté client limite l’offre à la seule clé voulue, dans ~/.ssh/config :

Host 192.0.2.10
    IdentitiesOnly yes
    IdentityFile ~/.ssh/id_ed25519

La même contrainte s’obtient sans toucher au fichier de configuration, avec ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 alice@192.0.2.10. Les directives IdentityFile et IdentitiesOnly sont décrites dans ssh_config(5), et IdentitiesOnly yes empêche l’agent d’ajouter ses propres clés à la liste des candidates.

Cinq questions qui reviennent

Faut-il redémarrer sshd après avoir corrigé les droits de ~/.ssh ?

Non. Les fichiers authorized_keys et leurs droits sont contrôlés à chaque tentative d’authentification, une nouvelle commande ssh suffit à vérifier la correction. Une modification de sshd_config, elle, demande sudo systemctl reload ssh sur Debian et Ubuntu, sshd relisant sa configuration sur SIGHUP.

Pourquoi aucune ligne « Failed publickey » n’apparaît-elle dans /var/log/auth.log ?

Parce que ces échecs sont écrits au niveau VERBOSE et que la valeur par défaut est LogLevel INFO : le premier échec d’une clé connue n’est enregistré qu’à partir du troisième, la moitié de MaxAuthTries. Un test de clé refusé, lui, ne compte même pas comme échec. Passer temporairement à LogLevel VERBOSE, recharger le service, reproduire l’échec, puis revenir à INFO.

Comment savoir si le serveur a reçu la clé attendue ?

ssh -v affiche l’empreinte SHA256 dans la ligne « Offering public key », et ssh-keygen -lf ~/.ssh/id_ed25519.pub donne la même empreinte pour le fichier local. Côté serveur, la comparaison se fait sur la partie base64 : grep -c "$(cut -d' ' -f2 ~/.ssh/id_ed25519.pub)" /home/alice/.ssh/authorized_keys doit renvoyer au moins 1.

La clé fonctionne pour le compte git mais pas pour mon compte, pourquoi ?

Les fichiers sont lus par utilisateur : authorized_keys est cherché dans le répertoire personnel du compte demandé, et un compte de service possède souvent son propre fichier. Vérifier le nom exact du compte avec getent passwd, puis la valeur d’authorizedkeysfile renvoyée par sshd -T.

Peut-on désactiver StrictModes pour se dépanner ?

Techniquement, StrictModes no laisse sshd accepter un fichier modifiable par d’autres, ce que le manuel déconseille puisque n’importe qui pourrait alors ajouter sa clé. Le geste propre reste chmod go-w /home/alice /home/alice/.ssh /home/alice/.ssh/authorized_keys, complété si besoin par chown -R alice:alice /home/alice/.ssh.

Sources : OpenSSH 8.8, notes de version du 26 septembre 2021, désactivation des signatures RSA/SHA-1, sshd_config(5), valeurs par défaut de PubkeyAuthentication, AuthorizedKeysFile, StrictModes, MaxAuthTries et PermitRootLogin, sshd(8), version 1:9.2p1-2+deb12u6, options -T et -C, format du fichier authorized_keys, /etc/nologin, ssh-keygen(1), option -l et empreinte SHA256 par défaut, ssh-copy-id(1), copie de la clé dans ~/.ssh/authorized_keys, code source OpenSSH, fichiers auth.c, auth2.c, auth2-pubkey.c, auth2-pubkeyfile.c et misc.c pour les messages cités. Versions relevées : openssh-server 9.6p1-3ubuntu13 sous Ubuntu 24.04 LTS, 1:10.0p1-7 sous Debian 13.