Instalación y uso de Fail2ban en Debian 12

Fail2ban supervisa los archivos de registro en busca de fallos en el inicio de sesión y prohíbe temporalmente el acceso al host a la dirección IP de origen propensa al fallo. Es una defensa contra los ataques de fuerza bruta para adivinar contraseñas. Es muy útil tener fail2ban en los servidores expuestos a Internet.

La versión de fail2ban en Debian 12 es la 1.0.2.

root@posti:~# fail2ban-client version
1.0.2

Para ver si fail2ban se está ejecutando actualmente, envía al servidor el comando ping con fail2ban-client. El servidor fail2ban responde «pong» si se está ejecutando.

root@posti:/etc/fail2ban# fail2ban-client ping
Server replied: pong
root@posti:/etc/fail2ban#

Cómo funciona

Fail2ban recopila los archivos de filtro, acción y monitorizados en una jaula. Varias jaulas vienen con la distribución. Es necesario habilitarlas para que empiecen a funcionar. filter especifica cómo detectar los fallos de autenticación. action define cómo se produce el baneo y el desbaneo.

Los intentos de intrusión activan el bloqueo si durante el tiempo de búsqueda se detectan al menos un máximo de intentos fallidos de inicio de sesión desde el mismo número IP. Entonces la IP es baneada durante bantime segundos. Después de que el baneo haya estado en vigor durante bantime segundos, se levanta el baneo y la IP puede acceder de nuevo al host. Fail2ban puede gestionar tanto IPv4 como IPv6.

Puedes obtener más información en los archivos del directorio /usr/share/doc/fail2ban/.

Configuración de Fail2ban

En los sistemas Debian GNU/Linux se instala fail2ban por defecto con la jaula sshd habilitada con una configuración razonable. Esto se hace en el archivo /etc/fail2ban/jail.d/defaults-debian.conf. Esa es la única jaula que funciona por defecto. Otras jaulas deben ser habilitadas por el administrador del sistema.

Por tanto, si sólo quieres que se controlen los inicios de sesión ssh y se prohíba a los intrusos que se comporten mal, no es necesaria ninguna configuración adicional.

Por desgracia, en Debian 12, fail2ban puede no funcionar con la configuración por defecto. Debian 12 marcó el paquete rsyslog como opcional, lo que significa que puede no estar instalado, por lo que los registros se recogen sólo en journald [wiki.debian.org/Rsyslog].

En los sistemas ISPConfig fail2ban funciona, ya que el autoinstalador de ISPConfig instala rsyslog y el tutorial del servidor ISPConfig Perfect indica que se instale rsyslog.

Con rsyslog, los archivos de registro aparecen en el directorio /var/log/, por lo que la configuración por defecto de fail2ban encuentra los archivos de registro. Si rsyslog no está instalado, la configuración de fail2ban debe modificarse para que lea los registros del diario systemd. Añade a la sección por defecto de jail. local backend = systemd, así

[DEFAULT]
backend = systemd

Habilitar una jaula

La documentación recomienda poner todas las modificaciones propias en los archivos .local. Esto evita problemas cuando los archivos proporcionados por la distribución son actualizados o modificados por el mantenedor [Lee el archivo /usr/share/doc/fail2ban/README.Debian.gz].

Por ejemplo, habilitar la jaula pure-ftpd se hace añadiendo al archivo /etc/fail2ban/jail.local (crea el archivo si no existe ya) las líneas

[pure-ftpd]
enabled = true

El nombre de la jaula entre corchetes inicia la sección para la configuración de esa jaula.

Cuando termines con las modificaciones, fuerza la relectura de los archivos de configuración con el comando

systemctl reload fail2ban

Ahora la jaula debería estar funcionando, lo que se puede comprobar con fail2ban-client:

root@posti:/etc/fail2ban# fail2ban-client status pure-ftpd
Status for the jail: pure-ftpd
|- Filter
|  |- Currently failed:	0
|  |- Total failed:	106
|  `- File list:	/var/log/syslog
`- Actions
   |- Currently banned:	0
   |- Total banned:	4
   `- Banned IP list:	
root@posti:/etc/fail2ban#

Como jail.local sólo tiene la configuración «enabled» para esa jaula, todas las demás configuraciones son las predeterminadas de la distribución. Normalmente tienen buenos valores, por lo que no es necesario realizar más configuraciones. Si es necesario, la sección jail.local para esa jaula puede contener ajustes que anulen lo establecido en los archivos .conf.

Este ejemplo cambia findtime, maxretry y bantime para la jaula pure-ftpd:

[pure-ftpd]
enabled = true
findtime = 2h
maxretry = 6
bantime = 1d

Fail2ban-client muestra los tiempos en segundos, pero los tiempos se pueden introducir en los archivos de configuración en un formato más sencillo, por ejemplo 10h en lugar de 36000 segundos. man jail.conf en el capítulo «FORMATO DE ABREVIATURA DE TIEMPO» explica los formatos de entrada de tiempo fáciles de usar.

fail2ban-client tiene una opción para convertir el formato de tiempo fácil de usar a segundos.

# fail2ban-client --str2sec 1d3h7m
97620

Sigue los registros

Para determinar qué jaulas deben activarse, sigue los registros creados por los servicios que se ejecutan en el host. Es útil una herramienta que cree resúmenes de los registros, como logwatch o pflogsumm. Leer registros sin procesar lleva mucho tiempo y es tedioso.

Comprueba si hay una jaula disponible para un servicio que se ejecuta en el host, quizás leyendo jail.conf.

Cuando los logs muestren algo interesante o preocupante, es el momento de examinarlos. Por ejemplo, pflogsumm envió un resumen de correo electrónico con líneas como ésta:

136   unknown[91.224.92.40]: SASL LOGIN authentication failed: UGFzc3...
136   hostname srv-91-224-92-40.serveroffer.net does not resolve to a...
123   unknown[193.32.162.23]: SASL LOGIN authentication failed: UGFzc...
123   hostname mail.whatami.co does not resolve to address 193.32.162.23

Que muestra que la IP 91.224.92.40 falló 136 veces al registrar el correo electrónico, y otro caso similar. Fail2ban debería haber evitado tantos intentos. Para ver por qué no ocurrió, examina el registro de fail2ban.

root@posti:/etc/apt/apt.conf.d# grep 91.224.92.40 /var/log/fail2ban.log | head
2024-02-18 00:01:38,718 fail2ban.filter         [996]: INFO    [postfix-sasl] Found 91.224.92.40 - 2024-02-18 00:01:38
2024-02-18 00:11:50,261 fail2ban.filter         [996]: INFO    [postfix-sasl] Found 91.224.92.40 - 2024-02-18 00:11:50
2024-02-18 00:21:54,337 fail2ban.filter         [996]: INFO    [postfix-sasl] Found 91.224.92.40 - 2024-02-18 00:21:54
2024-02-18 00:32:14,232 fail2ban.filter         [996]: INFO    [postfix-sasl] Found 91.224.92.40 - 2024-02-18 00:32:14
2024-02-18 00:42:37,921 fail2ban.filter         [996]: INFO    [postfix-sasl] Found 91.224.92.40 - 2024-02-18 00:42:37
2024-02-18 00:53:06,796 fail2ban.filter         [996]: INFO    [postfix-sasl] Found 91.224.92.40 - 2024-02-18 00:53:06
2024-02-18 01:03:35,293 fail2ban.filter         [996]: INFO    [postfix-sasl] Found 91.224.92.40 - 2024-02-18 01:03:35
2024-02-18 01:14:03,765 fail2ban.filter         [996]: INFO    [postfix-sasl] Found 91.224.92.40 - 2024-02-18 01:14:03
2024-02-18 01:24:24,628 fail2ban.filter         [996]: INFO    [postfix-sasl] Found 91.224.92.40 - 2024-02-18 01:24:24
2024-02-18 01:34:43,876 fail2ban.filter         [996]: INFO    [postfix-sasl] Found 91.224.92.40 - 2024-02-18 01:34:43
root@posti:/etc/apt/apt.conf.d#

Esa IP intenta conectarse a intervalos de unos 10 minutos, y fail2ban jail postfix-sasl sí lo detecta.

Es una buena idea averiguar si esa IP puede pertenecer a un usuario legítimo del host, que simplemente tiene una contraseña antigua en el smartphone o algún otro dispositivo que intenta conectarse a intervalos regulares. Yo utilizo geoiplookup, que muestra de qué país es la IP. Mis usuarios son de mi país, así que los usuarios extranjeros suelen ser malos actores. geoiplookup viene de los paquetes de Debian geoip-database y geoip-bin.

$ geoiplookup 91.224.92.40
GeoIP Country Edition: LT, Lithuania

Para averiguar por qué no se ha baneado la IP, examina findtime de esa cárcel:

root@posti:/etc/apt/apt.conf.d# fail2ban-client get postfix-sasl findtime
600
root@posti:/etc/apt/apt.conf.d#

Recientemente he visto estos ataques lentos, el autor sabe que el tiempo de búsqueda es de 10 minutos, por lo que intenta evitar que le baneen intentando iniciar sesión a intervalos más largos. En este caso ha funcionado. Para que los inicios de sesión fallidos provoquen bloqueos, aumenta el tiempo de búsqueda de la jaula, por ejemplo a 10 horas. Añádelo al archivo jail.local en la sección [postfix-sasl]:

findtime = 10h

Después de recargar fail2ban con systemctl, la jaula tendrá un tiempo de búsqueda más largo:

root@posti:/etc/fail2ban# fail2ban-client get postfix-sasl findtime
36000
root@posti:/etc/fail2ban#

Otra forma en que los intrusos intentan entrar es siendo persistentes. Aunque el intruso esté baneado, espera a que termine el ban y sigue adivinando la contraseña. El tiempo de baneo podría ser más largo, pero eso causa problemas a los usuarios legítimos, que pueden teclear mal la contraseña y entonces no pueden acceder a su cuenta hasta que termine el tiempo de baneo. Existe una cárcel para reincidentes llamada recidive. Funciona buscando baneos repetidos para una IP en el log fail2ban, y luego baneando durante un tiempo prolongado, por ejemplo una semana.

El siguiente listado procede del informe de logwatch:

--------------------- pam_unix Begin ------------------------ 
 sshd:
    Authentication Failures:
       unknown (212.70.149.150): 59 Time(s)

La búsqueda de esa IP en el archivo de registro muestra:

2024-02-21 03:42:39,121 fail2ban.filter         [895]: INFO    [sshd] Found 212.70.149.150 - 2024-02-21 03:42:38
2024-02-21 03:42:39,508 fail2ban.actions        [895]: NOTICE  [sshd] Ban 212.70.149.150
2024-02-21 03:52:38,386 fail2ban.actions        [895]: NOTICE  [sshd] Unban 212.70.149.150
2024-02-21 03:54:33,560 fail2ban.filter         [895]: INFO    [sshd] Found 212.70.149.150 - 2024-02-21 03:54:33
2024-02-21 03:54:35,364 fail2ban.filter         [895]: INFO    [sshd] Found 212.70.149.150 - 2024-02-21 03:54:35
2024-02-21 04:00:37,017 fail2ban.filter         [895]: INFO    [sshd] Found 212.70.149.150 - 2024-02-21 04:00:36
2024-02-21 04:00:39,021 fail2ban.filter         [895]: INFO    [sshd] Found 212.70.149.150 - 2024-02-21 04:00:38
2024-02-21 04:06:43,036 fail2ban.filter         [895]: INFO    [sshd] Found 212.70.149.150 - 2024-02-21 04:06:42
2024-02-21 04:06:45,039 fail2ban.filter         [895]: INFO    [sshd] Found 212.70.149.150 - 2024-02-21 04:06:44
2024-02-21 04:06:45,426 fail2ban.actions        [895]: NOTICE  [sshd] Ban 212.70.149.150
2024-02-21 04:16:44,302 fail2ban.actions        [895]: NOTICE  [sshd] Unban 212.70.149.150
2024-02-21 04:19:04,868 fail2ban.filter         [895]: INFO    [sshd] Found 212.70.149.150 - 2024-02-21 04:19:04

Fail2ban funciona según lo previsto, encontrando los inicios de sesión erróneos y emitiendo un baneo durante 10 minutos. Durante este baneo se impide al infractor el acceso a este host, pero continúa después de que se levante el baneo. Este parece ser el caso de un intento serio de intrusión. El remedio es habilitar la cárcel recidive con maxretry bajo y ban largo.

A mí me gusta utilizar un baneo inicial corto, digamos de 10 minutos. Si un usuario real es baneado, sólo tiene que esperar ese tiempo, con la esperanza de utilizarlo para encontrar la contraseña correcta e intentarlo de nuevo. A los que vuelven a ser baneados el mismo día, se les banea durante una semana. Los valores por defecto de recidive jail se encuentran en el archivo jail.conf, hay bantime de 1 semana y findtime de 1 día, me parecen bien. Pero he puesto maxretry a 2, los infractores son baneados más rápido. He añadido al archivo jail.local:

[recidive]
enabled = true
maxretry = 2

En mi opinión, los baneos de más de 1 semana no merecen la pena. Con el tiempo, la antigua dirección IP es baneada o incluida en listas negras por todas partes, por lo que el infractor obtiene una nueva IP. La antigua IP se entrega a algún nuevo usuario de Internet inocente, que no debe ser castigado por las cosas malas de las que es culpable el anterior propietario de esa IP.

Solución de problemas

Tras arrancar el SO o reiniciar fail2ban se restablece el estado, por lo que los baneos continúan hasta que transcurre el tiempo de baneo. Por tanto, las pruebas y la resolución de problemas pueden implicar reinicios.

Para probar la configuración, hay una opción de prueba:

fail2ban-server --test

Para saber si una IP está baneada, las versiones recientes de fail2ban pueden hacer

# fail2ban-client banned 43.131.9.186
[['recidive']]

El comando muestra la lista de cárceles en las que una IP determinada está baneada actualmente.

Las versiones antiguas de fail2ban no tienen ese comando. Se puede probar cada cárcel una por una así:

# fail2ban-client status recidive | tr " " "\n" | grep 43.163.219.232
43.163.219.232

Si la salida muestra la IP, entonces estaba en la lista de IP baneadas. El comando tr está ahí para dividir la lista de números IP prohibidos (es una línea larga) en una IP por línea.

Para ver lo que ha estado ocurriendo con una IP determinada, búscala en fail2ban.log:

root@posti:/etc/mysql# grep 43.131.9.186 /var/log/fail2ban.log | cut --characters=-80
2024-03-06 09:00:40,295 fail2ban.filter  [3574846]: INFO    [sshd] Found
2024-03-06 09:02:53,954 fail2ban.filter  [3574846]: INFO    [sshd] Found
2024-03-06 09:02:55,958 fail2ban.filter  [3574846]: INFO    [sshd] Found
2024-03-06 09:04:34,193 fail2ban.filter  [3574846]: INFO    [sshd] Found
2024-03-06 09:04:36,195 fail2ban.filter  [3574846]: INFO    [sshd] Found
2024-03-06 09:04:36,388 fail2ban.actions [3574846]: NOTICE  [sshd] Ban 43
2024-03-06 09:04:36,626 fail2ban.filter  [3574846]: INFO    [recidive] Fo
2024-03-06 09:14:35,180 fail2ban.actions [3574846]: NOTICE  [sshd] Unban
2024-03-06 09:15:10,073 fail2ban.filter  [3574846]: INFO    [sshd] Found
2024-03-06 09:16:55,919 fail2ban.filter  [3574846]: INFO    [sshd] Found
2024-03-06 09:16:58,522 fail2ban.filter  [3574846]: INFO    [sshd] Found
2024-03-06 09:18:44,972 fail2ban.filter  [3574846]: INFO    [sshd] Found
2024-03-06 09:20:30,018 fail2ban.filter  [3574846]: INFO    [sshd] Found
2024-03-06 09:20:30,499 fail2ban.actions [3574846]: NOTICE  [sshd] Ban 43
2024-03-06 09:20:30,620 fail2ban.filter  [3574846]: INFO    [recidive] Fo
2024-03-06 09:20:30,899 fail2ban.actions [3574846]: NOTICE  [recidive] Ba
2024-03-06 09:20:32,021 fail2ban.filter  [3574846]: INFO    [sshd] Found
2024-03-06 09:30:29,289 fail2ban.actions [3574846]: NOTICE  [sshd] Unban

El volcado detallado de la configuración de fail2ban muestra la configuración para su examen:

# fail2ban-client -vvv -d

Lista blanca de direcciones IP propias

Puede que tus propios hosts sean baneados o que quieras asegurarte de que algunos hosts ajenos nunca sean baneados aunque se comporten mal. Esos números IP pueden incluirse en una lista blanca. Por defecto no hay nada en la lista blanca, puedes comprobarlo con:

root@posti:~# fail2ban-client get sshd ignoreip
No IP address/network is ignored
root@posti:~

La configuración de ignoreip podría establecerse en cada sección de las cárceles, pero esta configuración debería afectar a todas las cárceles, así que es mejor establecerla en la sección DEFAULT. Podría ser mejor establecer ignore en la subred interna, para que todos tus propios hosts eviten los baneos. Esto es al principio de jail.local:

[DEFAULT]
ignoreip = 92.237.123.96/27

La sección DEFAULT puede tener otros ajustes que afecten a todas las cárceles. Por ejemplo, podría añadirse allí findtime = 10h.

Prohibir manualmente

Para probar lo que ocurre cuando se banea, configura el ban manualmente. Prueba primero con una cárcel con un tiempo de ban corto, para que puedas volver eventualmente si te baneas por error. Por ejemplo

# fail2ban-client set sshd banip 8.8.4.4</>

Si alguna IP se comporta mal pero no puedes hacer que fail2ban la detecte y emita baneos, estableciendo un baneo manual en una jaula de recidive te libras de esa IP durante una semana.

# fail2ban-client set recidive banip 8.8.4.4

El baneo de una subred funciona utilizando la notación CIDR:

fail2ban-client set recidive banip 5.188.87.0/24

Desbaneo manual

Eliminar un ban es posible, pero ten en cuenta que si el mal comportamiento continúa, la IP volverá a ser baneada. Así que debes averiguar qué está pasando (leyendo los logs, por ejemplo) y solucionar el mal comportamiento.

# fail2ban-client set recidive unbanip 8.8.4.4

La IP puede estar baneada en varias cárceles. Para desbanear una IP en todas las cárceles, utiliza

# fail2ban-client unban 8.8.4.4

Sin embargo, rara vez necesito hacerlo. Tengo 10 minutos de baneo, excepto la cárcel recidive que tiene 1 semana, así que sólo desbaneo IP de la cárcel recidive, las otras cárceles ya han caducado. Si no utilizas la cárcel de recidive, la IP puede estar baneada en varias cárceles al mismo tiempo, por lo que esto es útil.

Para desbanear todas las direcciones IP de todas las jaulas haz lo siguiente

fail2ban-client unban --all

Conclusión

Fail2ban dificulta la adivinación de contraseñas, pero no impide completamente que los crackers intenten acceder al host. Para SSH, forzar el uso de claves SSH ofrece más protección al impedir el inicio de sesión con una contraseña. Para otros servicios, la autenticación multifactor impide el inicio de sesión si sólo se conoce la contraseña.

También te podría gustar...