Cómo proteger SSH con Fail2Ban en Rocky Linux 8

Introducción

SSH es el método por excelencia para conectarse a un servidor en la nube. Es duradero y extensible: a medida que se desarrollan nuevos estándares de cifrado, pueden utilizarse para generar nuevas claves SSH, asegurando que el protocolo principal permanezca seguro. Sin embargo, ningún protocolo o conjunto de software es totalmente infalible, y dado que SSH está tan ampliamente desplegado en Internet, representa una superficie de ataque muy predecible a través de la cual las personas pueden intentar obtener acceso.

Cualquier servicio expuesto a la red es un objetivo potencial de esta manera. Si revisas los registros de tu servicio SSH en cualquier servidor con mucho tráfico, a menudo verás intentos de inicio de sesión repetidos y sistemáticos que representan ataques de fuerza bruta tanto por parte de usuarios como de bots. Aunque puedes realizar algunas optimizaciones en tu servicio SSH para reducir la probabilidad de que estos ataques tengan éxito a casi cero, como desactivar la autenticación por contraseña a favor de las claves SSH, aún pueden representar una responsabilidad menor y continua.

Las implementaciones de producción a gran escala para las cuales esta responsabilidad es completamente inaceptable generalmente implementarán una VPN como WireGuard frente a su servicio SSH, de manera que sea imposible conectarse directamente al puerto SSH predeterminado 22 desde Internet externo sin software adicional de abstracción o pasarelas. Estas soluciones de VPN son ampliamente confiables, pero agregarán complejidad y pueden romper algunas automatizaciones u otros ganchos de software pequeños.

Antes o además de comprometerse con una configuración completa de VPN, puede implementar una herramienta llamada Fail2ban. Fail2ban puede mitigar significativamente los ataques de fuerza bruta creando reglas que alteran automáticamente la configuración de su firewall para prohibir IPs específicas después de cierto número de intentos de inicio de sesión fallidos. Esto permitirá que su servidor se proteja contra estos intentos de acceso sin intervención de su parte.

En esta guía, verás cómo instalar y usar Fail2ban en un servidor Rocky Linux 8.

Requisitos previos

Para completar esta guía, necesitarás:

  • Un servidor Rocky Linux 8 y un usuario no root con privilegios sudo. Puedes obtener más información sobre cómo configurar un usuario con estos privilegios en nuestra guía Configuración Inicial del Servidor con Rocky Linux 8. También deberías tener firewalld ejecutándose en el servidor, lo cual está cubierto en nuestra guía de configuración inicial del servidor.

  • Opcionalmente, un segundo servidor al que puedes conectarte desde tu primer servidor, que usarás para probar ser deliberadamente prohibido.

Paso 1 — Instalación de Fail2ban

Fail2ban no está disponible en los repositorios de software predeterminados de Rocky. Sin embargo, está disponible en el repositorio EPEL, o Paquetes Mejorados para Linux Empresarial, que se utiliza comúnmente para paquetes de terceros en Red Hat y Rocky Linux. Si aún no has agregado EPEL a las fuentes de paquetes de tu sistema, puedes agregar el repositorio usando dnf, como instalarías cualquier otro paquete:

  1. sudo dnf install epel-release -y

El administrador de paquetes dnf ahora verificará EPEL además de tus fuentes de paquetes predeterminadas al instalar nuevo software. Continúa con la instalación de Fail2ban:

  1. sudo dnf install fail2ban -y

Fail2ban configurará automáticamente un servicio en segundo plano después de ser instalado. Sin embargo, está desactivado de forma predeterminada, debido a que algunos de sus ajustes por defecto pueden causar efectos no deseados. Puedes verificar esto utilizando el comando systemctl:

  1. systemctl status fail2ban.service
Output
○ fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; disabled; vendor preset: disabled Active: inactive (dead) Docs: man:fail2ban(1)

Podrías habilitar Fail2ban de inmediato, pero primero revisarás algunas de sus características.

Paso 2 – Configuración de Fail2ban

El servicio fail2ban guarda sus archivos de configuración en el directorio /etc/fail2ban. Hay un archivo con valores por defecto llamado jail.conf. Ve a ese directorio e imprime las primeras 20 líneas de ese archivo usando head -20:

  1. cd /etc/fail2ban
  2. head -20 jail.conf
Output
# # ADVERTENCIA: altamente refactorizado en la versión 0.9.0. Por favor, revise y # personalice la configuración para su instalación. # # Cambios: en la mayoría de los casos no debería modificar este # archivo, sino proporcionar personalizaciones en el archivo jail.local, # o en archivos .conf separados en el directorio jail.d/, por ejemplo: # # CÓMO ACTIVAR LAS JAILS: # # NO DEBERÍA MODIFICAR ESTE ARCHIVO. # # Probablemente será sobrescrito o mejorado en una actualización de distribución. # # Proporcione personalizaciones en un archivo jail.local o en un jail.d/customisation.local. # Por ejemplo, para cambiar el tiempo de bloqueo predeterminado para todas las jails y para habilitar la # jail ssh-iptables, lo siguiente (sin comentar) aparecería en el archivo .local. # Consulte el manual 5 jail.conf para más detalles. # # [DEFAULT]

Como verás, las primeras líneas de este archivo están comentadas – comienzan con caracteres # indicando que deben ser leídas como documentación en lugar de como configuraciones. Como también verás, estos comentarios te indican que no modifiques este archivo directamente. En cambio, tienes dos opciones: crear perfiles individuales para Fail2ban en múltiples archivos dentro del directorio jail.d/, o crear y recopilar todas tus configuraciones locales en un archivo jail.local. El archivo jail.conf será actualizado periódicamente a medida que se actualice Fail2ban, y se utilizará como fuente de configuraciones predeterminadas para las cuales no hayas creado ninguna anulación.

En este tutorial, crearás jail.local. Puedes hacerlo copiando jail.conf:

  1. sudo cp jail.conf jail.local

Ahora puedes comenzar a realizar cambios de configuración. Abre el archivo en vi o tu editor de texto favorito:

  1. sudo vi jail.local

Mientras estás navegando por el archivo, este tutorial revisará algunas opciones que es posible que desees actualizar. Los ajustes ubicados bajo la sección [DEFAULT] cerca del principio del archivo se aplicarán a todos los servicios admitidos por Fail2ban. En otras partes del archivo, hay encabezados para [sshd] y para otros servicios, que contienen configuraciones específicas del servicio que se aplicarán sobre los valores predeterminados.

/etc/fail2ban/jail.local
[DEFAULT]
. . .
bantime = 10m
. . .

El parámetro bantime establece la duración del tiempo durante el cual un cliente será prohibido cuando haya fallado en la autenticación correctamente. Esto se mide en segundos. Por defecto, está establecido en 10 minutos.

/etc/fail2ban/jail.local
[DEFAULT]
. . .
findtime = 10m
maxretry = 5
. . .

Los dos siguientes parámetros son findtime y maxretry. Estos trabajan juntos para establecer las condiciones bajo las cuales un cliente se considera un usuario ilegítimo que debe ser prohibido.

La variable maxretry establece el número de intentos que un cliente tiene para autenticarse dentro de una ventana de tiempo definida por findtime, antes de ser prohibido. Con la configuración predeterminada, el servicio fail2ban prohibirá a un cliente que intente iniciar sesión sin éxito 5 veces dentro de una ventana de 10 minutos.

/etc/fail2ban/jail.local
[DEFAULT]
. . .
destemail = root@localhost
sender = root@<fq-hostname>
mta = sendmail
. . .

Si necesitas recibir alertas por correo electrónico cuando Fail2ban tome acción, debes evaluar la configuración de destemail, sendername y mta. El parámetro destemail establece la dirección de correo electrónico que debería recibir los mensajes de prohibición. El sendername establece el valor del campo “De” en el correo electrónico. El parámetro mta configura qué servicio de correo se utilizará para enviar el correo. Por defecto, esto es sendmail, pero es posible que desees utilizar Postfix u otra solución de correo.

/etc/fail2ban/jail.local
[DEFAULT]
. . .
action = $(action_)s
. . .

Este parámetro configura la acción que Fail2ban toma cuando desea instituir una prohibición. El valor action_ está definido en el archivo poco antes de este parámetro. La acción predeterminada es actualizar la configuración de tu firewall para rechazar el tráfico del host infractor hasta que el tiempo de prohibición transcurra.

Existen otros scripts de action_ proporcionados por defecto que puedes reemplazar $(action_) con lo siguiente:

/etc/fail2ban/jail.local
…
# prohibir y enviar un correo electrónico con un informe whois a la destemail.
action_mw = %(action_)s
            %(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]

# prohibir y enviar un correo electrónico con un informe whois y líneas de registro relevantes
# a la destemail.
action_mwl = %(action_)s
             %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]

# Ver la nota IMPORTANTE en action.d/xarf-login-attack para saber cuándo utilizar esta acción
#
# prohibir y enviar un correo electrónico xarf al contacto de abuso de la dirección IP e incluir líneas de registro relevantes
# a la destemail.
action_xarf = %(action_)s
             xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]

# prohibir la IP en CloudFlare y enviar un correo electrónico con un informe whois y líneas de registro relevantes
# a la destemail.
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
                %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
…

Por ejemplo, action_mw realiza una acción y envía un correo electrónico, action_mwl realiza una acción, envía un correo electrónico e incluye registro, y action_cf_mwl hace todo lo anterior además de enviar una actualización a la API de Cloudflare asociada con tu cuenta para prohibir al infractor también.

Configuración Individual de Cárceles

La siguiente es la parte del archivo de configuración que trata sobre servicios individuales. Estos se especifican mediante encabezados de sección, como [sshd].

Cada una de estas secciones necesita ser habilitada individualmente agregando una línea enabled = true debajo del encabezado, junto con sus otras configuraciones.

/etc/fail2ban/jail.local
[jail_to_enable]
. . .
enabled = true
. . .

Para este tutorial, habilitarás la cárcel SSH. Debería estar en la parte superior de la configuración de la cárcel individual. Los parámetros predeterminados funcionarán de otra manera, pero necesitarás agregar una línea de configuración que diga enabled = true debajo del encabezado [sshd].

/etc/fail2ban/jail.local
#
# JAILS
#

#
# Servidores SSH
#

[sshd]

# Para utilizar modos sshd más agresivos, establece el parámetro de filtro "mode" en jail.local:
# normal (predeterminado), ddos, extra o agresivo (combina todos).
# Consulta "tests/files/logs/sshd" o "filter.d/sshd.conf" para obtener ejemplos de uso y detalles.
#mode   = normal
enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

Algunas otras configuraciones que se establecen aquí son el filtro que se utilizará para decidir si una línea en un registro indica una autenticación fallida y el logpath que indica a fail2ban dónde se encuentran los registros para ese servicio en particular.

El valor del filtro es en realidad una referencia a un archivo ubicado en el directorio /etc/fail2ban/filter.d, con su extensión .conf eliminada. Estos archivos contienen expresiones regulares (una abreviatura común para el análisis de texto) que determinan si una línea en el registro es un intento de autenticación fallido. No cubriremos estos archivos en profundidad en esta guía, porque son bastante complejos y los ajustes predefinidos coinciden bien con las líneas apropiadas.

Sin embargo, puede ver qué tipo de filtros están disponibles mirando en ese directorio:

  1. ls /etc/fail2ban/filter.d

Si ve un archivo que parece relacionado con un servicio que está utilizando, debería abrirlo con un editor de texto. La mayoría de los archivos están bastante comentados y debería poder al menos saber qué tipo de condición fue diseñada para proteger el script. La mayoría de estos filtros tienen secciones apropiadas (desactivadas) en el archivo jail.conf que podemos habilitar en el archivo jail.local si lo deseamos.

Por ejemplo, imagine que está sirviendo un sitio web usando Nginx y se da cuenta de que una parte protegida por contraseña de su sitio está siendo bombardeada con intentos de inicio de sesión. Puede indicar a fail2ban que utilice el archivo nginx-http-auth.conf para verificar esta condición dentro del archivo /var/log/nginx/error.log.

Esto ya está configurado en una sección llamada [nginx-http-auth] en tu archivo /etc/fail2ban/jail.conf. Solo necesitarías agregar el parámetro enabled:

/etc/fail2ban/jail.local
. . .
[nginx-http-auth]

enabled = true
. . .

Una vez que hayas terminado de editar, guarda y cierra el archivo. Si estás utilizando vi, utiliza :x para guardar y salir. En este punto, puedes habilitar tu servicio Fail2ban para que se ejecute automáticamente de ahora en adelante. Primero, ejecuta systemctl enable:

  1. sudo systemctl enable fail2ban

Luego, inícialo manualmente por primera vez con systemctl start:

  1. sudo systemctl start fail2ban

Puedes verificar que esté en funcionamiento con systemctl status:

  1. sudo systemctl status fail2ban
Output
● fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: disabled Active: active (running) since Mon 2022-06-27 19:25:15 UTC; 3s ago Docs: man:fail2ban(1) Main PID: 39396 (fail2ban-server) Tasks: 5 (limit: 1119) Memory: 12.9M CPU: 278ms CGroup: /system.slice/fail2ban.service └─39396 /usr/bin/python3.6 -s /usr/bin/fail2ban-server -xf start Jun 27 19:25:15 fail2ban22 systemd[1]: Started Fail2Ban Service. Jun 27 19:25:15 fail2ban22 fail2ban-server[39396]: Server ready

En el siguiente paso, demostrarás Fail2ban en acción.

Paso 3 — Probando las Políticas de Bloqueo (Opcional)

Desde otro servidor, uno que no necesitará iniciar sesión en tu servidor Fail2ban en el futuro, puedes probar las reglas haciendo que ese segundo servidor sea bloqueado. Después de iniciar sesión en tu segundo servidor, intenta conectarte por SSH al servidor Fail2ban. Puedes intentar conectarte usando un nombre inexistente:

  1. ssh blah@your_server

Introduce caracteres aleatorios en el prompt de contraseña. Repite esto varias veces. En algún momento, el error que estás recibiendo debería cambiar de Permission denied a Connection refused. Esto indica que tu segundo servidor ha sido bloqueado del servidor Fail2ban.

En tu servidor Fail2ban, puedes ver la nueva regla revisando la salida de fail2ban-client. fail2ban-client es un comando adicional proporcionado por Fail2ban para verificar su configuración en ejecución.

  1. sudo fail2ban-client status
Output
Status |- Number of jail: 1 `- Jail list: sshd

Si ejecutas fail2ban-client status sshd, puedes ver la lista de IPs que han sido prohibidas en SSH:

  1. sudo fail2ban-client status sshd
Output
Status for the jail: sshd |- Filter | |- Currently failed: 2 | |- Total failed: 7 | `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd `- Actions |- Currently banned: 1 |- Total banned: 1 `- Banned IP list: 134.209.165.184

El contenido de la lista de IPs prohibidas debe reflejar la dirección IP de tu segundo servidor.

Conclusión

Ahora deberías poder configurar algunas políticas de prohibición para tus servicios. Fail2ban es una forma útil de proteger cualquier tipo de servicio que utilice autenticación. Si quieres aprender más sobre cómo funciona fail2ban, puedes consultar nuestro tutorial sobre cómo funcionan las reglas y archivos de fail2ban.

Para obtener información sobre cómo utilizar fail2ban para proteger otros servicios, puedes leer sobre Cómo proteger un servidor Nginx con Fail2Ban y Cómo proteger un servidor Apache con Fail2Ban.

Source:
https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-rocky-linux-8