Cosa vedi
Load key "/home/user/.ssh/id_ed25519": invalid format
user@server: Permission denied (publickey).
Su molti sistemi Linux lo stesso file rovinato dà:
Load key "/home/user/.ssh/id_ed25519": error in libcrypto
Nei nostri test lo stesso file ha dato invalid format su macOS e error in libcrypto su Debian. Considerali quindi un unico problema. Una passphrase sbagliata ha un aspetto diverso: incorrect passphrase supplied to decrypt private key.
SSH non si ferma qui. Prosegue con altre chiavi e password, quindi il login può fallire più tardi o perfino riuscire con qualcos'altro.
Provare il file senza connettersi
ssh-keygen -y -f ~/.ssh/id_ed25519
Una chiave buona stampa la sua chiave pubblica, oppure chiede una passphrase e poi la stampa. Una rovinata stampa lo stesso errore Load key. Qui file non è un test affidabile: per un file rovinato riporta comunque OpenSSH private key.
Capire cosa non va
In un file sano questi comandi stampano solo le righe di intestazione e di chiusura. Un file rovinato con tutto su una riga mostrerebbe l'intera chiave, quindi non eseguirli in un log di CI o su uno schermo condiviso:
head -1 ~/.ssh/id_ed25519
tail -1 ~/.ssh/id_ed25519
tail -c 1 ~/.ssh/id_ed25519 | xxd
grep -c $'\r' ~/.ssh/id_ed25519
| Cosa vedi | Causa | Soluzione |
|---|---|---|
grep -c stampa più di 0 | Fine riga di Windows, da un editor Windows o da una copia passata da Windows | tr -d '\r' < key > key.fixed |
xxd mostra 2d, non 0a | Nessun newline dopo la riga END | echo >> key |
Inizia con ssh-ed25519 AAAA o ssh-rsa AAAA | È la chiave pubblica | Usa il file senza .pub |
Inizia con PuTTY-User-Key-File | Formato PPK | Convertila, vedi sotto |
La prima riga non è -----BEGIN ..., o l'ultima non è -----END ... | Manca una parte del file | Copialo di nuovo dalla fonte |
| Tutto su una riga, con spazi | Le interruzioni di riga sono andate perse | Vedi CI sotto |
| File vuoto | La copia è fallita | Copialo di nuovo dalla fonte |
file key riporta UTF-16 | Salvato con > di PowerShell 5 o da un editor impostato su Unicode | iconv -f UTF-16 -t UTF-8 key > key.fixed |
I controlli severi sui fine riga e sul newline finale valgono per il formato più recente, quello che inizia con -----BEGIN OPENSSH PRIVATE KEY-----. Un file più vecchio con -----BEGIN RSA PRIVATE KEY----- e lo stesso danno veniva comunque caricato nel nostro test.
Dopo aver scritto una copia corretta, imposta i permessi e provala. Senza questo passaggio, SSH può rifiutarla per un altro motivo, vedi file della chiave privata non protetto:
chmod 600 key.fixed
ssh-keygen -y -f key.fixed
Chiavi nelle variabili di CI
È una fonte molto comune di questo errore. Senza virgolette, la shell trasforma le interruzioni di riga in spazi. E printf '%s' non aggiunge un newline, quindi una variabile senza newline finale produce un file sbagliato. Entrambi questi comandi sono falliti:
echo $SSH_KEY > key
printf '%s' "$SSH_KEY" > key
Questo funziona, a patto che la variabile contenga la chiave completa con le sue interruzioni di riga:
printf '%s\n' "$SSH_KEY" > key
chmod 600 key
ssh-keygen -y -f key > /dev/null
Esegui l'ultima riga come passaggio iniziale del job e fallirà con un errore chiaro. Fai attenzione a cosa fa il tuo sistema di CI con i valori su più righe. Alcuni li conservano solo se salvati come file, altri salvano invece il base64.
Chiavi PPK
OpenSSH non legge i file .ppk. Convertili con il generatore di chiavi PPK, oppure su Linux e macOS:
puttygen key.ppk -O private-openssh -o key
chmod 600 key
Dettagli in Convertire una chiave PPK in OpenSSH.
File sbagliato nella configurazione
Se non volevi usare questa chiave, controlla da dove arriva:
ssh -G server | grep '^identityfile '
-i key.pub e IdentityFile key.pub sono un errore frequente. SSH offre la chiave pubblica, il server la accetta, poi caricarla come chiave privata fallisce, spesso con bad permissions perché i file .pub sono leggibili da tutti. Indica il file privato.
Se la chiave è davvero troncata e non hai un'altra copia, non si può riparare. Genera una nuova chiave, installala e rimuovi la vecchia chiave pubblica dai tuoi server.
Per ricavare la chiave pubblica da una chiave privata funzionante, vedi come ottenere la chiave pubblica dalla privata.
Domande
Che differenza c'è tra invalid format ed error in libcrypto?
Di solito nessuna. Lo stesso file danneggiato dà invalid format con le build LibreSSL, come su macOS, ed error in libcrypto con le build OpenSSL su Linux.
Una chiave con invalid format si può riparare?
Spesso sì, se sono sbagliati solo i fine riga o l'a capo finale. Una chiave troncata non si ripara: generane una nuova e sostituisci la chiave pubblica sui server.
Perché la chiave funziona in locale ma fallisce in CI?
Di solito la variabile di CI ha perso gli a capo o l'a capo finale. Scrivila nel file tra virgolette e con un a capo finale, poi provala con ssh-keygen -y -f.