Le password SSH sono il bersaglio numero uno dei bot che scansionano internet. Un server Ubuntu appena esposto sulla porta 22 riceve migliaia di tentativi di login al giorno, spesso entro pochi minuti dall’accensione. La difesa definitiva non è una password più lunga, ma l’eliminazione totale delle password a favore della crittografia a chiave pubblica. In questo tutorial configuri l’autenticazione SSH con chiavi Ed25519, generi la coppia con ssh-keygen, blindi sshd_config e installi fail2ban, fino a ottenere un server che accetta solo connessioni firmate crittograficamente.

Il percorso è organizzato in 12 step concreti, con comandi pronti da incollare, esempi di output reali e una checklist finale. Lavoriamo su OpenSSH 10.3p1 (rilasciato il 2 aprile 2026) e Ubuntu Server, ma i comandi valgono identici su Debian, Rocky Linux e qualsiasi distribuzione moderna. Alla fine avrai un progetto completo: una postazione client e un server collegati senza password, con root disabilitato, brute-force mitigato e algoritmi resistenti al calcolo quantistico.

Perché l’autenticazione SSH con chiavi batte le password

Una password, per quanto robusta, è un segreto condiviso: viaggia (in forma cifrata) verso il server a ogni login e può essere indovinata, intercettata via phishing o estratta da un database compromesso. Una chiave SSH funziona in modo radicalmente diverso. La parte privata non lascia mai il tuo computer. Il server conserva solo la chiave pubblica e lancia una sfida matematica che solo chi possiede la chiave privata può risolvere. Nessun segreto transita sulla rete e non c’è nulla da indovinare con la forza bruta.

I numeri lo confermano. Un attaccante che tenta password contro la porta 22 ha probabilità realistiche di successo contro credenziali deboli o riutilizzate. Contro una chiave Ed25519 dovrebbe risolvere un problema di logaritmo discreto su curva ellittica, un’operazione che resta fuori dalla portata dei computer classici. Aggiungi che con PasswordAuthentication no il server smette del tutto di valutare le password, e i bot che riempiono /var/log/auth.log ricevono un rifiuto immediato senza nemmeno arrivare alla fase di autenticazione.

C’è anche un fattore di igiene operativa. Le chiavi sono per macchina e per utente: puoi autorizzare il laptop di un collaboratore e revocarlo cancellando una riga da authorized_keys, senza cambiare nulla per gli altri. Con ssh-agent ti autentichi una volta e riutilizzi la sessione per decine di server, eliminando la tentazione di scegliere password facili da digitare. La chiave privata, protetta da una passphrase, resta cifrata sul disco anche se il portatile viene rubato.

Come funziona la crittografia a chiave pubblica in SSH

SSH usa la crittografia asimmetrica. Quando esegui ssh-keygen generi due file matematicamente legati: la chiave privata (per esempio ~/.ssh/id_ed25519) e la chiave pubblica (~/.ssh/id_ed25519.pub). Ciò che firmi con la privata si verifica solo con la pubblica corrispondente, e dalla pubblica è computazionalmente impossibile risalire alla privata.

Durante la connessione il flusso è questo: il client annuncia quale chiave pubblica intende usare, il server controlla che quella chiave sia presente in ~/.ssh/authorized_keys dell’utente, poi invia una sfida basata sulla sessione corrente. Il client firma la sfida con la chiave privata e rimanda la firma. Il server la verifica con la chiave pubblica registrata. Se la firma è valida, l’accesso è concesso. Tutto questo avviene dopo che client e server hanno già negoziato un canale cifrato tramite uno scambio di chiavi (key exchange), quindi anche i metadati dell’autenticazione viaggiano protetti.

Il concetto è lo stesso che protegge le connessioni web e la posta cifrata. Se vuoi approfondire le fondamenta, abbiamo spiegato il meccanismo delle firme digitali e il funzionamento di HTTPS e TLS, che condividono con SSH la stessa logica di scambio asimmetrico. La differenza pratica è che in SSH gestisci tu, manualmente, l’elenco delle chiavi autorizzate su ogni macchina.

Step 1: Prerequisiti e versioni del 2026

Prima di iniziare, allinea l’ambiente. Questo tutorial presuppone due macchine: un client (il tuo laptop, Linux o macOS, oppure Windows con OpenSSH integrato) e un server raggiungibile via rete. Servono accesso amministrativo (sudo) sul server e una sessione SSH già funzionante, anche solo con password, per la configurazione iniziale.

ComponenteVersione consigliata (2026)Note
OpenSSH10.3p1 (2 aprile 2026)Versione stabile corrente lato client e server
Ubuntu Server24.04 LTS o 26.04 LTSValido anche su Debian 12/13
ssh-keygenIncluso in OpenSSH 10.3p1Genera Ed25519, ECDSA, RSA
fail2banPacchetto APT correnteMitigazione brute-force
Algoritmo chiaveEd25519RSA 4096 solo per compatibilità legacy

Verifica la versione di OpenSSH installata sul client e sul server con un solo comando. Le due macchine non devono per forza avere la stessa versione, ma è bene che entrambe siano recenti per supportare gli algoritmi moderni.

ssh -V

# Output atteso (esempio):
# OpenSSH_10.3p1, OpenSSL 3.5.0  2 Apr 2026

Se vedi una versione compresa tra 8.5p1 e 9.7p1, aggiorna subito: quell’intervallo è vulnerabile a CVE-2024-6387 (la falla “regreSSHion”), che in determinate condizioni permette l’esecuzione di codice come root sul server. Su Ubuntu basta sudo apt update && sudo apt upgrade openssh-server openssh-client. Le release 9.9p2 (18 febbraio 2025) e successive correggono anche CVE-2025-26465 e CVE-2025-26466.

Step 2: Ed25519 vs ECDSA vs RSA 4096, quale algoritmo scegliere

La scelta dell’algoritmo determina sicurezza, prestazioni e compatibilità della tua chiave per i prossimi anni. Nel 2026 la risposta è semplice nella stragrande maggioranza dei casi: Ed25519. È basato sulla curva Curve25519, produce chiavi minuscole (circa 32 byte di materiale grezzo), firma e verifica molto rapidamente e ha parametri sicuri fissati per progetto, quindi non puoi configurarlo male.

AlgoritmoSicurezzaChiave pubblicaPrestazioniQuando usarlo
Ed25519Eccellente~32 byteMolto veloceScelta predefinita per ogni nuova chiave
ECDSA P-256Buona~64 byteVeloceSolo se Ed25519 non è disponibile
ECDSA P-521Molto buonaMaggiorePiù lenta di Ed25519Requisiti di policy specifici
RSA 4096Buona~512 bytePiù lentaSistemi legacy senza supporto ECC
RSA 2048Sufficiente, sconsigliata~256 bytePiù lentaDa evitare per nuove chiavi

RSA 4096 resta una scelta conservativa e compatibile, utile quando devi connetterti ad apparati datati o a sistemi embedded che non parlano curve ellittiche. Lo svantaggio è la dimensione (chiavi e firme molto più grandi) e una verifica più lenta. ECDSA è supportato ma offre pochi vantaggi rispetto a Ed25519, e la generazione di parametri sbagliati è storicamente più rischiosa. La regola operativa: genera una chiave Ed25519 e tieni a portata di mano una RSA 4096 solo se incontri un sistema che la pretende.

Step 3: Generare la coppia di chiavi con ssh-keygen

Sul client (non sul server) genera la chiave. L’opzione -a 100 imposta 100 round di derivazione KDF per proteggere meglio la passphrase, -C aggiunge un commento identificativo e -f definisce il percorso del file.

ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519 -C "laptop-lavoro-2026"

Il programma chiede una passphrase. Non lasciarla vuota: la passphrase cifra la chiave privata sul disco, così chi ruba il portatile non ottiene un accesso immediato ai tuoi server. L’output assomiglia a questo.

Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase): ********
Enter same passphrase again: ********
Your identification has been saved in /home/sam/.ssh/id_ed25519
Your public key has been saved in /home/sam/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:9pT2k...Qz8 laptop-lavoro-2026

Per un sistema legacy che richiede RSA, il comando equivalente è il seguente. L’opzione -o forza il formato di chiave privata moderno e -b 4096 definisce la lunghezza.

ssh-keygen -t rsa -b 4096 -o -a 100 -f ~/.ssh/id_rsa -C "compatibilita-legacy"

Ora hai due file. Visualizza la chiave pubblica, l’unica che condividerai: inizia con ssh-ed25519 ed è lunga una sola riga. La chiave privata, id_ed25519 senza estensione, non deve mai uscire dal client né essere inviata via email o chat.

cat ~/.ssh/id_ed25519.pub

# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH9...kQ laptop-lavoro-2026

Step 4: Copiare la chiave pubblica sul server

Il modo più pulito per autorizzare la chiave sul server è ssh-copy-id. Lo strumento aggiunge la chiave pubblica al file authorized_keys dell’utente remoto e imposta automaticamente i permessi corretti. Ti verrà chiesta un’ultima volta la password dell’account: è normale, la stai usando per installare la chiave.

ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]

# Output atteso:
# Number of key(s) added: 1
# Now try logging into the machine, with:
#   "ssh '[email protected]'"

Setup manuale di authorized_keys

Se ssh-copy-id non è disponibile (per esempio su alcuni client Windows), copia la chiave manualmente. Carica il file pubblico con scp, poi accodalo ad authorized_keys impostando i permessi nella stessa riga.

scp ~/.ssh/id_ed25519.pub [email protected]:/tmp/chiave.pub

ssh [email protected] 'mkdir -p ~/.ssh && chmod 700 ~/.ssh && \
  cat /tmp/chiave.pub >> ~/.ssh/authorized_keys && \
  chmod 600 ~/.ssh/authorized_keys && rm -f /tmp/chiave.pub'

Adesso prova a entrare. Se hai impostato una passphrase, il client la chiede una volta per sbloccare la chiave privata locale, non per autenticarti al server. La connessione deve riuscire senza che il server chieda mai la password dell’account.

ssh [email protected]

# Enter passphrase for key '/home/sam/.ssh/id_ed25519': ********
# Welcome to Ubuntu 26.04 LTS (GNU/Linux 6.11.0 x86_64)
# sam@server:~$

Step 5: Configurare ssh-agent e la passphrase

Digitare la passphrase a ogni connessione è scomodo e spinge verso chiavi senza passphrase, una pessima abitudine. La soluzione è ssh-agent: un processo che custodisce la chiave decifrata in memoria per la durata della sessione. La sblocchi una volta e l’agente firma le sfide successive senza richiedere altro.

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l

# Output:
# Agent pid 4821
# Identity added: /home/sam/.ssh/id_ed25519 (laptop-lavoro-2026)
# 256 SHA256:9pT2k...Qz8 laptop-lavoro-2026 (ED25519)

Su GNOME, KDE e macOS l’agente parte in automatico al login, quindi spesso basta ssh-add. Su macOS puoi memorizzare la passphrase nel portachiavi con ssh-add --apple-use-keychain ~/.ssh/id_ed25519. Evita invece di inoltrare l’agente (ForwardAgent yes) verso server non fidati: chi controlla quel server può usare la tua chiave per la durata della connessione.

Step 6: Semplificare le connessioni con ~/.ssh/config

Il file ~/.ssh/config sul client trasforma comandi lunghi in alias brevi e centralizza le impostazioni per host. Crea o modifica il file e definisci una voce per il tuo server. La direttiva IdentitiesOnly yes evita che il client proponga al server tutte le chiavi in elenco, comportamento che può causare l’errore “Too many authentication failures”.

Host server-prod
    HostName server.example.com
    User sam
    Port 2222
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes
    ServerAliveInterval 30
    ServerAliveCountMax 3

Imposta i permessi del file di configurazione e connettiti con l’alias. Da ora ssh server-prod equivale a digitare host, utente, porta e chiave per esteso.

chmod 600 ~/.ssh/config
ssh server-prod

Le direttive ServerAliveInterval e ServerAliveCountMax inviano un pacchetto di keep-alive ogni 30 secondi e chiudono la sessione dopo tre mancate risposte, evitando connessioni “appese” dietro router che terminano le sessioni inattive.

Step 7: Hardening di sshd_config sul server

Ora blindiamo il demone SSH. Sul server modifica /etc/ssh/sshd_config con un editor. Non chiudere la sessione corrente: aprine una seconda per testare le modifiche, così se ti blocchi fuori hai ancora un terminale attivo per correggere.

DirettivaValore consigliatoEffetto
PubkeyAuthenticationyesAbilita l’autenticazione a chiave pubblica
PasswordAuthenticationnoDisabilita del tutto le password
KbdInteractiveAuthenticationnoBlocca i prompt interattivi via PAM
PermitRootLoginnoVieta il login diretto come root
MaxAuthTries3Limita i tentativi per connessione
AllowUserssam adminConsente SSH solo agli account elencati
Port2222Riduce il rumore degli scanner automatici
X11ForwardingnoDisabilita l’inoltro grafico non necessario

Applica una baseline come la seguente. Su Ubuntu recenti le impostazioni vanno preferibilmente in un file dedicato dentro /etc/ssh/sshd_config.d/, che ha la precedenza sul file principale.

sudo tee /etc/ssh/sshd_config.d/99-hardening.conf >/dev/null <<'EOF'
Port 2222
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
MaxAuthTries 3
AllowUsers sam admin
X11Forwarding no
EOF

Verifica sempre la sintassi prima di riavviare. Il comando sshd -t non produce output se la configurazione è valida, mentre segnala riga e motivo di un eventuale errore.

sudo sshd -t && echo "Configurazione valida"
sudo systemctl restart ssh

Step 8: Disabilitare password e accesso root in sicurezza

Disattivare le password è il momento più delicato del tutorial. Se la tua chiave non è installata correttamente e disabiliti le password, ti chiudi fuori. La procedura sicura è questa: con la baseline dello step precedente già applicata, non chiudere la sessione root o sudo attiva e apri un secondo terminale per testare l’accesso a chiave sulla nuova porta.

# Dal client, in una NUOVA finestra di terminale:
ssh -p 2222 [email protected]

# Se entri senza che venga chiesta la password dell'account,
# la chiave funziona e puoi considerare l'hardening riuscito.

Solo dopo aver confermato che il login a chiave funziona nella seconda sessione, puoi chiudere la prima. Se invece ricevi Permission denied (publickey), non disconnetterti: torna alla sessione ancora aperta, controlla authorized_keys e i permessi, e correggi prima di proseguire. Molti provider cloud offrono una console seriale o una modalità di recovery che ti salva anche in caso di lockout totale.

Per i firewall ricorda di aprire la nuova porta. Se usi UFW su Ubuntu, autorizza la 2222 e rimuovi la 22 solo dopo aver verificato l’accesso. Questo approccio per chiavi e accessi limitati si integra con altre difese perimetrali come il server WireGuard VPN, che può esporre SSH solo all’interno di un tunnel cifrato.

sudo ufw allow 2222/tcp
sudo ufw reload
# Dopo aver verificato il login sulla 2222:
# sudo ufw delete allow 22/tcp

Step 9: Algoritmi moderni e crittografia post-quantistica

OpenSSH 10.3p1 negozia di default algoritmi solidi, quindi nella maggior parte dei casi non serve fissarli a mano. Anzi, “incollare” liste statiche di KexAlgorithms o Ciphers è rischioso: i default evolvono a ogni release e una lista obsoleta può indebolire il server o impedirne l’avvio dopo un aggiornamento. La regola del 2026 è lasciare i default e intervenire solo per allinearsi a una baseline auditata.

La novità più rilevante è lo scambio di chiavi resistente al quantum. Le versioni recenti di OpenSSH adottano scambi ibridi come mlkem768x25519-sha256 (basato su ML-KEM, lo standard NIST derivato da Kyber) e sntrup761x25519-sha256. Sono “ibridi” perché combinano un algoritmo post-quantistico con la classica Curve25519: anche se uno dei due cadesse, l’altro tiene. Questo protegge dal modello “harvest now, decrypt later”, in cui un attaccante registra il traffico oggi per decifrarlo quando avrà un computer quantistico.

Se devi davvero pinnare gli algoritmi per una policy interna, mantieni la lista minima e moderna, per esempio cifrari AEAD come [email protected] e [email protected]. Per capire perché il post-quantum sta entrando ovunque, dalla web alla messaggistica, abbiamo dedicato un’analisi alla crittografia e alle funzioni hash che alimentano queste primitive.

# Verifica gli algoritmi di scambio chiavi supportati dal tuo client:
ssh -Q kex | grep -E 'mlkem|sntrup'

# Output atteso su OpenSSH 10.3p1:
# [email protected]
# mlkem768x25519-sha256

Step 10: Proteggere SSH con fail2ban

Con le password disabilitate i bot non possono indovinare credenziali, ma continuano a tempestare il server di tentativi che sporcano i log e consumano risorse. fail2ban analizza /var/log/auth.log, individua gli indirizzi IP che falliscono ripetutamente e li banna a livello di firewall per un periodo definito.

sudo apt update
sudo apt install fail2ban

sudo tee /etc/fail2ban/jail.d/sshd.local >/dev/null <<'EOF'
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
findtime = 10m
bantime = 1h
EOF

sudo systemctl restart fail2ban
sudo systemctl enable fail2ban

Se hai mantenuto SSH sulla porta 22 imposta port = 22. Controlla lo stato del jail: vedrai il conteggio dei tentativi falliti e l’elenco degli IP attualmente bannati. Con bantime = 1h ogni IP viene escluso per un’ora dopo cinque fallimenti in dieci minuti.

sudo fail2ban-client status sshd

# Status for the jail: sshd
# |- Filter
# |  |- Currently failed: 2
# |  |- Total failed:     148
# |  `- File list:        /var/log/auth.log
# `- Actions
#    |- Currently banned: 3
#    `- Total banned:     27

Step 11: Impostare i permessi corretti dei file

OpenSSH rifiuta di usare chiavi e file di configurazione con permessi troppo aperti: è una protezione contro la lettura da parte di altri utenti del sistema. La causa numero uno dei messaggi “bad permissions” e di molti Permission denied (publickey) sono proprio permessi sbagliati su ~/.ssh. Applica questo schema sia sul client sia sul server.

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chown -R "$USER:$USER" ~/.ssh
File o directoryPermessiSignificato
~/.ssh700Accesso solo al proprietario
~/.ssh/authorized_keys600Lettura e scrittura solo proprietario
~/.ssh/id_ed25519 (privata)600Mai leggibile da altri
~/.ssh/id_ed25519.pub (pubblica)644Leggibile e condivisibile
~/.ssh/config600Lettura e scrittura solo proprietario

La proprietà conta quanto i permessi: tutti i file in ~/.ssh devono appartenere all’utente, non a root. Se hai creato file con sudo per errore, il comando chown qui sopra rimette a posto il proprietario in modo ricorsivo.

Step 12: Il progetto completo e la checklist di verifica

A questo punto hai un sistema completo e funzionante: client con chiave Ed25519 protetta da passphrase e gestita da ssh-agent, server che accetta solo autenticazione a chiave su una porta non standard, root disabilitato e fail2ban a presidio del brute-force. Esegui questa verifica finale per confermare che ogni pezzo sia al suo posto.

# 1. Le password sono davvero disattivate? (deve fallire subito)
ssh -p 2222 -o PreferredAuthentications=password \
    -o PubkeyAuthentication=no [email protected]
# Atteso: Permission denied (publickey).

# 2. Il login a chiave funziona?
ssh server-prod 'echo OK; hostname; whoami'
# Atteso: OK / nome-server / sam

# 3. fail2ban è attivo?
sudo fail2ban-client status sshd

Usa questa checklist come riepilogo del progetto. Se tutte le voci sono soddisfatte, il tuo accesso SSH è blindato secondo le pratiche del 2026.

  • Chiave Ed25519 generata con ssh-keygen -a 100 e passphrase impostata
  • Chiave pubblica in authorized_keys, chiave privata mai uscita dal client
  • PasswordAuthentication no e PermitRootLogin no attivi e testati
  • MaxAuthTries 3 e AllowUsers configurati
  • Porta personalizzata aperta sul firewall, porta 22 chiusa dopo verifica
  • Permessi 700/600 corretti su client e server
  • fail2ban installato, abilitato e con il jail sshd attivo
  • OpenSSH aggiornato a una versione non vulnerabile a CVE-2024-6387

Errori comuni e troubleshooting

Anche con una procedura precisa, l’autenticazione a chiave fallisce per pochi motivi ricorrenti. Ecco gli otto problemi più frequenti e come risolverli rapidamente. Quasi tutti si diagnosticano con la modalità verbosa ssh -v, che mostra esattamente quali chiavi vengono proposte e dove si interrompe il dialogo.

  • Permission denied (publickey): la chiave non è in authorized_keys, l’utente è sbagliato o i permessi sono troppo aperti. Esegui ssh -v sam@host e controlla quale chiave offre il client.
  • Bad permissions / ignoring key: ~/.ssh o la chiave privata hanno permessi errati. Applica chmod 700 ~/.ssh e chmod 600 ~/.ssh/id_ed25519.
  • Host key verification failed: la chiave host del server è cambiata (reinstallazione o reimaging) e known_hosts contiene quella vecchia. Rimuovi la voce con ssh-keygen -R server.example.com e riconnetti verificando il fingerprint.
  • Too many authentication failures: il client offre troppe chiavi e supera MaxAuthTries. Aggiungi IdentitiesOnly yes nel file ~/.ssh/config.
  • Agent admitted failure to sign: la chiave non è caricata nell’agente. Esegui ssh-add ~/.ssh/id_ed25519 e verifica con ssh-add -l.
  • Connection refused sulla nuova porta: il firewall blocca la 2222 o sshd non è ripartito. Controlla con sudo ufw status e sudo systemctl status ssh.
  • sshd non riparte dopo le modifiche: errore di sintassi in sshd_config. Lancia sempre sudo sshd -t prima del riavvio per individuare la riga incriminata.
  • Lockout totale: hai disabilitato le password senza una chiave funzionante. Accedi tramite la console seriale o la modalità rescue del provider cloud, riabilita temporaneamente PasswordAuthentication yes e ricomincia dallo step 4.

Diagnostica avanzata lato server

Quando il client non basta, leggi i log del server. Su Ubuntu i tentativi SSH finiscono in /var/log/auth.log, mentre journalctl mostra in tempo reale il comportamento del demone. Spesso il motivo esatto del rifiuto (chiave non autorizzata, utente non in AllowUsers, permessi errati) è scritto chiaramente lì.

sudo journalctl -u ssh -f
sudo tail -n 50 /var/log/auth.log | grep sshd

Consigli avanzati per ambienti di produzione

Una volta padroneggiate le basi, alcune pratiche fanno la differenza su flotte di server. La prima è la chiave su token hardware: generando una chiave di tipo ed25519-sk la parte privata vive in una chiavetta FIDO2 (come una YubiKey) e ogni firma richiede un tocco fisico. Senza il token la chiave è inutilizzabile, anche se il portatile viene compromesso.

ssh-keygen -t ed25519-sk -O resident -f ~/.ssh/id_ed25519_sk -C "yubikey-prod"

Per parchi macchine numerosi, le certificate authority SSH superano la gestione manuale di authorized_keys. Firmi le chiavi degli utenti con una CA interna e ogni server si fida automaticamente di chiunque presenti un certificato valido e non scaduto, eliminando la distribuzione delle chiavi pubbliche server per server. Aggiungi ClientAliveInterval 300 e ClientAliveCountMax 2 in sshd_config per chiudere le sessioni inattive, e considera LoginGraceTime 20 per ridurre la finestra utile agli attacchi pre-autenticazione come regreSSHion.

Infine, automatizza l’audit. Strumenti come ssh-audit analizzano la configurazione del tuo server e segnalano algoritmi deboli o impostazioni obsolete con un punteggio. Integrato in una pipeline, ti avvisa quando un aggiornamento cambia i default o quando una macchina si discosta dalla baseline. Per il quadro normativo europeo che spinge verso questi controlli, vedi la nostra analisi della direttiva NIS2 in Italia.

Backup, rotazione e revoca delle chiavi SSH

Una chiave SSH non è eterna. La gestione del ciclo di vita (backup sicuro, rotazione periodica, revoca tempestiva) è ciò che distingue una configurazione amatoriale da una di produzione. Il principio guida è semplice: la chiave privata va trattata come la combinazione di una cassaforte, mentre la chiave pubblica è un’informazione liberamente distribuibile.

Per il backup, non copiare mai la chiave privata su un servizio cloud non cifrato o in una chat. Conservala in un password manager che supporti gli allegati cifrati, oppure su un supporto offline custodito fisicamente. Se la chiave è protetta da una passphrase robusta, anche un backup che finisse in mani sbagliate resterebbe inutilizzabile senza la frase. Esporta sempre anche la chiave pubblica corrispondente, così puoi ripristinare l’accesso senza rigenerare tutto.

La rotazione consiste nel generare periodicamente una nuova coppia e dismettere la vecchia. Una cadenza ragionevole per ambienti sensibili è annuale, oppure immediata in caso di sospetto compromesso. La procedura corretta evita finestre di lockout: prima aggiungi la nuova chiave pubblica ad authorized_keys, verifichi che il login con la nuova chiave funzioni, e solo dopo rimuovi la riga della vecchia chiave.

# 1. Genera la nuova chiave sul client
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519_new -C "rotazione-2026"

# 2. Installa la nuova chiave pubblica (la vecchia è ancora attiva)
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub server-prod

# 3. Verifica il login con la nuova chiave
ssh -i ~/.ssh/id_ed25519_new server-prod 'echo nuova chiave OK'

# 4. Solo ora rimuovi la vecchia riga da authorized_keys sul server
ssh server-prod "sed -i '/laptop-lavoro-2026/d' ~/.ssh/authorized_keys"

La revoca è la rimozione immediata di una chiave compromessa. Su un singolo server basta cancellare la riga corrispondente in authorized_keys. Su una flotta gestita con certificate authority, invece, pubblichi la chiave in una lista di revoca (RevokedKeys in sshd_config) e tutti i server la rifiutano all’istante, senza dover toccare ogni macchina. È uno dei vantaggi principali dell’approccio basato su CA per organizzazioni con molti host.

Accesso SSH da Windows con OpenSSH integrato

Windows include OpenSSH come funzionalità nativa da diversi anni, quindi non servono più client di terze parti per le operazioni di base. Apri PowerShell e verifica la presenza del client: i comandi ssh, ssh-keygen e ssh-add funzionano esattamente come su Linux e macOS, con qualche differenza nei percorsi dei file.

# In PowerShell:
ssh -V
ssh-keygen -t ed25519 -a 100 -C "windows-desktop"
# Le chiavi finiscono in C:\Users\<utente>\.ssh\

Su Windows l’agente è un servizio di sistema. Abilitalo e avvialo una sola volta da PowerShell con privilegi di amministratore, poi aggiungi la chiave. Da quel momento l’agente parte automaticamente a ogni avvio e custodisce la chiave decifrata.

# PowerShell come amministratore:
Set-Service -Name ssh-agent -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519

Il file di configurazione vive in C:\Users\<utente>\.ssh\config e usa la stessa sintassi vista nello step 6. L’unico accorgimento ricorrente riguarda i permessi: se Windows segnala che la chiave privata è “troppo aperta”, rimuovi l’ereditarietà delle ACL e lascia l’accesso al solo utente proprietario tramite le proprietà del file o il comando icacls. Per chi preferisce un ambiente Linux completo, WSL2 offre un OpenSSH identico a quello di Ubuntu, con i file in ~/.ssh come di consueto.

Domande frequenti sull’autenticazione SSH con chiavi

Devo impostare una passphrase sulla chiave SSH?

Sì. La passphrase cifra la chiave privata sul disco: senza di essa chiunque acceda al tuo file ottiene un accesso immediato a tutti i server autorizzati. Con ssh-agent la digiti una sola volta per sessione, quindi non c’è ragione pratica per ometterla. L’unica eccezione legittima sono le chiavi usate da processi automatici, che vanno comunque limitate con restrizioni in authorized_keys.

Ed25519 o RSA 4096 nel 2026?

Ed25519 per ogni nuova chiave. È più sicuro per dimensione, molto più veloce e immune a errori di configurazione. RSA 4096 ha senso solo quando devi connetterti a sistemi datati o apparati embedded che non supportano le curve ellittiche. In quel caso genera una seconda chiave RSA dedicata e usala unicamente per quegli host.

Cambiare la porta SSH dalla 22 rende il server più sicuro?

Solo marginalmente. Spostarsi sulla 2222 riduce il rumore degli scanner automatici e alleggerisce i log, ma non è una difesa crittografica: un attaccante mirato trova facilmente la porta giusta. Consideralo igiene, non sicurezza. La vera protezione è PasswordAuthentication no insieme alle chiavi.

Cosa succede se perdo la chiave privata?

Perdi l’accesso ai server che la autorizzano, ma nessun altro può usarla se era protetta da passphrase. La procedura è generare una nuova chiave, aggiungerne la pubblica ad authorized_keys tramite un canale alternativo (console del provider, un altro account autorizzato) e rimuovere la vecchia chiave dal file. Per questo conviene autorizzare sempre almeno due chiavi o mantenere un percorso di recovery.

fail2ban serve ancora se ho disabilitato le password?

Sì, anche se il rischio di compromissione crolla. fail2ban non protegge tanto dalle password (già disattivate) quanto dal rumore: banna gli IP che martellano la porta, riduce il carico, mantiene i log leggibili e mitiga eventuali falle pre-autenticazione future. È un complemento economico, non un’alternativa alle chiavi.

SSH è già pronto per i computer quantistici?

Lo scambio di chiavi sì, l’autenticazione non ancora del tutto. OpenSSH negozia scambi ibridi post-quantistici come mlkem768x25519-sha256, che proteggono la riservatezza della sessione dal modello “registra ora, decifra dopo”. Le firme di autenticazione restano per ora basate su Ed25519 o RSA, sicure contro i computer classici. La migrazione completa delle firme verso algoritmi post-quantistici è in corso a livello di standard.

Posso usare la stessa chiave su più computer?

È tecnicamente possibile ma sconsigliato. La buona pratica è una chiave per dispositivo: se un laptop viene rubato o dismesso, revochi solo quella chiave senza toccare le altre. Copiare la chiave privata su più macchine moltiplica i punti di esposizione e complica la revoca selettiva.

Qual è la versione di OpenSSH da evitare per la vulnerabilità regreSSHion?

Le versioni portable da 8.5p1 a 9.7p1 sono vulnerabili a CVE-2024-6387, che può portare all’esecuzione di codice come root. Aggiorna ad almeno 9.9p2 (febbraio 2025) o, meglio, alla 10.3p1 (aprile 2026). Verifica con ssh -V e, sul server, mantieni attivi gli aggiornamenti di sicurezza automatici.

Fonti ufficiali e approfondimenti tecnici: progetto OpenSSH, documentazione Gpg4win per i client Windows, le specifiche IETF RFC 9580 sull’evoluzione di OpenPGP e le best practice di Riseup sulla gestione delle chiavi.