Cómo configurar 2FA para autenticarse en Ubuntu Server

Cómo configurar 2FA para autenticarse en Ubuntu Server

Por estos días estoy migrando algunas cosas, no solo de proveedor de Cloud, también de tecnología. Específicamente estoy moviendo algunas cosas de Azure a DigitalOcean, a la vez que saco cosas de Docker y ahora las tengo en Kubernetes.

Aprovechando esta migración he decidido adoptar ciertas medidas de seguridad, que son excelentes pero para lo mio, nunca lo había implementado.

Una de esas cosas es agregar un segundo factor de autenticación al login de los servidores cuando me conecto a ellos por SSH. Hay otras, que seguramente les voy a ir compartiendo en otros artículos.

Ahora bien, lo que te voy a mostrar en este tutorial, te sirve que para cuando te autentiques en el servidor, te pida un segundo código que puedas sacar desde una App como Google Authenticator, Authy o FreeOTP.

Empecemos

Lo primero que vamos a hacer es bajar alguna de estas aplicaciones a nuestro teléfono para el caso en el que aún no usemos 2FA para cualquier otro servicio (Muy mal).

Lo siguiente que vamos a tener en cuenta es que la configuración varia un poco dependiendo si nos autenticamos al servidor con contraseña o por medio de llaves SSH, pero eso lo vemos un poco más adelante.

Lo siguiente que tenemos que hacer es instalar Google Authenticator en el servidor:

$ sudo apt install -y libpam-google-authenticator

Una vez instalado, ejecutamos...

$ google-authenticator

Nos va a hacer una pregunta a la cual, le damos que si...

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

Luego nos aparecerá algo como esto:

Acá, lo que debemos hacer es escanear ese código QR con nuestra aplicación favorita para 2FA, la otra cosa que debemos hacer es guardar los códigos que nos aparecen ahí como respaldo por si perdemos el celular y necesitemos usarlos de emergencia.

Enseguida que nos aparece el código QR, vamos a ver nos pregunta lo siguiente y le vamos a responder que si:

Do you want me to update your "/root/.google_authenticator" file? (y/n) y

A la siguiente pregunta, también le vamos a decir que si:

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

La siguiente:

By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n) y

Y por último...

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) y

Ahora bien, es hora de configurar de manera específica si es que nos autenticamos por contraseña o usando llaves SSH.

Autenticación por contraseña

Si seguis usando contraseñas en 2021, bueno, dejame de decirte que te quedaste en el tiempo y comienza a usar llaves SSH. Pero si por el motivo que fuera, aún sigues usando contraseñas, los ajustes que hay que hacer en nuestro sistema operativo son los siguientes:

Vamos a abrir el archivo de configuración de OpenSSH:

$ nano /etc/ssh/sshd_config

Buscamos los siguientes dos parámetros y en ambos, los descomentamos y los cambiamos a "yes" (sin comillas).

UsePAM yes
ChallengeResponseAuthentication yes

Si quieres habilitar al usuario root a que se autentique también usando 2FA, también cambiamos a "yes" en la siguiente linea:

PermitRootLogin yes

Guardamos y cerramos.

Ahora vamos a editar el archivo el archivo de reglas PAM para el daemon SSH:

$ nano /etc/pam.d/sshd

Cuando abrimos este archivo, la primera linea que vamos a ver es esta:

@include common-auth

Enseguida abajo de esa linea, pegamos lo siguiente:

# two-factor authentication via Google Authenticator
auth   required   pam_google_authenticator.so

Quedaría de esta manera:

Por último, lo que hacemos es restartear el servicio SSH. Para eso ejecutamos:

$ systemctl restart sshd

Si no usas SystemD, la magia es:

$ /etc/init.d/ssh restart

Autenticación por llaves SSH

¿Qué pasa cuándo tenemos llaves SSH? pues nada, la configuración se modifica ligeramente:

Abrimos el archivo de configuración de OpenSSH Server...

$ nano /etc/ssh/sshd_config

Dejamos la configuración que agregamos más arriba y agregamos al final del archivo:

AuthenticationMethods publickey,keyboard-interactive

Abrimos el siguiente archivo:

$ nano /etc/pam.d/sshd

Acá, lo que debemos hacer es comentar la siguiente linea:

@include common-auth

Lo siguiente es agregar la siguiente linea:

# two-factor authentication via Google Authenticator
auth   required   pam_google_authenticator.so

Quedando así:

Guardamos, cerramos y por último, reiniciamos el servicio SSH:

$ systemctl restart ssh

Vamos a probarlo...

Si todo salió como esperamos, ahora, cada vez que nos autenticamos por SSH, mediante password o llave SSH, nos pedirá un código, recuerden que él mismo, saldrá de la aplicación OTP que hayamos instalado.

root@0efc91f6c426:/# ssh root@172.17.0.2
Password:
Verification code:

Ponemos el código de verificación que sacamos de nuestra aplicación y wala!

Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 4.19.104-linuxkit aarch64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

Para ir cerrando

Como ven, asegurar nuestro servidor mediante 2FA no es complicado. Si a esto le sumamos herramientras como Fail2ban, el uso de llaves SSH y el acceso mediante un bastión, se lo vamos a hacer muy complicado a quien quiera entrar a nuestra infrastructura con alguna intención maliciosa.

Si por esas casualidades, pierden el celular y no pueden acceder al celular o dispositivo donde tengan configurado Authenticator, Authy o FreeOTP de todos modos pueden autenticarse usando los códigos de emergencia que se generaron cuando arrancamos a configurar todo.

Eso es todo, espero que este artículo les haya gustado, si tenés alguna duda o consulta, puedes dejarla en los comentarios.