Implementar MFA para autenticar accesos SSH

El acceso por SSH se ha normalizado como el mecanismos de acceso remoto a los sistemas basados en GNU/Linux. Existe la creencia que el propio hecho de usar SSH ya es garantía de seguridad pero como hemos ido viendo en artículos anteriores, la configuración por defecto del servicio es mejorable.

En este artículo se plantea el uso de un mecanismo de doble factor de autenticación para acceder por SSH. En este escenario partiremos de una configuración de acceso basada en usuario y contraseña por lo que la configuración por defecto de nuestra distribución ya nos servirá.

Requerimientos

Se requiere un servidor linux, en mi caso Ubuntu, con el servicio SSH activado. Es recomendable que verifiquemos que tenemos acceso por consola a la máquina ya que si hacemos algún paso mal podremos perder el acceso.

Además necesitaremos instalar una app de autenticación como Authy o Google Authenticator.

Instalación

Una vez tenemos la máquina desplegada y con acceso SSH necesitaremos descargar la librería que nos va a a permitir autenticarnos con doble factor. Esta librería es un módulo de PAM (Pluggable Authentication Modules) que, entre otras cosas, nos va a permitir definir en qué punto del proceso de autenticación se va a proceder a validar el login con un doble factor.

PAM es una mecanismo modular que permite configurar el proceso de autenticación y autorización añadiendo paquetes. De esta manera es posible hacer que una máquina Linux valide contra un Active Directory o, como en este caso, se añada una capa extra de validación con una app.

Para instalar la librería de Google Authenticator ejecutaremos :

sudo apt install libpam-google-authenticator

Configuración de PAM

Una vez instalado el paquete deberemos indicarle a PAM que queremos que el servicio ssh use el nuevo módulo de autenticación. Para hacerlo editaremos el archivo /etc/pam.d/sshd y añadiremos al final del archivo:

auth required pam_google_authenticator.so

Como curiosidad resaltar que si en vez de añadir esta línea al final la añades al inicio del archivo primero te preguntará por el código y luego por la contraseña del usuario.

Configuración SSH

Para indicar al servicio ssh que queremos usar el doble factor hemos de editar el archivo /etc/ssh/sshd_config y cambiar el valor de KbdInteractiveAuthentication a yes. La configuración debería quedar tal que así :

KbdInteractiveAuthentication yes

Si usamos Ubuntu 22.04 o anteriores hemos de usar la directiva ChallengeResponseAuthentication.

ChallengeResponseAuthentication yes

Reiniciaremos el servicio con :

sudo systemctl restart ssh

Configuración de Google Authenticator

Accederemos a una consola de la máquina con el usuario que queremos que tenga MFA y ejecutamos:

google-authenticator

Al ejecutar el comando nos preguntará si queremos que la autenticación sea en base a tokens basados en tiempo. Le indicaremos que sí.

Do you want authentication tokens to be time-based (y/n) y

A continuación se mostrará el código QR y un link a el mismo código QR en línea por si no se puede visualizar correctamente. Además también nos mostrará el código alfanumérico equivalente.

Con la aplicación de doble factor de autenticación podremos escanearlo o introducir el código para hacer la vinculación. También nos mostrará los códigos de recuperación. Estos códigos se deben copiar en un sitio seguro ya que son los que garantizarán que podamos acceder en caso de que no tengamos acceso al sistema de MFA.

Código QR de ejemplo con el que configurar la aplicación de autenticación.

Nos seguirá haciendo preguntas:

Enter code from app (-1 to skip) : -1
...
Do you want me to update your "/home/andres/.google_authenticator" file= (y/n) y
Do you want to disallow multiple uses of the same authentication token ? [...] (y/n) y
By default [...] Do you want to do so (y/n) n
If the computer [...] Do you want to enable rate-limiting? (y/n) y

La primera nos preguntará por el código de la app. Si indicamos -1 se saltará la validación aunque es recomendable que validemos con un código de la aplicación que funciona correctamente.

La siguiente pregunta es para permitir que nos actualice el archivo .google_authenticator de nuestro usuario.

A continuación nos pregunta sobre queremos bloquear múltiples usos del mismo token. O sea, que un token sólo se va a poder usar una única vez.

La penúltima pregunta es acerca de incrementar el número de tokens válidos antes y después del que nos toca actualmente. Si marcamos que sí querrá decir que va a aceptar como válidos los 8 tokens anteriores al que está actualmente disponible y los 8 siguientes. De esta manera da solución a posibles problemas de sincronización horaria entre dispositivos con un margen de 4 minutos antes y 4 minutos después. Si indicamos que no únicamente va a permitir 3 intentos antes y 3 intentos despues minimizando el margen a 90 segundos de desfase.

Finalmente nos pregunta acerca si queremos limitar a tres accesos máximo cada 30 segundos para protegernos de ataques de fuerza bruta.

Lo recomendable es responder a todas las preguntas afirmativamente para mejorar la seguridad y la disponibilidad del servicio.

Acceso SSH

Para poder acceder primero nos pedirá la contraseña y si es correcta, nos pedirá el código de la aplicación de autenticación que tenemos en el móvil. Si todo es correcto podremos acceder a nuestra consola.

Imagen en la que se hace login y en el que se ve como pide el código de la aplicación de validación.

¿Funciona con autenticación por clave pública/privada?

¡Sí! Hay que hacer unas leves modificaciones en los archivos y podrás validarte con clave pública/privada sin problemas.

Si has llegado hasta aquí y no sabes de qué va esto de hacer login con el par clave pública/privada te invito a que leas el artículo Cómo configurar SSH para autenticar con clave pública y privada.

Editamos el archivo /etc/pam.d/ssh y comentamos la línea que indica @include common-auth de manera que queda:

#@include common-auth

A continuación editamos el archivo /etc/ssh/sshd_config y añadimos al final del archivo:

AuthenticationMethods publickey,keyboard-interactive

Guardamos y reiniciamos el servicio con:

sudo systemctl restart ssh

Finalmente hacemos una conexión para comprobar:

No te pierdas nada

Voy publicando artículos de vez en cuando. Si crees que son interesantes y no te los quieres perder, suscríbete a mi boletín.