Cómo bastionar el servicio SSH

Cuando tenemos una máquina con linux en la que está instalado SSH solemos dar por sentado que el servicio y la configuración son correctas y que no corremos ningún riesgo. Y no siempre es así y debemos ir un paso más allá para mejorar la seguridad y la integridad del servicio.

Os presento 9 acciones que podemos implementar en nuestro servicio SSH para mejorar la seguridad, limitar el acceso y bloquear los intentos de acceso no autorizado.

Prerequisitos

Necesitaremos, como no, una máquina con Ubuntu 😉 Nosotros hemos optado por una recién salida del horno Ubuntu 24.04 LTS Server virtualizada.

La máquina dispone de dos interfaces de red. La primera está configurada en modo NAT para poder tener acceso a internet para descargar alctualizaciones y software. La segunda está en la misma red que el ordenador físico y le he asignado la 192.168.52.8/24. De esta manera podré acceder desde mi ordenador de escritorio a la máquina virtual ya que ambas comparten direccionamiento.

Medidas para securizar nuestro SSH

La mayoría de las configuracions que desarrollaremos en este documentos se harán en el archivo /etc/ssh/sshd_config. Ojo que el archivo se llama sshd_config, con una d después del ssh. Y éste hace referencia al servicio (daemon) de ssh.

Para editar los archivos usaremos el editor de archivos con el que nos sintamos cómodos, como el nano. Yo soy un tipo raro y uso vi.

Después de cada modificación necesitaremos reiniciar el servicio. SSH se reinicia en Ubuntu con el siguiente comando :

sudo systemctl restart ssh

Deshabilitar el acceso sin password

Parece una obviedad pero hemos de verificar que no se va a poder acceder sin una contraseña definda. Probablemente en un servidor nuevo no nos vamos a encontrar con esta situación pero podemos encontrar instalaciones con un cierto tiempo, para «facilitar» la ejecución de algunos comandos o transferencia de datos se ha permitido que determinados usuarios accedan sin contraseña.

Ubuntu hace años que la opción PermitEmptyPasswords tiene por defecte el valor no. De todas maneras, no está de más verificar que dicha opción se encuentra comentada o en su defecto, con la opción no.

Cambiar el puerto por defecto

Mucho software que se dedica a intentar entrar en los sistemas a través de fuerza bruta atacan el puerto 22, donde escucha SSH. Cambiar de puerto el servicio es una buena opción siempre y sea factible, ya que puede que no dependa de nostros, no tengamos acceso a la máquina o tengamos el puerto abierto públicamente.

Editaremos el archivo de configuración del servicio y buscaremos la directiva Port. En nuestro caso vamos a cambiar el puerto al 2222.

Port 2222

Si nuestro servidor dispone de más de una interfaz podremos tambien forzar que las conexions a ese puerto deben entrar por la IP de esa interfaz.

ListenAddress 192.168.56.8

Una vez modificados reiniciaremos el servicio y probaremos a conectarnos.

A partir de Ubuntu 22.04 (ésta incluída) se cambia la manera en que SSH «escucha» las conexiones entrantes. Las conexions se gestionan a través de un socket e ignora la configuración del archivo de configuración.

Hemos experimentado ciertos problemas cuando movemos SSH a un nuevo puerto por lo que para volver al mecanismo que se utiliza en versiones anteriores únicamente hay que ejecutar los siguientes comandos :

sudo systemctl disable ssh.socket
sudo systemctl daemon-reload
sudo systemctl enable ssh.service
sudo systemctl start ssh.service

Deshabilitar el acceso del usuario root

Ya hace un tiempo que en Ubuntu las conexiones remotas del usuario root no están permitidas con contraseña pero sí que las permiten si se hace con certificados gracias a que por defecto està predefinido el valor prohibit-password.

Si queremos bloquear completamente el acceso remoto del usuario root definiremos la directiva PermitRootLogin a no en el fichero de configuración y después reiniciaremos el servicio.

PermitRootLogin no

De esta manera tendremos a seguridad que ningún usuario podrá conectarse a nuestro sistema usando el usuario root.

El usuario root en sistemas Ubuntu viene desactivado. Existe un mecanismo para poder activarlo pero no se considera una buena práctica.

Sé inteligente y no desbloquees el usuario root.

Desactivar el protocolos SSH1 y X11

Existen protocolos que se pueden usar con SSH que, por inseguros, conviene desactivar. Ubuntu hace tiempo que ya no implementa la version 1 del protocolo SSH. Si nos encontrásemos en un servidor esta versión lo más recomendable sería cambiarlo a SSH2 a través de la directiva :

 Protocol 2

Si queremos saber si podemos conectar a nuestro sistema usando SSH1 podemos hacer un intento de conexión y el servidor nos debería devolver que el protocolo ya no está implemetado.

Captura intento acceso SSH1

El protocolo X11 permite gestionar sesiones remotas de entorno gràfico utilizando túnels SSH. Existe controversia sobre la seguridad de esta práctica pero está claro que si no vamos a usar este funcionalidad lo mejor serà desactivarla. Para hacerlo simplemente podremos en no el valor de la directiva X11Forwarding.

X11Forwarding no

Configurar el tiempo de desconexión por inactividad

Podemos minimizar el tiempo que una sesión puede estar abierta e inactiva para evitar riesgos con sysadmins despistados. Cambiando el valor de la directiva ClientAliveInterval a un valor en segundos pequeño forzaremos una desconexión de la sessión pasados esos segundos de inactividad.

ClientAliveInterval 180

Definir de manera explícita los usuarios y/o grupos con acceso

Por defecto, cualquier usuario que creemos en un sistema y que tenga una consola válida y una contraseña definida, podrá acceder a nuestro sistema. SSH nos permite definir listas blancas o white lists donde podremos definir qué grupos y/o usuarios pueden acceder al sistema.

Para definir qué usuarios permitimos el acceso utilizaremos la directiva AllowUsers seguida por el listado separado por espacio de los usuarios que van a tener acceso.

AllowUsers harry hermione

Para los grupos usaremos AllowGroups. separando con espacio los diferentes grupos.

AllowGroups gryffindor

La directiva AllowUsers tiene precedencia sobre AllowGroups por lo que no es conveniente usarlas juntas porque lo que definamos en AllowGroups no funcionarà.

Siempre es una buena práctica definir grupos de usuarios por encima de usuarios individuales.

Desactivar los accesos basados en contraseñas

SSH viene configurado por defecto para pedir la contraseña a no ser que dispongamos de una clave que nos garantice el acceso. Es por ello que si tenemos un usuario con una contraseña débil puede poner en peligro el sistema, por no hablar que se puedan haber exfiltrado las contraseñas de los usuarios.

Además, los ataques de fuerza bruta se basan en ir probando contraseñas hasta que una permita el acceso. Este tipo de software simula que introduce el usuario y espera que el sistema le devuelva la palabra Password o alguna de las posibles variantes para introducir el password. Si desactivamos que no se pida contraseña este tipo de ataque queda inutilizado ya que nunca daremos la opción para introducir la contraseña.

Para desactivar las contraseñas como mecanismo de autentitcación editaremos el archivo /etc/ssh/sshd_config.d/50-cloid-init.conf, activaremos la directiva PasswordAuthentication i estableceremos su valor a no.

PasswordAuthentication no

Reiniciaremos el servicio para aplicar la configuración.

Captura de login con contraseña con SSH
Antes de desactivar la autenticación basada en contraseña.
Captura del sistema denegando el acceso a un usuario y no mostrando la solicitud de pasword.
Después de desactivar la validación basada en contraseña.
Usuario accediendo al sistema con certificado.
Usuario accediendo al sistema con certificado ya que se han desactivado las contraseñas.

En este caso, la directiva PasswordAuthentication del archivo de configuración /etc/ssh/sshd_config no se aplica. Hay una configuración más específica dentro de la carpeta /etc/ssh/sshd_config y que sobreescribe el valor que pueda tener el fichero general. Es por eso que tenemos que modificar el archivo /etc/ssh/sshd_config.d/50-cloud-init.conf.

Recuerda que si implementas esta medida debes poder tener acceso a la máquina con otro mecanismo, ya sea por la consola del propio equipo o a través de SSH con validación por certificado.

En el artículo Cómo configurar SSH para autenticar con clave pública y privada explico cómo configurar el acceso basado en claves pùblicas / privadas

Mitigación de ataques de fuerza bruta

Los ataques de fuerza bruta se basan en intentar averiguar la contraseña de un usuario del sistema aplicando diccionarios de palabras y frases. Básicamente se usan listas de palabras o contraseñas ya conocidas (como password, 1234, etc) para intentar acceder al sistema.

Cuando nos hacen un ataque de fuerza bruta no sólo supone un estrés para el servicio SSH. Atender todas las peticiones que se están recibiendo puede suponer que la calidad del servicio se vea afectada y otros servicios como servidores web, bases de datos o sistemas de correo funcionen más despacio o incluso lleguen a colapsarse.

La mecánica de mitigación de un ataque de fuerza bruta contra SSH puede resultar tan sencilla como analizar los registros de intento de acceso y si detectamos un número determinado de intentos fallidos desde una dirección IP en un espacio corto de tiempo procederemos a bloquearlo.

Esto que suena tan sencillo realmente lo es gracias a una herramienta como fail2ban. Con esta herramienta podemos crear filtros que revisen los registros de sistema buscando determinados patrones y si se localizam, que ejecute una acción, como por ejemplo, bloquear la dirección IP que está lanzando la petición.

En un artículo posterior detallaremos cómo configurar fail2ban en nuestro sistema para bloquear direcciones IP con más de determinados intentos fallidos de acceso al sistema.

Si no quieres perderte este artículo cuando salga, suscríbete a la newsletter.

Implementar un mecanismo de múltiple factor de autenticación

Los sistemas de múltiple factor de autenticación nos permite usar un segundo mecanismo de validación. Así, cuando queremos acceder a un servidor no será suficiente con tener el certificado : además deberemos usar un código que nos llegará por SMS a nuestro dispositivo móvil o un código de nuestra aplicación de autenticación (como Google Authenticator o Authy).

En un post posterior detallaremos cómo usar MFA para autenticarse por SSH. De esta manera, una vez intentemos hacer login nos pedirá un número de código que tenemos en una aplicación de nuestro teléfono móvil.

¿ Te vas a perder este artículo cuando se publique ? ¡ Suscríbete al newsletter!

Notas finales

Estas son unas recomendaciones más o menos estandarizadas pero tendremos que ver en cada caso qué es viable para nosotros.

Si os ha gustado este artículo no olvidéis compartirlo.