Come risolvere SSH: Permission denied (publickey)
L’errore Permission denied (publickey) può avere cinque cause. Leggi l’output di ssh -v per identificarla e correggila senza perdere l’accesso al server.
Che cosa significa realmente Permission denied (publickey)
Permission denied (publickey) significa che il client ha inviato una o più chiavi pubbliche e il server non ne ha accettata nessuna. La rete funziona e sshd è in esecuzione: il rifiuto avviene nell'ultima fase dell'autenticazione. Se la sessione si interrompe prima di questo punto, il problema è connection refused o connection timed out, una diagnosi diversa che richiede verifiche differenti. La correzione non si basa su supposizioni, perché ssh -v indica quale delle cinque cause è presente.
Le parole tra parentesi indicano i metodi che il server era disposto ad accettare. Permission denied (publickey) da solo significa che l'accesso con password è disabilitato su quel server, quindi non è possibile usare una password come alternativa. Permission denied (publickey,password) significa che le password erano disponibili, ma anche quei tentativi di autenticazione non sono riusciti.
Un solo messaggio copre cinque problemi distinti ed è volutamente generico. Se il server rispondesse "utente inesistente" o "questa chiave non è installata", fornirebbe informazioni utili a chi cerca account validi. Non iniziare quindi a sostituire chiavi e modificare file di configurazione. Esegui un comando, leggi tre righe dell'output e riduci le cinque possibili cause a una sola.
Esegui prima ssh -v e leggi tre righe
Ripeti il comando che ha restituito l'errore, aggiungendo -v:
ssh -v deploy@203.0.113.10Un'esecuzione ridotta ma realistica è simile a questa:
OpenSSH_9.6p1 Ubuntu-3ubuntu13, OpenSSL 3.0.13 30 Jan 2024
debug1: Connecting to 203.0.113.10 [203.0.113.10] port 22.
debug1: Connection established.
debug1: Authenticating to 203.0.113.10:22 as 'deploy'
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Will attempt key: /home/you/.ssh/id_ed25519 ED25519 SHA256:0eL/8sBw... agent
debug1: Offering public key: /home/you/.ssh/id_ed25519 ED25519 SHA256:0eL/8sBw... agent
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
deploy@203.0.113.10: Permission denied (publickey).Tre righe contengono tutte le informazioni necessarie.
Authenticating to 203.0.113.10:22 as 'deploy' è il nome utente che verrà effettivamente usato. Non quello che intendevi usare, ma quello determinato da ssh in base alla riga di comando, a ~/.ssh/config oppure al nome dell'utente con cui hai effettuato l'accesso locale.
Authentications that can continue: publickey è l'elenco dei metodi accettati dal server, inviato prima di qualsiasi tentativo con una chiave. Se publickey non compare nel primo elenco, il server ha disabilitato l'accesso con chiave pubblica. Di conseguenza, nessuna chiave potrà funzionare.
Offering public key: ... contiene una riga per ogni chiave effettivamente inviata dal client, con il nome del file di origine e la relativa impronta SHA256. Una chiave priva della riga Offering non è mai stata inviata al server.
Ora dividi il problema in due casi:
- Non esiste alcuna riga
Offering public keyper la chiave prevista. Il problema è sul computer locale, perché il server non ha mai ricevuto la chiave. - La chiave viene offerta e compare nuovamente
Authentications that can continue: publickey. Il server ha ricevuto la chiave, ma l'ha rifiutata. Il problema è quindi sul server.
Le cause riportate di seguito sono ordinate in base alla frequenza con cui risultano essere la spiegazione del problema.
Causa 1: ti connetti con il nome utente sbagliato
La causa più comune è anche la meno interessante. sshd, il demone server SSH (secure shell), non comunica mai che un account non esiste. Esegue l'intero scambio per un nome utente inventato e rifiuta la connessione alla fine con lo stesso messaggio, perché divulgare nomi di account validi aiuta un attaccante. Un errore di battitura nel nome utente appare esattamente come una chiave non funzionante.
Controlla la riga Authenticating to ... as prima di ogni altra cosa. Se indica l'account usato per accedere al laptop invece dell'account sul server, hai omesso il nome utente dal comando.
ssh -v deploy@203.0.113.10
ssh -v root@203.0.113.10L'account predefinito dipende dall'immagine preparata dal provider. Ad agosto 2026, le immagini cloud Ubuntu usano generalmente un account ubuntu, quelle Debian usano debian o admin, Rocky Linux e AlmaLinux usano rocky e almalinux, mentre molti provider VPS installano direttamente la tua chiave in root. Il pannello di controllo del provider indica quale account è stato creato. Nessun comando eseguito dall'esterno del server può recuperare questa informazione.
Un blocco Host in ~/.ssh/config imposta anch'esso il nome utente e ha la precedenza sul nome dell'account locale:
Host vps-prod
HostName 203.0.113.10
User deploySe hai creato tu l'account e poi non hai potuto accedere con quell'account, probabilmente la chiave è stata installata per l'utente predefinito dell'immagine e non è mai stata copiata nel nuovo account. Questo passaggio fa parte di primi dieci minuti su un nuovo VPS ed è facile saltarlo.
Causa 2: la chiave che pensi di inviare non è quella effettivamente utilizzata
Per impostazione predefinita, ssh offre soltanto le chiavi gestite da ssh-agent e un insieme fisso di nomi di file in ~/.ssh: id_ed25519, id_ecdsa, id_rsa e le varianti hardware e DSA di questi nomi. Una chiave salvata come ~/.ssh/vps-prod non è visibile a ssh finché non la specifichi. Per questo l'output dettagliato non mostra alcuna riga Offering public key relativa a quella chiave.
Specifica il file e impedisci che le chiavi dell'agent vengano utilizzate al suo posto:
ssh -i ~/.ssh/vps-prod -o IdentitiesOnly=yes deploy@203.0.113.10-i da solo non è sufficiente quando l'agent contiene delle chiavi, perché ssh continua a offrire prima le chiavi dell'agent e per ultima quella del file specificato. Questo è importante perché il server conteggia ogni chiave rifiutata in MaxAuthTries, il cui valore predefinito è 6. Un agent che contiene sette chiavi può raggiungere il limite prima che venga provata quella corretta. Il messaggio cambia quindi in:
Received disconnect from 203.0.113.10 port 22:2: Too many authentication failuresSe invece visualizzi questo messaggio, il server ha chiuso la sessione prima di arrivare alla chiave corretta. Questo problema è trattato nella sezione troppi tentativi di autenticazione. IdentitiesOnly=yes limita il tentativo al file specificato. Elenca le chiavi attualmente gestite dall’agent con ssh-add -l e svuota l’agent con ssh-add -D se ha raccolto chiavi obsolete nel corso degli anni. Quindi salva le impostazioni, in modo che il login successivo non dipenda dalla memorizzazione dei flag:
Host vps-prod
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/vps-prod
IdentitiesOnly yesEsiste un'altra causa lato client. ssh rifiuta di usare una chiave privata leggibile da altri account sul computer locale. Stampa un avviso e ignora la chiave. Di conseguenza, la chiave non viene mai offerta e il server non la vede:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/you/.ssh/vps-prod' are too open.chmod 600 ~/.ssh/vps-prod risolve il problema. Il trasferimento di una chiave tramite una chiavetta USB o una condivisione Windows è il modo più comune in cui si perdono i permessi. La posizione delle chiavi e i nomi da assegnare sono descritti in Nozioni di base sulla gestione delle chiavi SSH.
Causa 3: la chiave pubblica non è mai arrivata in authorized_keys
Se ssh -v mostra che la chiave viene inviata e il server continua a rifiutarla, la verifica successiva consiste nel controllare se la chiave si trova nel file authorized_keys dell'account. Apri la console del provider, perché non puoi accedere tramite SSH per eseguire questo controllo.
sudo ls -l /home/deploy/.ssh/
sudo ssh-keygen -lf /home/deploy/.ssh/authorized_keysssh-keygen -lf su un file authorized_keys stampa un'impronta per ogni voce:
256 SHA256:0eL/8sBw... you@laptop (ED25519)
3072 SHA256:9Tq2yZk... old-laptop (RSA)Confronta queste impronte con quella presente nella riga Offering public key. Se non compare nell'elenco, la chiave non è installata su quell'account, indipendentemente da ciò che ricordi di aver fatto.
Ecco quattro cause comuni:
- Hai incollato la chiave privata invece del file
.pub. Una riga di chiave pubblica inizia conssh-ed25519ossh-rsa. Una chiave privata inizia con-----BEGIN OPENSSH PRIVATE KEY-----. - Il testo incollato è stato distribuito su più righe. Ogni voce deve occupare esattamente una riga; una chiave suddivisa su più righe viene quindi interpretata come più voci non valide e non corrisponde a nulla.
- La chiave è stata inserita in
/root/.ssh/authorized_keys, mentre accedi comedeploy, o viceversa. Il file è specifico per ogni account e non ne esiste uno condiviso. - La casella "add my key" del provider ha scritto la chiave soltanto nell'utente predefinito dell'immagine, quindi l'account creato in seguito ha una directory
.sshvuota.
Il metodo sicuro per aggiungere una chiave dalla console, come root, è il seguente:
sudo install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
sudo tee -a /home/deploy/.ssh/authorized_keys >/dev/null <<'EOF'
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKeyDataHere you@laptop
EOF
sudo chown deploy:deploy /home/deploy/.ssh/authorized_keys
sudo chmod 600 /home/deploy/.ssh/authorized_keysEsegui di nuovo sudo ssh-keygen -lf /home/deploy/.ssh/authorized_keys. La nuova impronta dovrebbe ora comparire nell'elenco. Da una macchina che consente ancora l'accesso con una password, ssh-copy-id -i ~/.ssh/vps-prod.pub deploy@203.0.113.10 esegue la stessa operazione e imposta correttamente anche i permessi.
Causa 4: perché sshd ignora authorized_keys quando i permessi sono troppo permissivi
StrictModes yes è il valore predefinito di sshd. In questa configurazione, sshd si rifiuta di leggere authorized_keys se il file, la directory .ssh o la directory home dell'account sono scrivibili da chiunque non sia il proprietario. Il motivo è diretto: se il gruppo o tutti gli utenti possono scrivere nella directory home, qualsiasi account con questo accesso può sostituire authorized_keys e prendere il controllo dell'accesso. sshd considera non attendibile il percorso, come se non esistesse alcuna chiave.
Il client visualizza il semplice messaggio Permission denied. Il log del server registra il motivo reale:
Authentication refused: bad ownership or modes for directory /home/deploy/.sshoppure, quando il problema riguarda direttamente il file:
Authentication refused: bad ownership or modes for file /home/deploy/.ssh/authorized_keysCosa accetta sshd:
- La directory home: non deve essere scrivibile dal gruppo né da tutti gli utenti.
755,750e700sono accettati.775e777non sono accettati. ~/.ssh: modalità700.~/.ssh/authorized_keys: modalità600.- Proprietà: tutti e tre devono appartenere all'account con cui esegui l'accesso, non a root.
La proprietà è importante quanto la modalità. Un file dentro /home/deploy/.ssh appartenente a root non supera lo stesso controllo. Questo accade quando lo crei con sudo nano e dimentichi di riassegnarlo all'account corretto. Correggi entrambi gli aspetti in una sola volta:
sudo chown -R deploy:deploy /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh
sudo chmod 600 /home/deploy/.ssh/authorized_keys
sudo chmod go-w /home/deploy
ls -ld /home/deploy /home/deploy/.sshL'ultimo comando mostra il risultato. Per la directory home vuoi drwxr-xr-x o una modalità più restrittiva, e drwx------ su .ssh. Se queste stringhe non sono ancora chiare, leggi come leggere una stringa di permessi come drwxr-xr-x prima di modificare le modalità su un server in produzione.
Su Rocky Linux e AlmaLinux, aggiungi SELinux (security-enhanced Linux) all'elenco delle possibili cause. Una directory .ssh creata tramite una procedura insolita può avere l'etichetta di file errata. Di conseguenza, a sshd viene negato l'accesso in lettura anche se le modalità sembrano corrette. sudo restorecon -Rv /home/deploy/.ssh ripristina le etichette e sudo ausearch -m avc -ts recent mostra se SELinux è il componente che ha negato l'accesso.
Causa 5: sshd è configurato per rifiutare l’accesso
Su un sistema Ubuntu o Debian attuale, leggere /etc/ssh/sshd_config non è sufficiente. Il file inizia con Include /etc/ssh/sshd_config.d/*.conf e OpenSSH mantiene il primo valore trovato per ogni impostazione. Di conseguenza, un file drop-in come 50-cloud-init.conf viene letto prima e prevale su qualsiasi modifica apportata più avanti nel file principale. Per questo una modifica può sembrare corretta senza produrre alcun effetto.
Chiedi a sshd quale configurazione sta utilizzando realmente:
sudo sshd -T | grep -Ei 'pubkeyauth|authorizedkeysfile|permitrootlogin|allowusers|allowgroups|denyusers'Una risposta corretta è simile alla seguente:
permitrootlogin prohibit-password
pubkeyauthentication yes
authorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2Nell’output del tuo sistema verifica quanto segue:
pubkeyauthentication no. Nessuna chiave verrà mai accettata. Questo compare anche inssh -vcome primo elencoAuthentications that can continue:senza alcunpublickey.authorizedkeysfilepunta a un altro percorso, ad esempio/etc/ssh/authorized_keys/%u. Il file nella directory home viene quindi ignorato completamente e le regole sui permessi descritte nella causa 4 si applicano al nuovo percorso.- Sono presenti
allowusersoallowgroups. Qualsiasi account non incluso viene rifiutato con esattamente questo errore e senza ulteriori spiegazioni.denyusersedenygroupsproducono lo stesso effetto al contrario. permitrootlogin nomentre stai tentando di accedere come root.prohibit-passwordè l’impostazione intermedia utile: root può usare una chiave, ma non una password.
I blocchi Match non compaiono in un semplice sshd -T, perché il risultato dipende dall’utente che si connette. Verifica una connessione specifica:
sudo sshd -T -C user=deploy,host=vps.example.com,addr=198.51.100.7Un’altra impostazione riguarda le chiavi meno recenti. OpenSSH 8.8 ha smesso di accettare per impostazione predefinita le firme SHA-1 (ssh-rsa). Di conseguenza, una chiave RSA che ha funzionato per anni può smettere di funzionare subito dopo l’aggiornamento del server. Il client lo indica chiaramente:
debug1: send_pubkey_test: no mutual signature algorithmLa correzione appropriata consiste nel creare una nuova chiave: ssh-keygen -t ed25519 -C "deploy@vps-prod", quindi installare il file .pub come illustrato sopra. Impostare PubkeyAcceptedAlgorithms +ssh-rsa sul server riabilita le vecchie firme e consente di accedere nell’immediato. Consideralo quindi un modo per raggiungere il server, non la soluzione definitiva. Le altre impostazioni lato server che vale la pena esaminare sono riportate in mettere in sicurezza il server SSH su un VPS.
Come dimostrare che una chiave privata corrisponde alla chiave pubblica installata
Gran parte delle supposizioni in questo errore deriva dal non sapere se due file formano una coppia. Un comando permette di verificarlo:
ssh-keygen -y -f ~/.ssh/vps-prodQuesto comando visualizza la chiave pubblica derivata dalla chiave privata. Non legge mai il file .pub associato, quindi mostra quale chiave privata è realmente presente, invece di basarsi su ciò che dichiara un file .pub obsoleto. Se la chiave ha una passphrase, il comando la richiede. Questo dimostra anche che si conosce ancora la passphrase.
ssh-keygen -lf ~/.ssh/vps-prod.pub
ssh-add -lIl primo comando visualizza l'impronta digitale di un file contenente una chiave pubblica. Il secondo visualizza le impronte delle chiavi gestite dall'agent. Confrontare ora quattro rappresentazioni della stessa stringa: l'impronta nella riga Offering public key restituita da ssh -v, l'impronta del file .pub, le impronte in ssh-keygen -lf nel file authorized_keys del server e l'impronta nel log del server. Il punto in cui i valori non corrispondono più identifica l'origine del problema.
Leggere il log del server mentre il login non riesce
Al client non viene restituita intenzionalmente alcuna informazione utile. Il server registra il motivo reale. Avviare il monitoraggio del log nella sessione di console, quindi eseguire dal laptop il comando ssh che non riesce.
sudo journalctl -u ssh -fUbuntu 24.04 non installa rsyslog per impostazione predefinita, quindi /var/log/auth.log potrebbe non esistere. Su Rocky Linux e AlmaLinux l'unità si chiama sshd e gli stessi record vengono scritti anche in /var/log/secure.
Impostare LogLevel VERBOSE nella configurazione di sshd e ricaricare il servizio. Ogni tentativo registra quindi l'impronta digitale ricevuta effettivamente dal server:
Failed publickey for deploy from 198.51.100.7 port 49812 ssh2: ED25519 SHA256:0eL/8sBw...Quella riga indica da quale lato si trova il problema. Un'impronta digitale riconosciuta significa che la chiave è arrivata al server, ma è stata rifiutata. Esaminare quindi le cause 3, 4 e 5. Un'impronta digitale non riconosciuta significa che il client ha inviato una chiave diversa da quella prevista. Tornare quindi alla causa 2.
Se il log non è ancora sufficientemente chiaro, avviare un secondo sshd su un'altra porta in modalità debug. Il processo resta in primo piano, gestisce una connessione, mostra i motivi delle decisioni, quindi termina:
sudo /usr/sbin/sshd -ddd -p 2222Dalla sessione di console sullo stesso server, connettersi tramite l'indirizzo di loopback:
ssh -p 2222 -i ~/.ssh/vps-prod -o IdentitiesOnly=yes deploy@127.0.0.1L'uso di 127.0.0.1 esclude il firewall dal test. L'output di debug indica il file aperto, l'impronta digitale confrontata e il rifiuto esatto, incluse righe come Authentication refused: bad ownership or modes for directory /home/deploy. Premere Ctrl+C quando si è individuata la causa. Il processo sshd effettivo sulla porta 22 non viene modificato durante il test.
Come evitare di bloccare l'accesso
Ogni passaggio che modifica la configurazione del server deve prevedere un metodo di accesso alternativo a SSH. Configurarlo mentre SSH funziona ancora, non dopo che ha smesso di funzionare.
- Apri la console del provider, tramite seriale o VNC (virtual network computing), e verifica di riuscire ad accedere.
- Assicurati di conoscere una password locale funzionante per un account con sudo. Se non ne hai una, reimposta prima la password di root dalla console del provider.
- Mantieni aperta la sessione SSH corrente. Una sessione aperta sopravvive a
systemctl restart ssh, quindi resta un metodo di accesso se la nuova configurazione è errata. - Controlla la sintassi prima di riavviare:
sudo sshd -tnon stampa nulla quando il file è valido e stampa il file e il numero di riga quando non lo è. - Apri un secondo terminale ed esegui un nuovo accesso prima di chiudere il primo. Una configurazione errata impedisce i nuovi accessi, ma non interrompe quelli esistenti. Per questo la sessione attiva non può indicare se la modifica ha funzionato.
Riavvia con sudo systemctl restart ssh su Debian e Ubuntu oppure con sudo systemctl restart sshd su Rocky Linux e AlmaLinux. Su Ubuntu 24.04 sshd viene avviato da una socket unit, quindi una modifica a Port o ListenAddress richiede anche sudo systemctl restart ssh.socket prima di diventare effettiva.
FAQ
Perché ricevo Permission denied (publickey) quando la stessa chiave funziona su un altro server?
Perché la chiave è corretta e il problema riguarda un elemento associato. Esegui ssh -v e individua la riga Offering public key. Se la chiave non è elencata, ssh non l'ha mai inviata: il file non si trova in ~/.ssh con un nome predefinito e la chiave non è stata caricata nell'agent, quindi aggiungi -i /path/to/key -o IdentitiesOnly=yes. Se la chiave è elencata ma il server continua a rifiutarla, allora manca nel file authorized_keys dell'account, il percorso che conduce al file è scrivibile dal gruppo oppure la configurazione di sshd impedisce l'accesso all'utente. Il log del server consente di distinguere questi casi.
Come posso vedere quale chiave SSH sta effettivamente inviando?
ssh -v host stampa una riga debug1: Offering public key: per ogni chiave, indicando il file di origine e l'impronta digitale SHA256. ssh-add -l elenca le impronte digitali gestite dall'agent. ssh-keygen -lf ~/.ssh/id_ed25519.pub stampa l'impronta digitale di un singolo file di chiave, mentre ssh-keygen -y -f ~/.ssh/id_ed25519 stampa la chiave pubblica derivata effettivamente da una chiave privata. Perché l'accesso riesca, l'impronta digitale della riga Offering deve comparire anche nell'output di ssh-keygen -lf eseguito sul authorized_keys del server.
Perché sshd ignora il mio file authorized_keys?
Perché StrictModes è attivo per impostazione predefinita e il file, la directory .ssh oppure la directory home è scrivibile dal gruppo o da chiunque, oppure appartiene all'account errato. sshd non considera attendibile un percorso che altri possono modificare, quindi si comporta come se non esistesse alcuna chiave. Imposta la directory home su 755 o su permessi più restrittivi, .ssh su 700, authorized_keys su 600 e assegna tutte e tre all'account di accesso. Con LogLevel VERBOSE il server registra Authentication refused: bad ownership or modes for directory /home/deploy/.ssh.
La mia chiave ha smesso di funzionare subito dopo un aggiornamento del server. Che cosa è cambiato?
Se è una chiave RSA, molto probabilmente la causa è il cambiamento relativo a SHA-1. OpenSSH 8.8 ha disabilitato per impostazione predefinita le firme ssh-rsa SHA-1, quindi una chiave che può firmare soltanto in quel modo viene ora rifiutata. L'output dettagliato del client mostra debug1: send_pubkey_test: no mutual signature algorithm. Genera una chiave moderna con ssh-keygen -t ed25519 e installa il relativo file .pub. Se ti serve accedere immediatamente, PubkeyAcceptedAlgorithms +ssh-rsa sul server riabilita le vecchie firme; rimuovi però quella riga appena la nuova chiave funziona.
Ho modificato sshd_config e ora non riesco più ad accedere. Come posso ripristinare l'accesso?
Usa la console del provider, che non passa attraverso SSH. Accedi con una password locale, esegui sudo sshd -t per visualizzare l'errore di sintassi e il numero della riga, annulla la modifica e riavvia il servizio. Poi controlla sudo sshd -T per confermare i valori effettivamente in esecuzione, perché un file in /etc/ssh/sshd_config.d/ potrebbe sovrascrivere la configurazione principale. Se non hai una password locale, reimposta prima la password di root dalla console, quindi correggi il file.