Aller au contenu
  • Accueil
  • Infrastructure
  • Datacenter
  • Services
    Nos services
    InfogéranceCloudHébergementIABare MetalHousingTransit IP
  • Blog
Contactez-nous
  1. Accueil
  2. /
  3. Blog
  4. /
  5. Permission denied (publickey) : lire ssh -v et trouver la cause

Linux
Sécurité
Administration

Permission denied (publickey) : lire ssh -v et trouver la cause

4 novembre 2026

12 min de lecture

Sommaire
Lire ssh -v, du compte à la clé
Sept clés dans l'agent, et la bonne jamais présentée
Signature ssh-rsa désactivée, clés DSA retirées
Le journal sshd, une fois sorti du niveau INFO
Quatre refus sans motif
Debian tolère ce qu'AlmaLinux refuse
PerSourcePenalties et fail2ban comptent les essais
PasswordAuthentication et StrictModes restent en place
Sources
$ ssh deploy@srv; echo "code retour : $?"
deploy@srv: Permission denied (publickey).
code retour : 255

Permission denied (publickey) veut dire que le client a épuisé ses clés sans aboutir et que le serveur ne propose pas d'autre méthode. Le message ne donne jamais la cause. ssh -v dit si la clé est partie et si le serveur l'a reconnue. Le journal de sshd dit pourquoi il l'a refusée.

La parenthèse liste les méthodes qui peuvent encore aboutir, au sens de la RFC 4252. Sur AlmaLinux 10, la même panne affiche (publickey,gssapi-keyex,gssapi-with-mic). Avec PubkeyAuthentication no dans un bloc Match et sans mot de passe, le client affiche Permission denied ()., liste vide.

Toutes les sorties viennent de nos conteneurs, sur une plage d'adresses de documentation : Debian 13 avec OpenSSH 10.0p2, AlmaLinux 10 avec openssh 9.9p1 pour comparer. La dernière version amont, la 10.6, date du 6 octobre 2026. Un libellé peut changer. Les blocs gardent les lignes utiles, sans l'horodatage des journaux.

Lire ssh -v, du compte à la clé

La première ligne utile, Authenticating to srv:22 as 'deploy', donne le compte réel, après ~/.ssh/config. Côté client, une faute de frappe ne se voit que là, car un compte inexistant reçoit le même refus. ssh -G deploy@srv affiche la configuration finale sans se connecter.

Un refus complet, avec une seule clé sur le poste et un serveur qui ne la connaît pas :

$ ssh -v deploy@srv
debug1: Authenticating to srv:22 as 'deploy'
debug1: Authentications that can continue: publickey
debug1: Will attempt key: /home/ops/.ssh/id_rsa
debug1: Will attempt key: /home/ops/.ssh/id_ed25519 ED25519 SHA256:RrJMN+vL5NKMt9X8f3yaGv3VTuIl2f+rkXh7uh14UQ0
debug1: Trying private key: /home/ops/.ssh/id_rsa
debug1: Offering public key: /home/ops/.ssh/id_ed25519 ED25519 SHA256:RrJMN+vL5NKMt9X8f3yaGv3VTuIl2f+rkXh7uh14UQ0
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
deploy@srv: Permission denied (publickey).

Will attempt key liste ce que le client compte essayer. Une ligne sans empreinte désigne en général un fichier absent du disque, et son Trying private key n'envoie alors rien au serveur. On cherche Offering public key, puis on lit ce qui suit.

Sans Offering, la clé n'est en général jamais partie. Avec un mauvais chemin, le client prévient par Warning: Identity file /home/ops/.ssh/nexistepas not accessible: No such file or directory., puis continue.

Si Authentications that can continue suit l'Offering, le serveur a dit non, sans motif, car la RFC 4252 ne lui laisse que ce refus ou l'acceptation. La suite se lit sur le serveur.

Si Server accepts key suit l'Offering et que Permission denied arrive quand même, le serveur a reconnu la clé : on regarde d'abord le poste. Une fin en Connection closed renvoie au journal : avec /etc/nologin, PAM coupe après l'acceptation.

Une clé privée en 644, avec son .pub à côté, donne ceci :

debug1: Offering public key: /home/ops/.ssh/id_ed25519 ED25519 SHA256:RrJMN+vL5NKMt9X8f3yaGv3VTuIl2f+rkXh7uh14UQ0
debug1: Server accepts key: /home/ops/.ssh/id_ed25519 ED25519 SHA256:RrJMN+vL5NKMt9X8f3yaGv3VTuIl2f+rkXh7uh14UQ0
Load key "/home/ops/.ssh/id_ed25519": bad permissions
debug1: No more authentication methods to try.

On corrige par chmod 600 sur la clé. Une connexion par clé à phrase de passe, sans terminal ni agent (reproduit avec BatchMode=yes, le cas d'un cron ou d'un job de CI), s'arrête au même endroit : Server accepts key, puis No more authentication methods to try. Il lui faut un agent accessible au job, ou une clé dédiée.

Sept clés dans l'agent, et la bonne jamais présentée

Sept clés dans l'agent, -i vers une huitième, MaxAuthTries par défaut, et le message change :

$ ssh -v -i ~/.ssh/id_prod deploy@srv
debug1: Will attempt key: k1 ED25519 SHA256:DPXBrVTxyhnVmj9nD7dPO8arnBV/M7yP6ZOjYLhN4Ps agent
debug1: Will attempt key: /home/ops/.ssh/id_prod ED25519 SHA256:ZCa9oWi9rErs4RgHPLGie8UNGMCFch1GFZHMW6JFAPo explicit
debug1: Offering public key: k6 ED25519 SHA256:Z9aXHSwUeld/WUQgEdjIWlp/2jFmRC9js0r+jsDmCZY agent
Received disconnect from 198.51.100.2 port 22:2: Too many authentication failures

-i n'écarte pas l'agent, et la clé demandée passe ici après ses sept clés. Avec -o IdentitiesOnly=yes, seule id_prod est présentée et la connexion aboutit. À poser avec IdentityFile dans le bloc Host de ~/.ssh/config, à côté de l'agent et des options client.

La limite vient de MaxAuthTries, 6 par défaut d'après le manuel. Notre guide de durcissement recommande 3. Mesuré à cette valeur, deux clés dans l'agent passent et trois coupent la connexion avant id_prod. On garde 3 et on corrige le client. D'après ses notes, OpenSSH 10.6 ne compte plus les 6 premiers tests de clé dans cette limite (PubkeyOptions max-pk-ok, non testé ici).

Signature ssh-rsa désactivée, clés DSA retirées

Notre clé RSA de 3072 bits passe sans réglage, car le client signe en rsa-sha2. OpenSSH 8.8 (26 septembre 2021) a désactivé par défaut la signature SHA-1 ssh-rsa. Dans les deux sens, aucune ligne Offering :

debug1: Skipping ssh-rsa key /home/ops/.ssh/id_rsa_vieux - corresponding algorithm not supported by server
debug1: No more authentication methods to try.

Cette sortie vient d'un client limité à ssh-rsa. Le cas inverse, un serveur qui n'annonce que server-sig-algs=<ssh-rsa>, donne lui aussi un refus sans Offering, et c'est cette ligne qu'il faut lire. Les notes de la 8.8 donnent PubkeyAcceptedAlgorithms +ssh-rsa comme solution d'attente. On ne le pose que le temps de remplacer la machine trop ancienne, dans un bloc Host ciblé. Pour DSA, plus de contournement : OpenSSH 10.0 a retiré l'algorithme, il faut une nouvelle clé.

Le journal sshd, une fois sorti du niveau INFO

Les refus se lisent dans /var/log/auth.log sur Debian et /var/log/secure sur la famille Red Hat quand rsyslog tourne, ou par journalctl -u ssh et journalctl -u sshd selon le nom de l'unité. Depuis OpenSSH 9.8, ces lignes viennent de sshd-session, séparé de sshd, donc un filtre sur sshd[ les rate. Les notes de la 10.0 préviennent que certaines peuvent aussi porter sshd-auth.

Au niveau INFO, valeur par défaut, une clé inconnue ne laisse que ceci :

srv sshd-session[4476]: Connection closed by authenticating user deploy 198.51.100.3 port 56846 [preauth]

On monte d'un cran le temps du diagnostic. VERBOSE suffit, le manuel déconseille DEBUG parce qu'il viole la vie privée des utilisateurs. La première valeur lue gagne, d'où le préfixe 00-. Sur la famille Red Hat, l'unité s'appelle sshd :

echo 'LogLevel VERBOSE' | sudo tee /etc/ssh/sshd_config.d/00-diag.conf
sudo sshd -t && sudo systemctl reload ssh
sudo sshd -T | grep -i '^loglevel'

Le refus porte alors une empreinte, à comparer à celle de la clé locale, puis à celles du fichier sur le serveur :

srv sshd-session[4706]: Failed publickey for deploy from 198.51.100.3 port 51014 ssh2: ED25519 SHA256:ZCa9oWi9rErs4RgHPLGie8UNGMCFch1GFZHMW6JFAPo

$ ssh-keygen -lf ~/.ssh/id_prod.pub
256 SHA256:ZCa9oWi9rErs4RgHPLGie8UNGMCFch1GFZHMW6JFAPo prod (ED25519)

$ sudo ssh-keygen -lf /home/deploy/.ssh/authorized_keys
256 SHA256:RrJMN+vL5NKMt9X8f3yaGv3VTuIl2f+rkXh7uh14UQ0 ops@cli (ED25519)

L'empreinte n'y est pas. La bonne clé n'a pas été déposée. Quand tout va bien, VERBOSE donne le fichier et la ligne : Accepted key ED25519 SHA256:... found at /home/deploy/.ssh/authorized_keys:1.

Les autres motifs sont explicites et sortent dès le niveau INFO :

Ligne du journalCause reproduiteCorrection
Authentication refused: bad ownership or modes for directory /home/deploy/.ssh.ssh en 777chmod 700
Authentication refused: bad ownership or modes for file /home/deploy/.ssh/authorized_keysfichier en 666 ou à un autre comptechmod 600, chown
Could not open user 'deploy' authorized keys '/home/deploy/.ssh/authorized_keys': Permission deniedfichier en 600 à root, déposé avec sudochown deploy:deploy
/home/deploy/.ssh/authorized_keys:1: Authentication tried for deploy with correct key but not from a permitted host (host=198.51.100.3, ip=198.51.100.3, required=203.0.113.10)option from= sur la clévérifier l'adresse source, NAT et bastion compris
User deploy from 198.51.100.3 not allowed because not listed in AllowUsersAllowUsers ; AllowGroups donne none of user's groups are listed in AllowGroupsajouter le compte si son accès est légitime
Invalid user dpeloy from 198.51.100.3 port 38834compte inexistant ou faute de frappecorriger le compte
userauth_pubkey: signature algorithm ssh-ed25519 not in PubkeyAcceptedAlgorithms [preauth]serveur restreint aux clés matériellesprésenter une clé du type exigé

Pour la dernière ligne, le client avait un indice dès ssh -v : server-sig-algs=<sk-ssh-ed25519@openssh.com>. C'est le comportement voulu d'un bastion réservé à FIDO2, on n'élargit pas la liste.

Quatre refus sans motif

Quatre situations donnent un Failed publickey nu, même en VERBOSE : clé absente, AuthorizedKeysFile pointant ailleurs, .ssh en 700 appartenant à root, clé repliée sur plusieurs lignes par un copier-coller. On vérifie à la main.

La configuration effective pour ce compte, blocs Match appliqués, ici avec le bloc de l'introduction :

$ sudo sshd -T -C user=deploy,host=cli,addr=198.51.100.3 | grep -E '^(pubkeyauthentication|authorizedkeysfile) '
pubkeyauthentication no
authorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2

Le contenu du fichier, puis le chemin élément par élément avec un essai de lecture sous le compte cible :

$ sudo ssh-keygen -lf /home/deploy/.ssh/authorized_keys
/home/deploy/.ssh/authorized_keys is not a public key file.

$ sudo namei -l /home/deploy/.ssh/authorized_keys
drwxr-xr-x deploy deploy deploy
drwx------ root   root   .ssh
-rw------- deploy deploy authorized_keys
$ sudo su -s /bin/sh deploy -c "cat /home/deploy/.ssh/authorized_keys >/dev/null"
cat: /home/deploy/.ssh/authorized_keys: Permission denied

Reste SELinux sur la famille Red Hat, impossible à tester dans nos conteneurs. Un ticket Red Hat de 2009, clos en NOTABUG, documente un refus avc: denied { read } sur authorized_keys : répertoire personnel mal étiqueté, à reprendre par restorecon -R -v. ls -Z montre le contexte, et notre article sur SELinux situe ssh_home_t. Passer en mode permissif laisse le répertoire mal étiqueté.

Debian tolère ce qu'AlmaLinux refuse

Sur Debian 13, un répertoire personnel en 775 et un authorized_keys en 664 passent, tant que le groupe deploy ne contient que le compte deploy. Avec un second membre, les mêmes droits déclenchent bad ownership or modes. Le correctif vient de Debian, user-group-modes.patch, et l'amont l'a refusé.

Sur AlmaLinux 10, ces droits échouent d'emblée. Un provisioning validé sur Debian peut donc casser ailleurs, ou plus tard, à l'ajout d'un membre dans un groupe. Les deux acceptent en revanche un fichier en 644, y compris appartenant à root, et un répertoire personnel en 755. La cible reste celle du manuel : .ssh et fichier accessibles au seul propriétaire.

Sans mot de passe ni clé déjà acceptée, ssh-copy-id ne peut plus rien déposer. Le dépôt passe par la console ou un compte d'administration :

sudo install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
sudo install -m 600 -o deploy -g deploy cle.pub /home/deploy/.ssh/authorized_keys

Le second install écrase les clés déjà présentes. Sur un fichier existant, on ajoute avec sudo -u deploy tee -a /home/deploy/.ssh/authorized_keys < cle.pub, après avoir vérifié que le fichier finit par un saut de ligne, sinon la clé se colle à la précédente.

PerSourcePenalties et fail2ban comptent les essais

Depuis OpenSSH 9.8, PerSourcePenalties est actif par défaut. Un échec coûte 5 secondes à l'adresse source, et le refus commence à 15 secondes cumulées. Une boucle sur notre serveur :

4: deploy@srv: Permission denied (publickey).
5: Connection closed by 198.51.100.2 port 22
6: Connection closed by 198.51.100.2 port 22

srv sshd[4252]: drop connection #0 from [198.51.100.3]:58746 on [198.51.100.2]:22 penalty: failed authentication

Selon les séries, Connection reset by remplace ce message, dès le cinquième ou le sixième essai. On croit alors à une panne réseau. Espacés de 6 secondes, huit essais vont tous jusqu'au refus de clé. Un essai à la fois, journal ouvert à côté, évite le problème. PerSourcePenaltyExemptList lève cette pénalité pour une adresse : à retirer ensuite.

Pour fail2ban, mesuré avec fail2ban-regex et le filtre par défaut de la version 1.1.0 : un refus de clé sur un compte existant et un bad ownership ne comptent pas (0 ligne retenue). Un compte inexistant, un refus AllowUsers et le dépassement de MaxAuthTries comptent chacun pour une. Le jail.conf de Debian fixe maxretry à 5 sur 10 minutes. Cinq fautes de frappe atteignent le seuil : notre jail de test, avec une action factice, a banni l'adresse au cinquième essai, rapproché ou espacé de 6 secondes.

PasswordAuthentication et StrictModes restent en place

On croise le conseil de repasser PasswordAuthentication à yes pour faire passer la connexion. Il ne répare rien : la clé reste refusée, et le serveur se rouvre aux essais de mots de passe que le durcissement avait fermés. Si l'accès est perdu, on passe par la console.

Même chose pour StrictModes no. D'après le manuel de sshd, un fichier, un .ssh ou un répertoire personnel modifiable par d'autres leur laisse ajouter leur clé, ce que ce contrôle bloque. Le couper ne traite que bad ownership or modes, que chmod et chown règlent. Sur un parc où ces fichiers donnent trop de travail, les certificats d'une CA SSH suppriment le sujet.

La cause trouvée, on retire 00-diag.conf et on recharge, une session gardée ouverte, puis on contrôle que sshd -T affiche de nouveau loglevel INFO.

Sources

  • ssh(1) : -v, -i, -G, droits de la clé privée
  • ssh_config(5) : IdentitiesOnly, IdentityFile
  • sshd_config(5) : MaxAuthTries, StrictModes, LogLevel, PerSourcePenalties
  • sshd(8) : droits recommandés, option from=
  • RFC 4252 : méthodes qui peuvent continuer
  • OpenSSH 8.8 : RSA/SHA-1 désactivé, contournement temporaire
  • OpenSSH 9.8 : PerSourcePenalties, sshd-session
  • Historique OpenSSH : 10.6 et max-pk-ok, DSA et sshd-auth en 10.0
  • Correctif Debian user-group-modes : écriture de groupe tolérée, refus en amont
  • Filtre sshd de fail2ban : publickey = nofail
  • Ticket Red Hat 499343 : refus SELinux sur authorized_keys, restorecon

Besoin d'aide sur ce sujet ?

Notre équipe d'experts est là pour vous accompagner dans vos projets d'infrastructure et d'infogérance.

Contactez-nous

Articles similaires

AIDE : intégrité des fichiers Linux contre rootkits et compromissions
Sécurité
Linux
Administration
Sécurité
Linux
Administration

AIDE : intégrité des fichiers Linux contre rootkits et compromissions

Configurer AIDE pour détecter modifications fichiers système, baseline, comparaisons, intégration cron et alerting. Outil d'intégrité Linux historique, toujours utilisé en production.

14 juin 2026
Lire plus
auditd et ausearch : audit kernel Linux pour la conformité
Sécurité
Linux
Administration
Sécurité
Linux
Administration

auditd et ausearch : audit kernel Linux pour la conformité

Configurer auditd, écrire des règles audit, requêter avec ausearch et aureport. Audit syscalls et fichiers, intégration SIEM, conformité PCI/CIS, retours ops.

13 juin 2026
Lire plus
systemd-cryptenroll et TPM2 : déchiffrement automatique LUKS
Sécurité
Linux
Administration
Sécurité
Linux
Administration

systemd-cryptenroll et TPM2 : déchiffrement automatique LUKS

Lier une partition LUKS au TPM2 de la machine avec systemd-cryptenroll. Déchiffrement automatique au boot, attestation Secure Boot, sealing PCR, retours ops.

8 juin 2026
Lire plus

SHPV, votre partenaire de confiance en infrastructure et infogérance informatique en France.

SHPV
Contactez-nousNous contacterBlog
Expertise
InfrastructureDatacenterInfogéranceCloudHébergementTransit IPIABare MetalHousing
Légales
Conditions Générales de VenteCPS - Contrat de ServicesCPS - Hébergement CloudCPS - Microsoft 365Accord sous-traitance RGPDTarifs interventions

SHPV © 2026 - Tous droits réservés

Mentions légalesPolitiques de confidentialité
SHPV FRANCE - SAS au capital de 16 000 € - 52 Rue Romain Rolland, 71230 Saint-Vallier - SIRET n°80886287400035 - R.C.S. Chalon-sur-Saône. Par téléphone 09 72 310 818 - Email: support@shpv.fr