Chiavi SSH: gestione, sicurezza e revoca
Scopri come funzionano le chiavi SSH su Ubuntu 24.04: una chiave ed25519 per dispositivo, permessi richiesti da sshd, blocchi Host e revoca.
Come funzionano le chiavi SSH
Una chiave SSH è una coppia di file: una chiave privata che resta sul dispositivo e una chiave pubblica che si copia su ogni server a cui si vuole accedere. Quando ci si connette, il server usa la chiave pubblica per inviare una verifica a cui può rispondere soltanto la chiave privata corrispondente. La chiave privata non lascia mai il dispositivo, quindi nessun segreto transita sulla rete e un server compromesso non ha nulla di utile da sottrarre. Per questo le chiavi sono più sicure delle password. Una buona gestione delle chiavi SSH si basa su quattro abitudini: una chiave per dispositivo, i permessi sui file richiesti da sshd, un file `~/.ssh/config` per evitare di specificare continuamente le opzioni e la capacità di rimuovere una chiave il giorno in cui un laptop viene smarrito.
Questa guida tratta ciascuna abitudine su Ubuntu 24.04, ma quasi tutto il contenuto si applica a qualsiasi server Linux e a qualsiasi versione recente di OpenSSH.
Prima di iniziare, è utile chiarire un termine per evitare errori concreti. La chiave pubblica non è segreta. È possibile incollarla in un ticket, inviarla tramite email o pubblicarla: nessuno può accedere con essa. La chiave privata è il segreto. Chiunque copi quel file e conosca la relativa passphrase, se impostata, può autenticarsi sui server come se fosse il proprietario della chiave.
Crea una chiave: ed25519 è l’impostazione predefinita corretta
Sul tuo computer, non sul server, esegui:
ssh-keygen -t ed25519 -C "laptop"-t ed25519 seleziona il tipo di chiave. Ed25519 è l’impostazione predefinita moderna: le chiavi sono brevi, veloci e supportate da ogni release di OpenSSH dal 2014. Usa ssh-keygen -t rsa -b 4096 solo quando devi collegarti a un dispositivo obsoleto che non supporta ed25519. -C "laptop" imposta un commento. Il commento non svolge alcuna funzione crittografica, ma permette di riconoscere questa chiave nel file authorized_keys di un server anche tra due anni. Indica quindi il dispositivo su cui risiede la chiave.
ssh-keygen chiede dove salvare la chiave. Accetta il valore predefinito, ~/.ssh/id_ed25519. Viene quindi richiesta una passphrase. Impostane una; la sezione successiva spiega perché non comporta costi operativi quotidiani. Otterrai due file: ~/.ssh/id_ed25519 è la chiave privata e ~/.ssh/id_ed25519.pub è la chiave pubblica. Visualizza la parte pubblica:
cat ~/.ssh/id_ed25519.pubssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF3k2s0vQx7GdKQhX1yBz... laptopÈ composta da una sola riga: il tipo di chiave, il materiale della chiave e il commento. È questa la riga che verrà inserita nei server.
Una chiave per dispositivo, non una per server
La prima domanda è sempre la stessa: serve una nuova chiave per ogni server? No. Create una chiave per ogni dispositivo da cui digitate i comandi e inserite quella chiave pubblica in ogni server che il dispositivo deve raggiungere. La chiave identifica il dispositivo. Il file authorized_keys su ogni server contiene l’elenco dei dispositivi autorizzati ad accedere.
Questo modello è scalabile; le alternative presentano problemi prevedibili. Una chiave per server significa che un laptop con venti server deve contenere venti chiavi private, rendendo difficile capire quale chiave corrisponde a quale server. Condividere una sola chiave tra tutti i dispositivi è ancora peggio: se il laptop viene rubato, non potete revocare l’accesso del laptop senza bloccare anche il desktop, perché entrambi contengono la stessa chiave privata. Dovete quindi sostituire la chiave ovunque e distribuirla contemporaneamente a tutti i dispositivi.
Con una chiave per dispositivo, la perdita del laptop richiede una sola modifica per server: eliminate la riga del laptop da authorized_keys e tutti gli altri dispositivi continuano a funzionare. Il commento impostato con -C permette di individuare facilmente quella riga.
La regola alla base del modello è questa: una chiave privata viene creata su un dispositivo e resta associata a quel dispositivo per tutta la sua durata. Non copiate mai una chiave privata su un secondo computer e non caricatela mai su un server. Quando un nuovo dispositivo deve ottenere l’accesso, generate una nuova chiave direttamente su quel dispositivo.
Inserire la chiave pubblica nel server
La procedura più semplice usa ssh-copy-id, incluso in OpenSSH:
ssh-copy-id matt@10.0.0.10Il comando accede con il metodo ancora disponibile, in genere una password, aggiunge la chiave pubblica a ~/.ssh/authorized_keys sul server e crea la directory e il file con i permessi corretti, se non esistono. Verifica aprendo una nuova sessione SSH: il server dovrebbe consentire l'accesso senza chiedere la password dell'account. Se la chiave ha una passphrase, il computer locale potrebbe chiedere quella; la richiesta viene visualizzata localmente e non riguarda la password del server.
Quando l'accesso tramite password è già disabilitato, ssh-copy-id non può accedere e devi aggiungere la riga manualmente. Accedi tramite una sessione ancora funzionante oppure tramite la console web del provider, quindi esegui questo comando sul server:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF3k2s0vQx7GdKQhX1yBz... laptop" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keysIncolla tra virgolette la tua chiave pubblica effettiva, cioè l'intera riga singola contenuta in id_ed25519.pub. authorized_keys contiene una chiave pubblica per riga e costituisce l'intero database degli accessi: aggiungere un dispositivo significa aggiungere una riga, mentre revocare un dispositivo significa eliminarne una. Su un server appena installato, questo passaggio rientra in primi 10 minuti su un nuovo VPS, subito prima di disabilitare l'accesso tramite password.
Le autorizzazioni che impediscono l’accesso con chiave
Questo è il motivo più comune per cui l’accesso con chiave non funziona. Dal lato client il problema non produce errori visibili. Per impostazione predefinita, su Ubuntu 24.04 sshd viene eseguito con StrictModes yes. Di conseguenza, rifiuta di usare un file authorized_keys modificabile da altri utenti. Se il file, la directory ~/.ssh o la directory home sono scrivibili da chiunque tranne te, sshd ignora la chiave e passa alla richiesta della password, senza fornire spiegazioni al client. (OpenSSH su Ubuntu tollera un solo caso specifico: un file scrivibile dal gruppo privato dell’utente, se nessun altro appartiene a quel gruppo. Non fare affidamento su questo comportamento; usa i permessi indicati di seguito.) Il motivo compare solo nel log del server:
sudo grep 'Authentication refused' /var/log/auth.logIn un’immagine minimale senza rsyslog non esiste auth.log; la stessa riga si trova nel journal: sudo journalctl -u ssh | grep 'Authentication refused'.
Authentication refused: bad ownership or modes for file /home/matt/.ssh/authorized_keysLa correzione richiede 2 modifiche ai permessi e un controllo della proprietà, eseguiti sul server dall’utente interessato:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R matt:matt ~/.sshLa regola da ricordare è: 700 sulla directory .ssh, 600 su tutto il suo contenuto. Gli stessi valori si applicano al computer locale, perché anche il client esegue il controllo. Se altri utenti possono leggere una chiave privata, ssh rifiuta direttamente la chiave. In questo caso l’errore è esplicito:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/matt/.ssh/id_ed25519' are too open.chmod 600 ~/.ssh/id_ed25519 risolve il problema.
~/.ssh/config: smetti di digitare le opzioni
Un file ~/.ssh/config sul tuo computer assegna un nome breve a ogni server e memorizza le opzioni che inserisci ripetutamente. Crealo con i permessi 600 e aggiungi un blocco Host per ogni server:
Host web1
HostName 10.0.0.10
User matt
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Host db1
HostName 10.0.0.11
User matt
Port 2222
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yesOra ssh web1 sostituisce ssh -p 22 matt@10.0.0.10, e lo stesso nome breve funziona in scp, rsync e git, perché tutti leggono questo file. HostName indica l'indirizzo reale, User evita di digitare il nome dell'account e IdentityFile specifica quale chiave offrire.
IdentitiesOnly yes richiede una spiegazione, perché risolve un errore poco intuitivo. Quando l'agent contiene più chiavi, il client le offre una alla volta e il server considera ogni offerta un tentativo non riuscito. Se sono caricate abbastanza chiavi, viene restituito Received disconnect: Too many authentication failures prima che venga provata la chiave corretta. IdentitiesOnly yes fa sì che il client offra soltanto la chiave indicata in IdentityFile, impedendo che l'errore si verifichi.
Passphrase e ssh-agent
Una passphrase cifra il file della chiave privata sul disco. Senza passphrase, chiunque copi il file può usarlo immediatamente; con una passphrase, il file sottratto non può essere utilizzato finché la passphrase non viene indovinata. Per una chiave presente su un laptop, questa è esattamente la protezione necessaria, perché i laptop possono essere rubati e i backup dei laptop possono essere divulgati.
In pratica, una passphrase non comporta costi operativi perché ssh-agent. L'agent conserva in memoria la chiave decrittografata. Devi quindi immettere la passphrase una sola volta per sessione di accesso e ogni connessione successiva è immediata. La maggior parte delle distribuzioni Linux desktop e macOS esegue già un agent per te. Carica la chiave con:
ssh-add ~/.ssh/id_ed25519ssh-add -l elenca le chiavi attualmente conservate dall'agent. Attenzione: l'agent forwarding (ssh -A) consente al server remoto di usare il tuo agent per autenticarsi verso altri sistemi mentre sei connesso. Abilitalo quindi solo verso server di cui ti fidi completamente e lascialo disattivato per impostazione predefinita.
Rotazione e revoca: esercitazione per un laptop smarrito
Revocare una chiave SSH semplice significa soltanto rimuovere la relativa riga da authorized_keys su ogni server che la contiene. Non è necessario informare alcuna autorità di certificazione né attendere una data di scadenza. Non appena la riga viene rimossa, i nuovi accessi con quella chiave falliscono.
Eseguire ora l'esercitazione, quando non è ancora un'emergenza. Scegliere un server, aprire ~/.ssh/authorized_keys e individuare la chiave tramite il relativo commento. Eliminare la riga con un editor oppure filtrarla in base al commento:
grep -v ' laptop$' ~/.ssh/authorized_keys > ~/.ssh/authorized_keys.tmp
mv ~/.ssh/authorized_keys.tmp ~/.ssh/authorized_keysConfermare quindi dal dispositivo appena revocato che l'accesso ora fallisce e da un altro dispositivo che l'accesso continua a funzionare. Tenere presente un dettaglio: la rimozione di una chiave non chiude le sessioni già aperte, perché la chiave viene verificata soltanto al momento dell'accesso. Se si sta revocando un dispositivo rubato, controllare anche who sul server e terminare le sessioni non riconosciute.
La rotazione consiste nella stessa operazione eseguita in un ordine diverso: generare una nuova chiave sul dispositivo, installarla con ssh-copy-id, confermare che la nuova chiave consenta l'accesso, quindi eliminare la riga della vecchia chiave. Eseguirla quando un dispositivo passa a un'altra persona, quando una chiave potrebbe essere stata esposta o quando una persona lascia un team. Eseguire questa procedura manualmente su due server è accettabile; su venti server è invece necessario usare l'automazione. gestire più server Linux spiega come distribuire lo stesso stato authorized_keys a un'intera flotta.
Cosa non fare
- Non condividere la stessa chiave privata tra tutti i dispositivi. In questo modo è impossibile revocare un singolo dispositivo rubato senza sostituire la chiave ovunque.
- Non eseguire il commit di una chiave privata in un repository Git, nemmeno se privato. Gli scanner automatici monitorano i repository pubblici e provano le chiavi esposte entro pochi minuti dal push. Se in seguito rendi pubblico un repository, esponi l'intera cronologia.
- Non caricare la chiave privata del laptop su un server per consentire a quel server di raggiungerne un altro. Genera una chiave separata direttamente sul server e autorizzala solo nel punto in cui serve.
- Non incollare una chiave privata in una chat, in un'e-mail o in un ticket. La chiave pubblica, il file `
.pub`, è l'unica parte che deve essere condivisa.
Quando la chiave consente l'accesso in modo affidabile, disattiva l'autenticazione tramite password. In questo modo i tentativi continui di indovinare la password del server non possono più avere successo. La configurazione drop-in è disponibile in Hardening SSH su un VPS.
FAQ
Come funzionano le chiavi SSH senza inviare una password?
Il server conserva la chiave pubblica in ~/.ssh/authorized_keys. Durante l'accesso invia una challenge, il client firma la challenge con la chiave privata e il server verifica la firma con la chiave pubblica. La chiave privata non lascia mai il dispositivo, quindi non c'è nulla da intercettare durante il transito e nulla di riutilizzabile da sottrarre al server. Un server violato espone soltanto chiavi pubbliche, che non possono essere usate per accedere ad alcun sistema.
Devo usare la stessa chiave SSH per tutti i miei server?
Usare una chiave su più server è corretto, purché la chiave resti su un singolo dispositivo. La regola è una chiave per dispositivo, non una per server: la chiave pubblica del laptop va installata su ogni server a cui il laptop deve accedere, mentre il desktop ha una propria chiave. Questo semplifica la revoca: se si perde un dispositivo, basta rimuovere una singola riga identificabile da ogni server, mentre gli altri dispositivi continuano a funzionare.
Quali permessi devono avere la directory .ssh e authorized_keys?
Impostare 700 su ~/.ssh e 600 su authorized_keys e su ogni chiave privata, assegnandone la proprietà all'account che li utilizza. Per impostazione predefinita, sshd viene eseguito con StrictModes yes, quindi un file o una home directory scrivibile da chiunque, non soltanto dall'utente proprietario, fa sì che la chiave venga ignorata senza messaggi espliciti. L'unica traccia è Authentication refused: bad ownership or modes nel log di autenticazione o nel journal del server.
Come rimuovo una chiave SSH da un server?
Eliminare la riga della chiave da ~/.ssh/authorized_keys nell'account per il quale era stata autorizzata. Individuare la riga corretta tramite il relativo commento, cioè l'etichetta dopo il materiale della chiave. I nuovi accessi con quella chiave falliscono immediatamente, ma le sessioni già aperte restano attive; se il dispositivo è stato rubato, chiudere anche ogni sessione attiva associata. Ripetere l'operazione su ogni server in cui la chiave è stata copiata.
Devo usare una passphrase per la mia chiave SSH?
Per una chiave presente su un laptop o su un desktop, sì. La passphrase cifra il file della chiave, quindi una copia rubata o esposta non è utilizzabile da sola, e ssh-agent consente di inserirla una volta per sessione invece che a ogni connessione. Le chiavi usate dall'automazione non presidiata su un server di solito non hanno una passphrase, perché non c'è nessun operatore che possa inserirla; è necessario proteggerle limitando le operazioni consentite all'account di destinazione.