Bloqueando bots y solicitudes no deseadas en Tomcat con Fail2Ban

Introducción

En servidores web, es común recibir miles de solicitudes de distintos orígenes, muchas veces provenientes de bots o actores malintencionados que pueden sobrecargar el sistema o, peor aún, intentar explotar vulnerabilidades. Recientemente, noté un comportamiento inusual en los logs de acceso de mi aplicación web desplegada en un servidor Tomcat. A continuación, detallo cómo configuré Fail2Ban para bloquear direcciones IP que hacen solicitudes fallidas de manera recurrente.

El problema

Cada día, Tomcat genera un archivo de log de acceso en el directorio /opt/pendientes-webapp/logs/tomcat/logs con un formato que incluye la fecha, como access_log.2024-10-08.log. Revisando los logs, me di cuenta de que algunas direcciones IP hacían múltiples solicitudes por segundo, generando un montón de respuestas HTTP con código de error 400 (Bad Request).

Aquí un extracto de mi log de ejemplo:

Bash
139.144.52.241 - - [08/Oct/2024:01:30:05 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:05 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:05 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:05 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:05 +0000] "GET / HTTP/1.1" 200 24352
139.144.52.241 - - [08/Oct/2024:01:30:05 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:05 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:06 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:06 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:12 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:12 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:12 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:12 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:12 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:12 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:12 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:12 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:12 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:13 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:13 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:13 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:14 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:15 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:22 +0000] "-" 400 -
139.144.52.241 - - [08/Oct/2024:01:30:23 +0000] "-" 400 -
198.235.24.127 - - [08/Oct/2024:01:49:58 +0000] "GET / HTTP/1.1" 200 24352
87.120.115.119 - - [08/Oct/2024:01:51:05 +0000] "GET /.env HTTP/1.1" 302 -
2602:80d:1000:0:0:0:0:2b - - [08/Oct/2024:02:36:11 +0000] "GET / HTTP/1.1" 200 24352
2602:80d:1000:0:0:0:0:2b - - [08/Oct/2024:02:36:12 +0000] "GET /images/logotipo-128.png HTTP/1.1" 200 30372
2602:80d:1000:0:0:0:0:2b - - [08/Oct/2024:02:36:13 +0000] "GET /favicon.ico HTTP/1.1" 302 -
2602:80d:1000:0:0:0:0:2b - - [08/Oct/2024:02:36:14 +0000] "GET /formLogin HTTP/1.1" 200 2568
2602:80d:1000:0:0:0:0:2b - - [08/Oct/2024:02:36:18 +0000] "-" 400 -
2602:80d:1000:0:0:0:0:2b - - [08/Oct/2024:02:36:20 +0000] "-" 400 -
2602:80d:1000:0:0:0:0:2b - - [08/Oct/2024:02:36:21 +0000] "-" 400 -

Como se observa, la IP 139.144.52.241 realizó más de 20 solicitudes en menos de 15 segundos, muchas de ellas resultando en un código 400. Este comportamiento es típico de bots maliciosos o mal configurados que intentan acceder a recursos sin éxito repetidamente.

Instalación de Fail2Ban

Para mitigar este tipo de ataques o abusos, utilizaremos Fail2Ban. Sigue estos pasos para instalar y configurar Fail2Ban en tu servidor.

Instalación en distribuciones basadas en Debian/Ubuntu

Primero, actualiza los repositorios de tu servidor y luego instala Fail2Ban:

Bash
sudo apt update
sudo apt install fail2ban

Una vez instalado, Fail2Ban debería iniciarse automáticamente. Si no es así, puedes iniciarlo y habilitarlo con los siguientes comandos:

Bash
sudo systemctl start fail2ban
sudo systemctl enable fail2ban

Creación y configuración de archivos de Fail2Ban

Una vez instalado Fail2Ban, procederemos a crear los archivos de configuración necesarios para que detecte las peticiones con errores y bloquee las direcciones IP maliciosas.

Configuración de jail.local

El archivo principal de configuración para Fail2Ban se encuentra en /etc/fail2ban/jail.conf. Sin embargo, es una buena práctica no modificar directamente este archivo, sino crear un archivo personalizado llamado jail.local donde agregamos nuestras configuraciones. Puedes crearlo o editarlo de la siguiente manera:

Bash
sudo nano /etc/fail2ban/jail.local

Luego, añade la siguiente configuración para monitorear las solicitudes que generan errores 400 en los logs de Tomcat:

Bash
[tomcat-400]
enabled  = true
port     = http,https
filter   = tomcat-400
logpath  = /opt/pendientes-webapp/logs/tomcat/logs/access_log.*.log
# Si una IP genera 3 errores HTTP 400 en menos de 15 segundos, sera bloqueada inmediatamente.
maxretry = 3
# Bloquear la IP durante 1 dia (86400 segundos)
bantime  = 86400
# Verificar las solicitudes en un intervalo de 15 segundos
findtime = 15

Creación del filtro tomcat-400

Fail2Ban también necesita un filtro que le permita identificar cuándo una solicitud HTTP devuelve un error 400. Para ello, creamos un archivo de filtro específico en la ruta /etc/fail2ban/filter.d/ con el nombre tomcat-400.conf:

Bash
sudo nano /etc/fail2ban/filter.d/tomcat-400.conf

Luego, añade la siguiente expresión regular para que Fail2Ban detecte las líneas relevantes en los logs de Tomcat:

Bash
[Definition]
# Expresion regular para identificar lineas en los logs que terminan en "- 400 -"
failregex = ^<HOST> - - \[.*\] "-" 400 -

# Ignorar cualquier otra linea que no sea relevante
ignoreregex =

Explicación de cada parámetro:

  • enabled = true: Activa esta jail para que Fail2Ban la monitoree.
  • port = http, https: Monitorea los puertos de HTTP y HTTPS.
  • filter = tomcat-400: Indica qué filtro utilizar para analizar el log. Este filtro debe ser configurado en un archivo separado, como hemos creado en el paso anterior.
  • logpath = /opt/pendientes-webapp/logs/tomcat/logs/access_log.*.log: Ruta de los archivos de log de Tomcat que Fail2Ban analizará. Utilizamos un patrón para que detecte todos los logs generados cada día.
  • maxretry = 3: El número máximo de errores 400 permitidos antes de bloquear la IP.
  • bantime = 86400: La duración del bloqueo de la IP, en segundos. Aquí configuramos un bloqueo de 24 horas.
  • findtime = 15: El intervalo de tiempo en el cual deben ocurrir las maxretry para que se dispare el bloqueo (15 segundos en este caso).
Reiniciar Fail2Ban y verificar

Después de realizar estos ajustes, es necesario reiniciar Fail2Ban para que los cambios surtan efecto:

Bash
sudo systemctl restart fail2ban

Para verificar que la “jail” está funcionando correctamente, puedes ejecutar el siguiente comando:

Bash
sudo fail2ban-client status tomcat-400

Esto mostrará el estado de la jail y las IPs que han sido bloqueadas.

NOTA: en el directorio /var/lib/fail2ban se genera una base de datos SQLite (fail2ban.sqlite3) con datos de las direcciones IP que han sido bloqueadas.

Monitorear Fail2Ban

También puedes monitorear el archivo de log de Fail2Ban en tiempo real para asegurarte de que está detectando correctamente los ataques y bloqueando las IPs infractoras:

Bash
sudo tail -f /var/log/fail2ban.log

¿Cómo desbloquear una IP en Fail2ban?

Si una IP ha sido bloqueada por error o necesitas desbloquear una dirección IP específica en Fail2ban, puedes hacerlo fácilmente desde la línea de comandos. Aquí te explico cómo:

1. Verificar las IPs bloqueadas

Para empezar, verifica si la IP que deseas desbloquear está bloqueada dentro de Fail2ban. Puedes hacerlo ejecutando el siguiente comando en el servidor:

Bash
sudo fail2ban-client status tomcat-400

Este comando mostrará el estado de la jail sshd, donde puedes ver las IPs actualmente bloqueadas. Si la IP está bloqueada en una jail diferente, reemplaza tomcat-400 con el nombre correcto de la jail.

2.Desbloquear una IP

Para desbloquear una IP, usa el siguiente comando. Solo debes cambiar el nombre de la jail y la IP correspondiente:

Bash
sudo fail2ban-client set tomcat-400 unbanip 200.68.138.17

En este ejemplo, tomcat-400 es la jail donde fue bloqueada la IP y 200.68.138.17 es la IP a desbloquear.

3.Verificar si la IP fue desbloqueada

Después de desbanear la IP, puedes verificar nuevamente el estado de la jail para confirmar que la IP ha sido eliminada de la lista de bloqueos:

Bash
sudo fail2ban-client status tomcat-400

Ten en cuenta que si la IP sigue violando las reglas de seguridad, Fail2ban podría volver a bloquearla. Asegúrate de revisar los logs y ajustar las configuraciones según sea necesario.

Conclusión

Implementar Fail2Ban para bloquear IPs maliciosas o mal configuradas es una excelente medida para mantener el rendimiento y la seguridad de tu servidor. En este caso, bloqueamos IPs que hacen muchas solicitudes fallidas con código 400 en un corto periodo de tiempo, protegiendo así nuestro servidor de bots abusivos.