SSH con 2FA su Linux si implementa installando il modulo PAM google-authenticator, generando il secret TOTP per l’utente, e modificando la configurazione di PAM e sshd per richiedere il codice OTP dopo la password o la chiave pubblica. In 10 minuti blocchi l’accesso da credenziali rubate.
| Step | File/Comando | Azione |
|—|—|—|
| 1 | sudo apt install libpam-google-authenticator | Installa modulo OTP |
| 2 | google-authenticator | Genera secret e QR per l’utente |
| 3 | /etc/pam.d/sshd | Aggiungi riga auth required |
| 4 | /etc/ssh/sshd_config | Abilita ChallengeResponseAuthentication |
| 5 | sudo systemctl restart sshd | Applica modifiche |
Credenziali SSH di un server di staging vendute su Telegram. Il server era raggiungibile dall’esterno e usava autenticazione a sola password. 2FA avrebbe bloccato tutto. L’attacco è durato 6 ore prima che qualcuno notasse il carico anomalo sulla CPU. Il 73% dei breach parte da credenziali rubate, secondo il Verizon DBIR 2025. Quando ho implementato l’autenticazione a due fattori su 50 server per un ente sanitario pubblico, la criticità principale era evitare di bloccare fuori gli operatori durante il turno di notte. La soluzione è testare mantenendo una sessione aperta. Ecco come fare.
Prerequisiti / Ambiente di test
Serve un server Ubuntu 20.04 o 22.04 LTS, accesso SSH con privilegi sudo, e un’app TOTP sul telefono (Google Authenticator, Authy, Microsoft Authenticator). Il 51% degli attacchi brute force SSH ha successo entro 12 ore se la password è debole (Rapid7 2025). Non testare questa procedura direttamente su un server in produzione senza una sessione di fallback aperta.
Installare google-authenticator-libpam
Il pacchetto collega il sistema di autenticazione Linux (PAM) al generatore di codici temporizzati TOTP.
sudo apt update
sudo apt install libpam-google-authenticator
Su RHEL/CentOS il pacchetto si trova in EPEL: sudo yum install google-authenticator. L’installazione non modifica ancora l’accesso SSH. Modifica solo la disponibilità del modulo.
Configurare per l’utente
Ogni utente che deve usare 2FA genera il proprio secret. Non eseguire questo comando con sudo per un altro utente, perché il secret finirebbe nella home di root.
google-authenticator
Il comando chiede cinque domande. Rispondi Y a tutte:
- Do you want authentication tokens to be time-based? Y
- Do you want to inhibit multiple uses? Y (blocca reuse del codice)
- Do you want to enforce rate-limiting? Y (max 3 tentativi ogni 30 secondi)
- Do you want to limit the number of failures before banning? Y (max 3 fallimenti)
- Do you want to enable rate-limiting in the log file? Y
Il terminale mostra il QR code, il secret key manuale, e i codici scratch per il recovery.
Scansionare il QR code con l’app
Apri Google Authenticator sul telefono. Seleziona Aggiungi account, scansiona il QR code mostrato nel terminale. L’app inizia a generare codici a 6 cifre che cambiano ogni 30 secondi. Se il QR non si scansiona dal terminale remoto, inserisci il secret key manuale mostrato sotto il QR.
Salva il secret key in un posto sicuro. Serve per rigenerare l’account se perdi il telefono.
Modificare PAM per abilitare 2FA
PAM (Pluggable Authentication Modules) decide come Linux verifica le credenziali. Modifica il file che gestisce SSH.
sudo nano /etc/pam.d/sshd
Aggiungi questa riga all’inizio del file, prima delle altre righe auth:
# /etc/pam.d/sshd: auth required pam_google_authenticator.so
auth required pam_google_authenticator.so nullok
Il parametro nullok è critico. Permette l’accesso senza 2FA se l’utente non ha ancora generato il file .google_authenticator nella propria home. Senza nullok, tutti gli utenti senza secret restano bloccati fuori. Rimuovi nullok solo dopo che ogni utente ha configurato il proprio secret.
Modificare sshd_config
Il demone SSH deve sapere che richiedere il challenge-response per il codice OTP.
sudo nano /etc/ssh/sshd_config
Trova e modifica queste righe:
# sshd_config: ChallengeResponseAuthentication yes
ChallengeResponseAuthentication yes
Se la riga è commentata o impostata a no, SSH ignora la richiesta OTP di PAM. Verifica anche che PasswordAuthentication sia yes se vuoi la combinazione password + OTP. Se usi solo chiave pubblica + OTP, PasswordAuthentication resta no, ma serve la configurazione Keyboard-Interactive descritta nella documentazione ufficiale.
Applica le modifiche:
sudo systemctl restart sshd
Testare senza chiudere la sessione corrente
Questo è il passaggio dove molti si bloccano fuori. NON chiudere la sessione SSH attiva. Apri un nuovo terminale e tenta il login.
ssh utente@server-ip
Il sistema chiede prima la Verification code (l’OTP dal telefono), poi la password. Se il login fallisce, torna alla sessione originale, rimuovi la riga da /etc/pam.d/sshd, riavvia sshd, e verifica cosa è andato storto.
Se il login funziona, ora l’accesso richiede password e OTP. Chiudi la sessione di test.
Gestire i codici di backup
Il comando google-authenticator genera 5 codici scratch (emergency scratch codes). Sono codici one-time che funzionano una sola volta, senza il telefono.
Salva questi codici offline, in un posto accessibile senza il server stesso. Se perdi il telefono e non hai i codici scratch, resti bloccati fuori. Per rigenerare i codici, esegui di nuovo google-authenticator, ma il secret cambia e devi aggiornare l’app.
Escludere utenti specifici dal 2FA
Gli account di servizio o gli utenti amministrativi di backup non hanno un telefono per l’OTP. Il parametro nullok gestisce questo caso. Se il file .google_authenticator non esiste nella home dell’utente, PAM salta la verifica OTP e richiede solo la password.
Per escludere un utente specifico anche dopo aver attivato 2FA per tutti, crea un file di skip in PAM.
sudo nano /etc/pam.d/sshd
Modifica la riga auth required:
auth [success=done default=ignore authinfo_missing=ignore] pam_google_authenticator.so nullok_skippable
In alternativa, usa la direttiva PAM user sense=ignore per specificare gli utenti esclusi. La documentazione Arch Linux spiega le opzioni avanzate di PAM per questi scenari.
Errori comuni e troubleshooting
Accesso negato dopo restart sshd: ChallengeResponseAuthentication è ancora no in sshd_config, o la riga PAM è in posizione sbagliata (dopo le altre auth). Deve essere la prima riga auth.
SSH chiede solo password, niente OTP: nullok è attivo e l’utente non ha generato il secret, oppure sshd non è stato riavviato dopo la modifica.
Codice OTP rifiutato: Il tempo del server è sfasato. TOTP tollera una finestra di 30 secondi. Sincronizza il server con NTP (sudo timedatectl set-ntp true).
Bloccato fuori: Se non hai mantenuto la sessione aperta e il login fallisce, serve l’accesso console fisica o via provider cloud (VNC) per ripristinare i file.
FAQ — Domande Frequenti
Come funziona 2FA SSH con chiave pubblica invece di password?
Se usi chiave pubblica, SSH autentica già l’identità. Per aggiungere 2FA, configura Keyboard-Interactive in sshd_config e PAM richiede l’OTP dopo la verifica della chiave. La procedura differisce dalla configurazione password+OTP.
Qual è la differenza tra nullok e nullok_skippable?
nullok permette il login senza OTP se il file secret non esiste. nullok_skippable fa lo stesso ma non logga l’evento come errore PAM. Per la transizione graduale usa nullok, per gli account di servizio permanenti usa nullok_skippable.
Posso usare Authy o Microsoft Authenticator invece di Google Authenticator?
Si. Il modulo PAM usa lo standard TOTP (RFC 6238). Qualsiasi app compatibile con TOTP genera codici validi. Il QR code è universale.
Cosa fare se perdo il telefono e i codici scratch?
Serve accesso console fisica o web console del provider. Accedi come root, rimuovi la riga pam_google_authenticator.so da /etc/pam.d/sshd, riavvia sshd, poi rigenera il secret per l’utente.
2FA SSH è richiesto dalla compliance NIS2?
L’articolo 21 di NIS2 richiede MFA per gli accessi agli asset critici. 2FA SSH su server in produzione è un requisito diretto per enti sanitari e PA.
Conclusioni con takeaway operativi
Aggiungere Google Authenticator a SSH Linux richiede 10 minuti e blocca il 100% degli accessi con credenziali rubate. I tre passaggi critici: installa il modulo PAM, genera il secret per ogni utente, modifica sshd_config e PAM. Il rischio più grande è bloccarsi fuori durante il test. Mantieni sempre una sessione aperta. Rimuovi nullok solo quando tutti gli utenti hanno il secret attivo. Le organizzazioni soggette a NIS2 devono implementare MFA su tutti gli accessi critici. 2FA SSH è il primo passo.
Leggi anche: Hardening SSH Linux: Guida Completa 2026 (10 Impostazioni Critiche)
Leggi anche: Fail2ban su Linux: Configurazione Completa e Sicurezza SSH
Leggi anche: Lynis Audit Sicurezza Linux: Guida Completa e Pratica (2026)
Aggiornato: Aprile 2026