Cómo proteger SSH con Fail2Ban en Ubuntu 20.04

Introducción

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

Cualquier servicio expuesto a la red es un objetivo potencial de esta manera. Si revisa los registros de su servicio SSH en cualquier servidor con mucho tráfico, a menudo verá intentos de inicio de sesión repetidos y sistemáticos que representan ataques de fuerza bruta tanto de usuarios como de bots. Aunque puede realizar algunas optimizaciones en su servicio SSH para reducir la probabilidad de que estos ataques tengan éxito casi a 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 modo que sea imposible conectar directamente al puerto SSH predeterminado 22 desde Internet sin abstracción de software adicional o pasarelas. Estas soluciones VPN son ampliamente confiables, pero agregarán complejidad y pueden romper algunas automatizaciones u otros pequeños ganchos de software.

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 mediante la creación de 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 fortalezca contra estos intentos de acceso sin intervención de su parte.

En esta guía, verá cómo instalar y usar Fail2ban en un servidor Ubuntu 20.04.

Prerrequisitos

Para completar esta guía, necesitará:

  • Un servidor Ubuntu 20.04 y un usuario no root con privilegios sudo. Puede aprender más sobre cómo configurar un usuario con estos privilegios en nuestra guía Configuración Inicial del Servidor con Ubuntu 20.04.

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

Paso 1: Instalación de Fail2ban

Fail2ban está disponible en los repositorios de software de Ubuntu. Comienza ejecutando los siguientes comandos como un usuario no root para actualizar tus listados de paquetes e instalar Fail2ban:

  1. sudo apt update
  2. sudo apt install fail2ban

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

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

Puedes 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 predeterminados 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: completamente 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 CÁRCELES: # # 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 cárceles y habilitar la # cárcel ssh-iptables, lo siguiente (sin comentarios) aparecería en el archivo .local. # Vea el man 5 jail.conf para más detalles. # # [DEFAULT]

Como verás, las primeras líneas de este archivo están comentadas – comienzan con caracteres # que indican que deben leerse como documentación en lugar de como configuraciones. Como también verás, estos comentarios te indican que no modifiques este archivo directamente. En su lugar, 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 se actualizará periódicamente a medida que se actualice Fail2ban en sí, y se utilizará como fuente de configuraciones predeterminadas para las cuales no has 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 hacer cambios de configuración. Abre el archivo en nano o tu editor de texto favorito:

  1. sudo nano jail.local

Mientras estás desplazándote por el archivo, este tutorial revisará algunas opciones que es posible que desees actualizar. Las configuraciones ubicadas 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 las predeterminadas.

/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 autenticarse correctamente. Esto se mide en segundos. Por defecto, está configurado en 10 minutos.

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

Los siguientes dos 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 debería ser prohibido.

La variable maxretry establece el número de intentos que tiene un cliente 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 necesita recibir alertas por correo electrónico cuando Fail2ban tome acción, debería evaluar los ajustes de destemail, sendername y mta. El parámetro destemail establece la dirección de correo electrónico que debería recibir 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 puede querer 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 quiere 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 su firewall para rechazar el tráfico del host infractor hasta que el tiempo de prohibición transcurra.

Existen otros scripts de action_ proporcionados de forma predeterminada que puede reemplazar $(action_) con arriba:

/etc/fail2ban/jail.local
…
# Prohibir y enviar un correo electrónico con un informe whois al correo electrónico de destino.
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
# al correo electrónico de destino.
action_mwl = %(action_)s
             %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]

# Consulte la nota IMPORTANTE en action.d/xarf-login-attack para saber cuándo usar 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
# al correo electrónico de destino.
action_xarf = %(action_)s
             xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]

# Prohibir IP en CloudFlare y enviar un correo electrónico con un informe whois y líneas de registro relevantes
# al correo electrónico de destino.
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 toma acción y envía un correo electrónico, action_mwl toma 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 su cuenta para prohibir al infractor también.

Configuraciones Individuales de Cárcel

A continuación se muestra 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 debe habilitarse individualmente agregando una línea enabled = true bajo el encabezado, con sus otras configuraciones.

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

Por defecto, el servicio SSH está habilitado y todos los demás están desactivados.
.
Algunos otros ajustes 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 (un formato 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, puedes ver qué tipo de filtros están disponibles mirando ese directorio:

  1. ls /etc/fail2ban/filter.d

Si ves un archivo que parece relacionado con un servicio que estás utilizando, deberías abrirlo con un editor de texto. La mayoría de los archivos están bastante bien comentados y deberías poder al menos saber qué tipo de condición estaba diseñado 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 así lo deseamos.

Por ejemplo, imagina que estás sirviendo un sitio web usando Nginx y te das cuenta de que una parte protegida con contraseña de tu sitio está siendo atacada con intentos de inicio de sesión. Puedes indicarle 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
. . .

Cuando hayas terminado de editar, guarda y cierra el archivo. En este punto, puedes habilitar tu servicio Fail2ban para que se ejecute automáticamente a partir de ahora. 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 ejecución con systemctl status:

  1. sudo systemctl status fail2ban
Output
● fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enab> Active: active (running) since Tue 2022-06-28 19:29: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 /usr/bin/fail2ban-server -xf start Jun 28 19:29:15 fail2ban20 systemd[1]: Started Fail2Ban Service. Jun 28 19:29:15 fail2ban20 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 para 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

Ingrese caracteres aleatorios en el cuadro de contraseña. Repita esto varias veces. En algún momento, el error que está recibiendo debería cambiar de Permiso denegado a Conexión rechazada. Esto indica que su segundo servidor ha sido prohibido por el servidor Fail2ban.

En su servidor Fail2ban, puede ver la nueva regla al verificar su salida de iptables. iptables es un comando para interactuar con reglas de puertos y firewall de bajo nivel en su servidor. Si siguió la guía de configuración inicial del servidor de DigitalOcean, estará utilizando ufw para gestionar las reglas del firewall a un nivel más alto. Ejecutar iptables -S le mostrará todas las reglas del firewall que ufw ya ha creado:

  1. sudo iptables -S
Output
-P INPUT DROP -P FORWARD DROP -P OUTPUT ACCEPT -N f2b-sshd -N ufw-after-forward -N ufw-after-input -N ufw-after-logging-forward -N ufw-after-logging-input -N ufw-after-logging-output -N ufw-after-output -N ufw-before-forward -N ufw-before-input -N ufw-before-logging-forward -N ufw-before-logging-input -N ufw-before-logging-output …

Si pasa la salida de iptables -S a grep para buscar dentro de esas reglas la cadena f2b, puede ver las reglas que han sido añadidas por fail2ban:

  1. sudo iptables -S | grep f2b
Output
-N f2b-sshd -A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd -A f2b-sshd -s 134.209.165.184/32 -j REJECT --reject-with icmp-port-unreachable -A f2b-sshd -j RETURN

La línea que contiene REJECT --reject-with icmp-port-unreachable habrá sido agregada por Fail2ban y debería reflejar la dirección IP de su 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 usar fail2ban para proteger otros servicios, puedes leer sobre Cómo proteger un servidor Nginx con Fail2Ban en Ubuntu 14.04 y Cómo proteger un servidor Apache con Fail2Ban en Ubuntu 14.04.

Source:
https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-ubuntu-20-04