Fail2ban: guía práctica para instalar, configurar y afinar tus jails

fail2ban

Cuando alguien me pregunta por una mejora de seguridad rápida y efectiva en un servidor Linux, suelo responder con lo mismo: instala Fail2Ban. No es un firewall “todo en uno” ni pretende serlo; y justo ahí reside su encanto. Hace una tarea concreta —vigilar tus logs y bloquear comportamientos sospechosos— y la hace con una fiabilidad que, en la práctica, marca una diferencia enorme. En mi experiencia, su reacción temprana ataja muchos problemas antes de que se conviertan en incidentes serios y te da visibilidad para actuar con cabeza.


Qué es Fail2ban y por qué “hacer una sola cosa bien” mejora la seguridad real

Fail2Ban observa lo que de verdad ocurre en tu sistema: los registros. Si un origen encadena intentos fallidos, errores repetidos o patrones propios de fuerza bruta, el daemon aplica una acción (normalmente reglas en el firewall) para bloquear esa IP temporal o permanentemente. El resultado tangible es que reduces superficie de ataque y ganas tiempo para pensar.

Aquí es donde brilla su filosofía: ni dependes de firmas mágicas ni de listas perfectas; te apoyas en la evidencia de tu operación. Además, y esto lo valoro mucho, los propios registros se convierten en un radar: puedes detectar IPs reincidentes, horarios de mayor actividad maliciosa o servicios especialmente castigados. Esa transparencia te ayuda a tomar decisiones más inteligentes: ajustar parámetros, crear filtros más finos o incluso automatizar alertas.


Cómo funciona (de verdad): logs, filtros, jails y acciones

El flujo mental es simple y poderoso:

  1. Logs → Filtros: cada servicio genera líneas de log; Fail2Ban aplica filtros (regex) que “reconocen” intentos fallidos, 401/403 agresivos, errores de autenticación, etc.
  2. Filtros → Jails: una jail combina filtro + logpath + parámetros de detección (cuántos fallos en qué ventana de tiempo) + acción (qué hacer con la IP).
  3. Jails → Acciones: lo habitual es tocar el firewall (iptables/nftables/firewalld), pero también puedes enviar correos, ejecutar webhooks o scripts propios.

Parámetros clave: bantime, findtime, maxretry, ignoreip

  • bantime: cuánto durará el bloqueo. Clásico: 10m–1h. En jails sensibles (SSH) puedes escalar a más tiempo tras reincidencia (ver recidive).
  • findtime: ventana de observación. Si pones findtime = 10m y maxretry = 5, 5 fallos en 10 minutos → ban.
  • maxretry: número de fallos permitidos antes de banear.
  • ignoreip: lista de IPs o rangos en whitelist (tu oficina, VPN, monitorización). Mantenla viva para evitar auto-ban.

Trucos prácticos
• Para SSH, suelo empezar con findtime = 10m, maxretry = 4 y bantime = 1h, y luego revisar reincidencias.
• En paneles/NGINX con tráfico alto, conviene no ser excesivamente punitivo al principio para evitar falsos positivos.

jail.conf vs jail.local: patrón seguro de personalización

  • No edites jail.conf. Es el archivo de fábrica.
  • Crea jail.local con solo las secciones/ajustes que quieras sobrescribir. Así, cuando actualices el paquete, no rompes nada y mantienes tus cambios claros.

Instalación rápida por distro (Ubuntu/Debian/CentOS) y verificación con fail2ban-client

Ubuntu/Debian

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

CentOS/RHEL/AlmaLinux/Rocky

sudo dnf install fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client status

Verificación básica

# Estado del servicio y versión
sudo fail2ban-client -V
sudo fail2ban-client status

# Ver jails activos
sudo fail2ban-client status sshd

# Desbanear una IP puntual
sudo fail2ban-client unban 203.0.113.42

Si, como me ocurre en entornos con tráfico constante, notas picos de bloqueos, deja Fail2Ban correr 24–48h y observa. Esa lectura de registros real te dirá dónde ajustar el umbral o qué filtros personalizar.


Jails listos para producción (con comentarios)

Nota: adapta logpath y rutas a tu distro. Los ejemplos van en jail.local.

SSH endurecido (anti-fuerza bruta sin falsos positivos)

[sshd]
enabled   = true
port      = ssh
filter    = sshd
logpath   = /var/log/auth.log
backend   = systemd
maxretry  = 4
findtime  = 10m
bantime   = 1h
ignoreip  = 127.0.0.1/8 10.0.0.0/8 192.168.0.0/16
action    = %(action_mwl)s
# action_mwl: banea + email con líneas de log adjuntas (útil para entender patrones)

En mi día a día, esta combinación es “silenciosa” y eficaz. El correo con logs me ha ayudado a identificar IPs que volvían a los pocos días para subir el bantime o activar recidive.

NGINX/Apache (auth básica, 401/403, bots agresivos)

[nginx-http-auth]
enabled   = true
filter    = nginx-http-auth
logpath   = /var/log/nginx/*error*.log
maxretry  = 5
findtime  = 10m
bantime   = 30m

[apache-badbots]
enabled   = true
filter    = apache-badbots
logpath   = /var/log/apache2/*access*.log
maxretry  = 5
findtime  = 5m
bantime   = 1h

Aquí Fail2Ban brilla integrándose con el servidor web. Cuando lo uso con paneles o CMS, prefiero arrancar con bans cortos para recoger señal y no “castigar” a usuarios legítimos por contraseñas mal tecleadas.

Postfix/Dovecot (SMTP/IMAP)

[postfix]
enabled   = true
filter    = postfix
logpath   = /var/log/mail.log
maxretry  = 5
findtime  = 10m
bantime   = 1h

[dovecot]
enabled   = true
filter    = dovecot
logpath   = /var/log/mail.log
maxretry  = 5
findtime  = 10m
bantime   = 1h

En correo los ataques “gota a gota” son habituales. Me gusta revisar IPs reincidentes semanalmente para valorar bans más largos o listas negras permanentes.

Paneles y CMS (cPanel, Plesk, WordPress)

[wordpress-auth]
enabled   = true
filter    = wordpress-auth
logpath   = /var/log/nginx/*access*.log
maxretry  = 5
findtime  = 10m
bantime   = 45m

Filtro ejemplo filter.d/wordpress-auth.conf (idea base para auth fallida en /wp-login.php):

[Definition]
failregex = <HOST> - .* "(GET|POST) /wp-login\.php HTTP/1\.[01]" 401
ignoreregex =

No hay bala de plata: revisa tus logs reales y ajusta el failregex. Ese enfoque práctico —mirar lo que pasa en tu servidor— es el que me ha dado mejores resultados.


Métricas que importan: leer logs, IPs reincidentes y decisiones inteligentes

  • IPs reincidentes: Si ves la misma IP caer en varias jails (SSH + NGINX), actúa: aumenta bantime, activa recidive o crea una lista negra local.
[recidive]
enabled  = true
logpath  = /var/log/fail2ban.log
bantime  = 1w
findtime = 1d
maxretry = 5
  • Horarios de “ruido”: muchas oleadas llegan en franjas concretas. Programa alertas y cruza con cambios que hagas (¿subió el maxretry? ¿bajó al día siguiente el número de bans?).
  • Alertas útiles (no spam): action_mwl (mail con líneas) es oro si estás afinando filtros. Cuando esté “estable”, pasa a action_ simple para reducir ruido.
  • Observabilidad cotidiana: un fail2ban-client status diario/semana y una revisión de /var/log/fail2ban.log me han permitido detectar falsos positivos antes de que escalen a soporte.

Buenas prácticas y errores comunes que aprendí por las malas

  • No edites jail.conf (sí, insiste en jail.local).
  • Ignora tus rangos legítimos en ignoreip (oficina, VPN, monitorización).
  • Empieza conservador y ajusta: primero recolecta señal, luego endurece.
  • Versiona tus configs (Git) y documenta cambios y motivos.
  • Prueba tus filtros con fail2ban-regex antes de activarlos en producción.
  • Piensa en contenedores: si estás en Docker/K8s, decide dónde aplicar la acción (host vs. contenedor) y considera ingress o WAF como primera línea.

Preguntas frecuentes y soluciones

¿Cómo desbaneo rápido una IP?
sudo fail2ban-client unban 203.0.113.42

¿Puedo usar nftables o firewalld?
Sí. Cambia la acción de la jail (action = nftables-multiport o firewalld) acorde a tu stack.

¿Qué diferencia hay entre maxretry bajo y findtime corto?
Ambos endurecen, pero de forma distinta. Un maxretry bajo penaliza pequeños errores; un findtime corto “perdona” si los fallos se dispersan en el tiempo.

¿Cómo evito falsos positivos en WordPress/paneles?
Ajusta el failregex al patrón de tu stack (tema, plugins, reverse proxy). Empieza con bans cortos y mide.

¿Puedo hacer bans permanentes?
Sí, con bantime = -1 o gestionando una lista negra fuera de Fail2Ban (útil para IPs/ASN claramente maliciosos).


Plantillas de jail.local para copiar/pegar (y adaptar)

[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 4
backend  = systemd
ignoreip = 127.0.0.1/8 10.0.0.0/8 192.168.0.0/16
# action = %(action_)s       # básico
action   = %(action_mwl)s    # ban + mail con logs

[sshd]
enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/auth.log

[nginx-http-auth]
enabled  = true
filter   = nginx-http-auth
logpath  = /var/log/nginx/*error*.log

[recidive]
enabled  = true
logpath  = /var/log/fail2ban.log
bantime  = 1w
findtime = 1d
maxretry = 5

Fail2ban

Fail2Ban no hace ruido, pero hace el trabajo. En mi experiencia, su enfoque práctico —mirar los logs, reaccionar temprano y aprender de los patrones— rinde mucho más que soluciones “mágicas” que prometen demasiado. Si lo integras con tus servicios clave (SSH, web, correo, paneles), lo calibras con datos reales y mantienes la casa ordenada (jail.local, filtros probados, métricas), obtendrás seguridad realista y sostenible.

Opinión Personal

Confieso que me cae especialmente bien Fail2Ban. No vende humo ni promete seguridad absoluta; hace una cosa muy concreta —vigilar tus logs y frenar comportamientos abusivos— y la hace de forma impecable. En la práctica, eso se traduce en servidores más tranquilos y menos tickets de “¿por qué hay tantos intentos de login?”. No es glamour, es eficacia.

Cuando lo integro en un stack con SSH, NGINX y correo, el cambio se nota rápido. Los picos de fuerza bruta bajan y yo gano tiempo para lo importante: optimizar, actualizar, observar patrones. Lo mejor es la transparencia: te obliga a mirar tus propios registros y tomar decisiones con datos, no con supersticiones. ¿IPs reincidentes? Endureces. ¿Falsos positivos en horario de oficina? Ajustas. Esa retroalimentación convierte un “instala y reza” en un proceso vivo y saludable.

¿Tiene límites? Claro. Si esperas que Fail2Ban sustituya a un WAF o a una buena política de contraseñas, te vas a decepcionar. También puedes romper la experiencia de usuario si te pasas de severo con bantime y maxretry sin entender tu tráfico real. Pero justo ahí está el punto: es una herramienta que premia a quien mide, prueba y afina.

Mi opinión: si administras sistemas y no usas Fail2Ban, estás dejando valor sobre la mesa. Es barato en recursos, rápido de implementar y brutalmente útil para cortar ruido. Y a diferencia de otras soluciones “caja negra”, aquí ves qué ocurre, por qué se banea y cómo mejorar.

Ahora quiero escucharte a ti: ¿lo usas en producción?, ¿qué jails te han funcionado mejor?, ¿qué falsos positivos te han dado guerra? Déjame tus comentarios abajo y lo debatimos.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *