Fail2Ban: instalación, monitoreo con diagnóstico y desbloqueo de IPs

Written by

in

Fail2Ban es una herramienta que monitorea logs del sistema (como los intentos de login de SSH) y bloquea automáticamente, vía iptables o nftables, las IPs que superan un número de intentos fallidos configurado. Cada servicio protegido (SSH, Nginx, Postfix, etc.) tiene su propio jail — una configuración independiente con sus propias reglas de detección y tiempo de bloqueo.

Instalación

Fail2Ban está disponible en los repositorios oficiales de las principales distribuciones.

Debian / Ubuntu:

sudo apt update
sudo apt install fail2ban
sudo systemctl enable --now fail2ban

Red Hat / CentOS / Rocky / AlmaLinux:

sudo dnf install epel-release
sudo dnf install fail2ban
sudo systemctl enable --now fail2ban

Por defecto, Fail2Ban trae solo el jail de SSH activo (o ninguno, según la distribución). La configuración recomendada es nunca editar /etc/fail2ban/jail.conf directamente, ya que se sobrescribe con las actualizaciones — en su lugar, se crea /etc/fail2ban/jail.local con las secciones que se quieran personalizar o activar:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Jails más comunes

Un jail se activa agregando o editando su sección en jail.local con enabled = true. Estos son los más usados en un servidor típico:

  • sshd — protege el servicio SSH contra ataques de fuerza bruta en intentos de login. Es el jail más usado y suele venir activo por defecto.
  • nginx-http-auth — bloquea IPs que fallan repetidamente la autenticación básica HTTP en Nginx.
  • nginx-limit-req — banea IPs que exceden los límites de tasa (limit_req) configurados en Nginx, útil contra scraping o abuso de API.
  • postfix — protege el servidor de correo contra intentos de relay no autorizado o fuerza bruta en autenticación SMTP.
  • apache-auth — equivalente a nginx-http-auth pero para servidores Apache.
  • recidive — un jail «de segundo nivel»: vigila el propio log de Fail2Ban y aplica bloqueos más largos a IPs que son baneadas repetidamente por otros jails (reincidentes).

Ejemplo de activación del jail sshd con parámetros personalizados en jail.local:

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 5
findtime = 600
bantime = 3600

Donde maxretry es el número de intentos fallidos permitidos, findtime la ventana de tiempo (en segundos) en la que se cuentan esos intentos, y bantime cuánto dura el bloqueo. Tras cualquier cambio en jail.local, se debe reiniciar el servicio:

sudo systemctl restart fail2ban

Administración: ver lo baneado

Para consultar el estado general y por jail:

# Listar todos los jails activos
sudo fail2ban-client status

# Ver detalle de un jail específico (intentos totales, IPs baneadas)
sudo fail2ban-client status sshd

La salida de status sshd muestra, entre otros datos, Total failed (intentos fallidos acumulados) y Banned IP list (las IPs actualmente bloqueadas). Para ver el detalle de logs de baneos recientes directamente:

sudo grep 'Ban' /var/log/fail2ban.log | tail -20

Y para revisar las reglas realmente aplicadas a nivel de firewall (la capa que efectivamente bloquea el tráfico):

sudo iptables -L -n -v -x f2b-sshd

El resto de esta guía documenta un caso real de troubleshooting: un jail con un volumen alto de intentos fallidos, donde el desbloqueo estándar no reflejaba cambios correctamente.

Diagnóstico del problema

Se detectó un alto volumen de intentos fallidos (Total failed: 50634) con 15 IPs bloqueadas activamente. Se intentaron realizar desbloqueos manuales, pero se identificó que la IP objetivo no estaba en la lista de bloqueados actual (Banned IP list).

Esto es más común de lo que parece: el jail puede tener la IP bloqueada a nivel de iptables/nftables sin que la base de datos interna de Fail2Ban (SQLite, normalmente en /var/lib/fail2ban/fail2ban.sqlite3) refleje el mismo estado — de ahí la necesidad de verificar ambas capas por separado.

1. Consulta y monitoreo

Para verificar el estado del jail e identificar las direcciones bajo sanción:

# Ver IPs actualmente bloqueadas en el jail sshd
sudo fail2ban-client status sshd

# Listar todos los jails activos en la instancia de Fail2Ban
fail2ban-client status

# Verificar reglas activas dentro de la cadena específica de iptables
sudo iptables -L -n -v -x f2b-sshd

2. Ejecución de desbloqueo (unban)

Comandos para liberar IPs individuales o masivamente:

# Desbloquear una IP específica por su dirección
sudo fail2ban-client set sshd unbanip <IP_ADDRESS>

# Intentar el desbloqueo masivo de todas las IPs en el jail 'sshd'
sudo fail2ban-client set sshd unbanip ALL

# Limpiar la cadena de iptables (uso extremo si persiste el bloqueo)
sudo iptables -F f2b-sshd

3. Automatización y troubleshooting

En caso de que los comandos estándar no reflejen cambios en iptables, se sugiere este bucle para procesar cada IP individualmente:

# Bucle Bash para desbloqueo manual iterativo
for ip in $(sudo fail2ban-client status sshd | awk '/Banned IP list:/ {print $4}'); do 
    sudo fail2ban-client set sshd unbanip $ip; 
done

# Reinicio del servicio para refrescar la base de datos interna y reglas
sudo systemctl restart fail2ban

Whitelist: prevenir el auto-bloqueo

Para evitar volver a quedar bloqueado por accidente (por ejemplo, tu propia IP fija o la red interna), conviene agregar excepciones permanentes en jail.local:

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 192.168.100.0/24

Cualquier IP dentro de ignoreip nunca será bloqueada por ningún jail, sin importar cuántos intentos fallidos genere.

Notas técnicas adicionales

  • Retorno 0: en fail2ban-client, el retorno 0 indica que la operación se ejecutó exitosamente, aunque no necesariamente significa que haya habido cambios si la IP ya estaba libre.
  • Persistencia en iptables: si las IPs siguen bloqueadas tras usar unbanip ALL, es necesario verificar reglas manuales con sudo nft list ruleset o limpiar directamente la cadena de iptables.
  • Diferencia entre capas: un unbanip exitoso a nivel de Fail2Ban no siempre elimina la regla correspondiente en el firewall si hubo inconsistencias previas — por eso conviene verificar ambos lados (Fail2Ban y iptables/nftables) tras cualquier operación de desbloqueo masivo.