Abilitare la 2FA in ssh

lock Fonte: Foto di Life Of Pix da Pexels.com

Cosa si intende per 2FA

Attivare la 2FA è sempre una buona pratica per mitigare attacchi di tipo brute-force. Perché non farlo pure per ssh, soprattutto se lo si usa nel bastion host per accedere alla nostra lan? Da letteratura, la 2FA consiste nel fornire 2 fattori di autenticazione fra:

  1. qualcosa che sai (ad es. una password o un pin)
  2. qualcosa che hai (ad es. un otp)
  3. qualcosa che sei (ad es. un rilievo biometrico)

Se i fattori sono più di due, si parla di Multi Factor Authentication (MFA).

Non entro nel merito della configurazione di un servizio ssh , che non è banale. La diamo per scontata, ci concentriamo sulla parte di autenticazione.

Metodi di autenticazione

La buona norma vorrebbe che un'autenticazione su un server openssh si limitasse all'autenticazione con chiave pubblica. Su alcune distro ad es. è l'unica disponibile di default. Ma non basta una buona autenticazione per garantire la sicurezza di un servizio come SSH. Occorrerebbe intervenire su ben altri aspetti perché altrimenti sarebbe come preoccuparsi della bontà della porta blindata per la nostra casa dalle pareti di cartone.

I parametri del file di configurazione che andrò a trattare riguardano le modalità di autenticazione di ssh. La versione che sto usando su debian bullseye è la 8.4p1. Queste sono:

Le prime 3 sono quelle che ci interessano sul serio.

Con ssh posso avere:

  1. una 2FA (ad es. publickey + password)
  2. una MFA (ad es. publickey (qualcosa che sei) + password (qualcosa che sai) + OTP (qualcosa che hai) , se ipotizziamo publickey, in quanto certificato digitale, assimilabile al rilievo biometrico).

Per realizzare i due scenari c'è bisogno di settare con attenzione ssh per non rischiare di lasciare voragini invece che mettere in sicurezza il servizio.

Suppongo che ssh sia già settato come si deve, ciò che andrò a toccare sarà:

Ogni modifica del file di configurazione richiederà il restart del servizio ssh.

systemctl restart sshd.service

PAM

Com'è noto, e banalizzando molto, PAM è un sottosistema gnu/linux che fornisce un livello di astrazione a quelle applicazioni, come ssh, che richiedono autenticazione. In questo modo le applicazioni non hanno bisogno di implementarle esplicitamente e, volendo, possono estendere i propri schemi di autenticazione aumentandone la complessità in maniera relativamente semplice.

PAM, insieme ad una autenticazione di tipo challenge-response, ci permetterà di ottenere un'autenticazione multipla.

Scenario 1: Configurazione sicura (chiave pubblica)

In molti contesti si preferisce abilitare la sola autenticazione con chiave pubblica, proprio per evitare possibili falle. Niente PAM in questo caso ma solo configurazione ssh:

...
UsePAM=no
ChallengeResponseAuthentication=no
PublicKeyAuthentication=yes
PasswordAuthentication=no
AuthenticationMethods=publickey
...

PAM viene disabilitato perché scegliamo di non affidarci a librerie di autenticazione esterne. Inoltre, in casi estremi, si può pensare che un aggiornamento di PAM possa rompere la compatibilità con qualche libreria invalidando o indebolendo il processo di autenticazione.

Di conseguenza, niente autenticazione di tipo challenge-response, niente autenticazione con password.

Attiviamo solo la PublicKeyAuthentication rafforzando la scelta in AuthenticationMethods dove impostiamo come unico metodo valido publickey. Infine, riavviamo il servizio.

L'unico modo per accedere al server ssh è possedere una chiave (o un certificato) valida.

Scenario 2: 2FA (chiave pubblica + password)

Facciamo un passo in più è facciamo in modo che l'accesso al server sia consentito solo a chi possiede sia chiave che password.

...
UsePAM=no
ChallengeResponseAuthentication=no
PublicKeyAuthentication=yes
PasswordAuthentication=yes
AuthenticationMethods=publickey,password
...

Oltre che specificare il tipo di autenticazione (PublickeyAutentication e PasswordAuthentication), imponiamo che il metodo sia quello di esibire entrambe le credenziali.

Non impostando AutenticationMethods, varrebbe il default che prevede uno fra password, publickey o keyboard-interactive.

L'ultimo sarebbe comunque inutile in questo caso, visto che pam e challenge-response sono disabilitati. Ma non avremmo ottenuto ciò che ci eravamo prefissati.

Una configurazione analoga è la seguente:

...
UsePAM=yes
ChallengeResponseAuthentication=yes
PublicKeyAuthentication=yes
PasswordAuthentication=no
AuthenticationMethods=publickey,keyboard-interactive
...

Riavviamo ssh e la nuova autenticazione sarà disponibile come al solito.

È un esempio di come posso usare PAM per rimpiazzare la PasswordAuthentication nativa. Con una combinazione di PAM e autenticazione challenge-response, attraverso il metodo esplicito keyboard-interactive, l'applicazione autenticherà con un'unica sfida che è la richiesta di password.

Con PAM posso aggiungere altro, ad es. l'otp, come vedremo nel 3° scenario.

Scenario 3: MFA (chiave pubblica + password + otp)

Lasciamo inalterata la configurazione ssh dello scenario 2, quella che fa uso di pam. Bisogna innanzittutto installare il plugin per l'otp.

Sistemi debian-based:

apt install libpam-google-authenticator

Sistemi rpm-based:

dnf install google-authenticator

Per completezza, giusto perché lo uso, MacOS (via brew):

brew install google-authenticator-libpam

Dopo l'installazione, il generatore otp va inizializzato lanciando l'eseguibile che porrà una serie di domande:

A seguire, verrà mostrato sia il qr-code (per il caricamento automatico della chiave su un authenticator come FreeOtp+) che la chiave privata (se si vuole procedere con la configurazione manuale dell'authenticator o dello script visto tempo fa), necessari per la fornitura del primo codice che inizializza il processo.

Infine configuriamo PAM per sshd. In /etc/pam.d/sshd dobbiamo imporre che il processo di autorizzazione includa obbligatoriamente l'otp. Lo faremo aggiungendo una riga contenente il riferimento alla libreria che lo implementa:

auth required pam_google_authenticator.so

Il solito riavvio di ssh (alcuni consigliano anche di fare il reboot della macchina per inizializzare correttamente il generatore di otp ma non ho trovato una giustificazione convincente del perché) completa il lavoro.

Per autenticarsi sul server ssh ora serviranno:

Scenario 3bis: 2FA (chiave pubblica + otp)

Se invece volessi avere una 2FA come nello scenario 2, ma con otp invece che con password, posso procedere così. Si lascia inalterata la configurazione ssh e si commenta una riga dalla configurazione di PAM:

Su /etc/pam.d/sshd commentare la seguente riga così:

...
#@include common-auth
...

In questo modo, si elimina la richiesta della password utente dalle “sfide” della challenge-response e rimane la sola richiesta otp.

Tips

Attenzione quando si gioca con i metodi di autenticazione ssh. Ci sono buone possibilità che vi autoescludiate dal vostro server. Basta avere keyboard-interactive (che implica un'autenticazione di tipo challenge-response) fra i metodi di autenticazione obbligatori e pam disattivato. Ecco un esempio:

...
usePAM no 
ChallengeResponseAuthentication yes
PasswordAuthentication no
PubkeyAuthentication no
AuthenticationMethods keyboard-interactive
...

Oppure, ancora più subdolo, lo scenario 3 con pam disabilitato, ossia: configurazione ssh

...
usePAM no 
ChallengeResponseAuthentication yes
PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
...

In questi casi, l'autenticazione fallirà con questo errore: “Permission denied (keyboard-interactive)” perché non sarà disponibile nessuna interazione da tastiera (es. una password) e noi rimarremmo chiusi irrimediabilmente fuori dal nostro server.

#ssh #otp