Fail2ban: instalación, jail.local, filtros y acciones

Introducción

Fail2ban monitoriza los logs del sistema y bloquea automáticamente las IPs que realizan demasiados intentos fallidos de autenticación en un intervalo de tiempo. Es la primera línea de defensa contra ataques de fuerza bruta en SSH, FTP, HTTP y otros servicios.

Instalación y estructura de ficheros


# Debian/Ubuntu
apt install fail2ban

# Red Hat/CentOS/Fedora
dnf install fail2ban

# Habilitar e iniciar
systemctl enable --now fail2ban

# Estructura de ficheros
/etc/fail2ban/
  fail2ban.conf      # configuración del demonio (no editar)
  fail2ban.local     # configuración local (sobreescribe fail2ban.conf)
  jail.conf          # configuración de jails (no editar directamente)
  jail.local         # configuración local de jails (aquí se trabaja)
  filter.d/          # filtros (expresiones regulares para detectar fallos)
  action.d/          # acciones (qué hacer al banear)
          

Regla importante: nunca editar jail.conf directamente. Los cambios en jail.local tienen prioridad y sobreviven a actualizaciones del paquete.

jail.local — Configuración principal


# /etc/fail2ban/jail.local

[DEFAULT]
# Tiempo de baneo en segundos (o con sufijo h, d: 1h, 7d)
bantime  = 1h

# Ventana de tiempo en la que se cuentan los intentos
findtime = 10m

# Número de intentos fallidos antes de banear
maxretry = 5

# IPs que nunca se banean (localhost + redes de confianza)
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 10.0.0.0/8

# Backend para leer logs (auto detecta systemd/journal o fichero)
backend = auto

# Acción por defecto al banear (usar iptables o nftables según el sistema)
banaction = iptables-multiport
# banaction = nftables-multiport   # para sistemas con nftables

# Enviar notificación por email (requiere sendmail/postfix)
# destemail = admin@ejemplo.com
# action = %(action_mwl)s   # ban + email con log

[sshd]
# Activar la jail de SSH
enabled = true
port    = ssh          # o el número de puerto si es diferente al 22
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3           # SSH más restrictivo que el DEFAULT
bantime  = 24h

# Para nginx (si se tiene instalado)
[nginx-http-auth]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log
maxretry = 5
          

fail2ban-client — Gestión en tiempo real


# Estado general
fail2ban-client status

# Estado de una jail específica
fail2ban-client status sshd
# Muestra: IPs baneadas, intentos totales, actualmente baneadas

# Desbanear una IP manualmente
fail2ban-client set sshd unbanip 203.0.113.50

# Banear una IP manualmente
fail2ban-client set sshd banip 10.0.0.99

# Recargar configuración sin reiniciar
fail2ban-client reload

# Recargar una jail específica
fail2ban-client reload sshd

# Ver las reglas de iptables creadas por fail2ban
iptables -L f2b-sshd -v --line-numbers

# Ver el log de fail2ban
tail -f /var/log/fail2ban.log
journalctl -u fail2ban -f
          

Filtros — Cómo detecta los fallos

Los filtros en /etc/fail2ban/filter.d/ son ficheros con expresiones regulares que coinciden con las líneas de log que indican un fallo de autenticación.


# Ver el filtro de SSH
cat /etc/fail2ban/filter.d/sshd.conf

# Probar un filtro contra un fichero de log
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
# Muestra cuántas líneas coinciden con el filtro

# Probar con una cadena de texto
fail2ban-regex "May  9 10:00:01 srv sshd[1234]: Failed password for invalid user root from 1.2.3.4 port 54321 ssh2" /etc/fail2ban/filter.d/sshd.conf

# Crear un filtro personalizado para una aplicación
# /etc/fail2ban/filter.d/mi-app.conf
[Definition]
failregex = ^%(__prefix_line)sLogin failed for .+ from <HOST>$
ignoreregex =
          

Acciones — Qué hace al banear


# Acciones principales disponibles:
# action_       → solo banear con iptables
# action_mw     → banear + enviar email
# action_mwl    → banear + email + líneas del log relevantes

# En jail.local, sección [DEFAULT]:
action = %(action_)s     # solo banear (recomendado, sin email)
# action = %(action_mwl)s  # con email (requiere MTA configurado)

# Ver las acciones disponibles
ls /etc/fail2ban/action.d/

# Contenido de una acción personalizada simplificada
# /etc/fail2ban/action.d/mi-accion.conf
[Definition]
actionban   = iptables -I INPUT -s <ip> -j DROP
actionunban = iptables -D INPUT -s <ip> -j DROP
          

Ejemplo completo: proteger SSH y nginx


# /etc/fail2ban/jail.local

[DEFAULT]
bantime  = 2h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 192.168.1.0/24
backend  = auto

[sshd]
enabled  = true
maxretry = 3
bantime  = 7d

[nginx-http-auth]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log

[nginx-limit-req]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log
maxretry = 10
          

# Aplicar y verificar
systemctl restart fail2ban
fail2ban-client status
fail2ban-client status sshd
          

Siempre incluir las IPs de confianza en ignoreip antes de activar fail2ban. Un bloqueo accidental de la propia IP de administración puede dejar el servidor inaccesible.

Logs de seguridad: /var/log/auth.log, last, auditd

Índice de la sección

Índice del curso