Todo servidor conectado a internet es un objetivo. Bots automatizados escanean rangos de IP las 24 horas del día, intentando miles de combinaciones de usuario y contraseña contra SSH, páginas de inicio de sesión web y servidores de correo. Un solo servicio sin protección puede ser comprometido en cuestión de horas. Fail2Ban es un framework de prevención de intrusiones que monitorea archivos de log en busca de señales de actividad maliciosa y bloquea automáticamente las direcciones IP ofensoras usando reglas de firewall. Esta guía te lleva paso a paso por la instalación, configuración y ajuste de Fail2Ban en Ubuntu, cubriendo protección SSH, jails personalizados para Nginx, integración con UFW, notificaciones por correo electrónico y comandos esenciales de gestión.

Requisitos Previos

Antes de comenzar, asegúrate de tener:

  • Ubuntu Server 20.04, 22.04 o 24.04
  • Acceso a terminal con privilegios sudo
  • Acceso SSH al servidor
  • Un firewall configurado y activo (se recomienda UFW — consulta nuestra guía de UFW)
  • Familiaridad básica con archivos de log y servicios systemd

¿Qué Es Fail2Ban?

Fail2Ban es una herramienta de prevención de intrusiones de código abierto escrita en Python. Se ejecuta como un demonio en segundo plano que monitorea continuamente archivos de log (como /var/log/auth.log o /var/log/nginx/error.log) en busca de patrones que indiquen comportamiento malicioso. Cuando un patrón coincide un número configurable de veces dentro de una ventana de tiempo definida, Fail2Ban crea una regla de firewall para bloquear la dirección IP ofensora durante un período especificado.

Características clave:

  • Basado en logs — reacciona a intentos fallidos reales registrados en archivos de log, no solo a tasas de conexión
  • Jails configurables — cada servicio (SSH, Nginx, Postfix) tiene su propio conjunto de reglas llamado “jail”
  • Múltiples acciones de bloqueo — puede usar iptables, UFW, firewalld, o incluso enviar notificaciones
  • Desbloqueo automático — las IPs bloqueadas se liberan automáticamente al expirar el período de bloqueo
  • Liviano — uso mínimo de recursos incluso en servidores ocupados

Cómo Funciona Fail2Ban

Fail2Ban opera a través de cuatro componentes interconectados:

  1. Archivos de log — la fuente de verdad. Los servicios registran fallos de autenticación y errores en archivos de log
  2. Filtros — expresiones regulares que coinciden con patrones específicos en archivos de log (por ejemplo, “Failed password for” en auth.log)
  3. Jails — unidades de configuración que combinan un filtro con una ruta de archivo de log, umbrales (maxretry, findtime) y una acción
  4. Acciones — lo que sucede cuando se excede el umbral (crear una regla de firewall, enviar un correo, ejecutar un script)

El flujo de trabajo es directo:

Entrada en log → Filtro coincide con patrón → Contador del jail incrementa
→ Contador excede maxretry dentro de findtime → Acción se ejecuta (bloquear IP)
→ Bantime expira → Acción se revierte (desbloquear IP)

Esta arquitectura hace que Fail2Ban sea altamente extensible. Puedes escribir filtros personalizados para cualquier aplicación que produzca salida de log.

Instalación de Fail2Ban

Instala Fail2Ban desde los repositorios de Ubuntu:

sudo apt update
sudo apt install fail2ban -y

Verifica la instalación:

fail2ban-client --version

Comprueba el estado del servicio:

sudo systemctl status fail2ban

Fail2Ban se inicia automáticamente después de la instalación, pero viene con una configuración predeterminada mínima. El siguiente paso es crear una configuración adecuada.

Entendiendo los Archivos de Configuración

Fail2Ban utiliza un sistema de configuración por capas:

ArchivoPropósito¿Editable?
/etc/fail2ban/fail2ban.confConfiguración del demonio (nivel de log, socket)No — usar fail2ban.local
/etc/fail2ban/jail.confDefiniciones de jails predeterminadasNo — usar jail.local
/etc/fail2ban/jail.localTus sobrescrituras personalizadas de jailsSí — esta es tu config principal
/etc/fail2ban/jail.d/*.confConfiguraciones adicionales de jails
/etc/fail2ban/filter.d/*.confDefiniciones de filtros (patrones regex)Sí — para filtros personalizados
/etc/fail2ban/action.d/*.confDefiniciones de acciones (comandos ban/unban)Sí — para acciones personalizadas

Importante: Nunca edites jail.conf o fail2ban.conf directamente. Estos archivos se sobrescriben durante las actualizaciones del paquete. Siempre crea archivos .local que sobrescriban configuraciones específicas.

Crea tu configuración local:

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

Alternativamente, crea un jail.local mínimo desde cero con solo las configuraciones que quieras sobrescribir:

sudo nano /etc/fail2ban/jail.local

Configuración de Protección SSH

La protección SSH es el caso de uso más común y crítico para Fail2Ban. Agrega lo siguiente a tu jail.local:

[DEFAULT]
# Duración del bloqueo: 1 hora
bantime = 3600

# Ventana de tiempo para contar fallos: 10 minutos
findtime = 600

# Número de fallos antes del bloqueo
maxretry = 3

# Usar UFW para acciones de bloqueo (recomendado en Ubuntu)
banaction = ufw

# Tus direcciones IP (separadas por espacio) que nunca se bloquean
ignoreip = 127.0.0.1/8 ::1 TU_IP_DE_CASA

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

Esta configuración:

  • Establece un valor predeterminado global de 3 reintentos dentro de 10 minutos, resultando en un bloqueo de 1 hora
  • Sobrescribe el jail SSH para bloquear por 24 horas (86400 segundos) en su lugar
  • Usa UFW como mecanismo de bloqueo
  • Agrega localhost y tu IP de casa a la lista blanca

Si ejecutas SSH en un puerto no estándar (recomendado — consulta nuestra guía de hardening SSH), actualiza la configuración del puerto:

[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400

Reinicia Fail2Ban para aplicar:

sudo systemctl restart fail2ban

Verifica que el jail SSH esté activo:

sudo fail2ban-client status sshd

Salida esperada:

Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     0
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 0
   |- Total banned:     0
   `- Banned IP list:

Configuración de Jails Personalizados

Más allá de SSH, puedes crear jails para prácticamente cualquier servicio. Aquí hay ejemplos prácticos:

Protección SSH Agresiva

Para servidores bajo ataques intensos, usa bloqueos progresivos con bantime.increment:

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 3600
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 604800

Con esta configuración, el primer bloqueo dura 1 hora, el segundo 2 horas, el tercero 4 horas, y así sucesivamente, hasta un máximo de 7 días (604800 segundos). Los reincidentes son penalizados más severamente cada vez.

Jail Recidive (Bloquear Reincidentes en Todos los Jails)

El jail recidive monitorea el propio log de Fail2Ban y bloquea IPs que son bloqueadas repetidamente en cualquier jail:

[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
bantime = 604800
findtime = 86400
maxretry = 3
banaction = ufw

Esto bloquea una IP por 7 días si es bloqueada 3 veces dentro de 24 horas desde cualquier jail.

Integración con UFW

Para servidores Ubuntu que usan UFW como firewall, configura Fail2Ban para usar UFW en los bloqueos:

[DEFAULT]
banaction = ufw

Verifica la integración revisando las reglas de UFW después de un bloqueo:

sudo ufw status numbered

Las IPs bloqueadas aparecen como reglas de denegación:

[ 1] Anywhere                   DENY IN     203.0.113.100
[ 2] 22/tcp                     ALLOW IN    Anywhere

Si prefieres iptables (por ejemplo, en sistemas sin UFW), usa el valor predeterminado:

[DEFAULT]
banaction = iptables-multiport

Para verificar bloqueos de iptables:

sudo iptables -L f2b-sshd -n

Protección de Nginx

Fail2Ban puede proteger servidores web de varios patrones de ataque. Aquí hay dos jails comunes para Nginx:

Autenticación HTTP de Nginx

Protege páginas detrás de autenticación básica HTTP contra ataques de fuerza bruta:

[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 3600
findtime = 600

El filtro integrado nginx-http-auth coincide con líneas como:

no user/password was provided for basic authentication

Protección Contra Inundación de 404 en Nginx

Bloquea IPs que generan errores 404 excesivos (un patrón común de escáneres de vulnerabilidades):

Crea un filtro personalizado:

sudo nano /etc/fail2ban/filter.d/nginx-404.conf
[Definition]
failregex = ^<HOST> - .* "(GET|POST|HEAD).*HTTP.*" 404
ignoreregex =

Agrega el jail:

[nginx-404]
enabled = true
port = http,https
filter = nginx-404
logpath = /var/log/nginx/access.log
maxretry = 30
findtime = 600
bantime = 3600

Esto bloquea una IP después de 30 errores 404 dentro de 10 minutos. Establece el umbral lo suficientemente alto para evitar bloquear usuarios legítimos que encuentran enlaces rotos.

Protección Contra Bots y Escáneres en Nginx

Crea un filtro para agentes de usuario maliciosos conocidos y escaneo de rutas:

sudo nano /etc/fail2ban/filter.d/nginx-badbots.conf
[Definition]
failregex = ^<HOST> - .* "(GET|POST).*HTTP.*" .* ".*(?:sqlmap|nikto|nmap|masscan|ZmEu|w3af).*"
ignoreregex =
[nginx-badbots]
enabled = true
port = http,https
filter = nginx-badbots
logpath = /var/log/nginx/access.log
maxretry = 1
findtime = 86400
bantime = 604800

Notificaciones por Correo Electrónico

Configura Fail2Ban para enviar alertas por correo cuando se bloquean IPs o cuando los jails se inician/detienen. Primero, instala un agente de transferencia de correo:

sudo apt install sendmail -y

Agrega las configuraciones de notificación a jail.local:

[DEFAULT]
destemail = admin@tudominio.com
sender = fail2ban@tudominio.com
mta = sendmail
action = %(action_mwl)s

Los atajos de acción disponibles son:

AcciónComportamiento
%(action_)sSolo bloqueo (sin notificación)
%(action_mw)sBloqueo + correo con información WHOIS
%(action_mwl)sBloqueo + correo con información WHOIS + líneas de log relevantes

Para un jail específico, sobrescribe la acción:

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
action = %(action_mwl)s

Nota: En servidores de alto tráfico bajo ataque constante, las notificaciones por correo pueden generar un gran volumen de mensajes. Considera usar %(action_)s (solo bloqueo) para jails ocupados y reservar las notificaciones por correo para jails críticos o el jail recidive.

Lista Blanca de IPs

Previene bloqueos accidentales en direcciones IP confiables usando la directiva ignoreip:

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8 192.168.1.0/24 TU_IP_PUBLICA

Puedes listar IPs individuales, rangos CIDR o nombres de host (resueltos al iniciar):

ignoreip = 127.0.0.1/8 ::1 oficina.tudominio.com 203.0.113.50

Para agregar a la lista blanca una IP solo para un jail específico:

[sshd]
enabled = true
ignoreip = 127.0.0.1/8 ::1 10.0.1.50

También puedes agregar a la lista blanca en tiempo de ejecución sin reiniciar Fail2Ban:

# Verificar la lista blanca actual
sudo fail2ban-client get sshd ignoreip

# Agregar una IP a la lista blanca temporalmente (hasta el reinicio)
sudo fail2ban-client set sshd addignoreip 203.0.113.50

Referencia de Comandos Esenciales

ComandoDescripción
sudo systemctl start fail2banIniciar el servicio Fail2Ban
sudo systemctl stop fail2banDetener el servicio Fail2Ban
sudo systemctl restart fail2banReiniciar el servicio Fail2Ban
sudo systemctl status fail2banVerificar el estado del servicio
sudo fail2ban-client statusListar todos los jails activos
sudo fail2ban-client status sshdMostrar estado e IPs bloqueadas del jail sshd
sudo fail2ban-client set sshd banip 203.0.113.100Bloquear manualmente una IP en el jail sshd
sudo fail2ban-client set sshd unbanip 203.0.113.100Desbloquear una IP específica del jail sshd
sudo fail2ban-client unban --allDesbloquear todas las IPs en todos los jails
sudo fail2ban-client get sshd bantimeMostrar la duración actual del bloqueo para un jail
sudo fail2ban-client get sshd maxretryMostrar el límite actual de reintentos para un jail
sudo fail2ban-client get sshd ignoreipMostrar IPs en lista blanca para un jail
sudo fail2ban-client reloadRecargar configuración sin reiniciar
sudo fail2ban-client reload sshdRecargar un jail específico
sudo tail -100 /var/log/fail2ban.logVer entradas recientes del log de Fail2Ban
sudo zgrep "Ban" /var/log/fail2ban.log*Buscar eventos de bloqueo en todos los archivos de log

Solución de Problemas

Fail2Ban No Inicia

Verifica los logs en busca de errores de configuración:

sudo fail2ban-client -t
sudo journalctl -u fail2ban --since "10 minutes ago"

Causas comunes:

  • Errores de sintaxis en jail.local (corchetes faltantes, indentación incorrecta)
  • Archivos de log referenciados que no existen (por ejemplo, /var/log/nginx/error.log cuando Nginx no está instalado)
  • Errores de regex en filtros personalizados

Las IPs No Se Están Bloqueando

Verifica que el jail esté habilitado y monitoreando el archivo de log correcto:

sudo fail2ban-client status sshd

Comprueba que el filtro coincida con las entradas en el log:

sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

Este comando prueba el filtro contra el archivo de log real e informa cuántas coincidencias encuentra. Si el conteo es cero, el filtro no está detectando los patrones esperados.

Usuarios Legítimos Están Siendo Bloqueados

Si los usuarios reportan estar bloqueados:

  1. Desbloquéalos inmediatamente:
sudo fail2ban-client set sshd unbanip IP_DEL_USUARIO
  1. Agrega su IP o red a la lista blanca:
sudo fail2ban-client set sshd addignoreip IP_DEL_USUARIO
  1. Para una corrección permanente, agrega la IP a ignoreip en jail.local y recarga.

Los Bloqueos de Fail2Ban No Persisten Tras Reinicio

Por defecto, Fail2Ban no persiste los bloqueos entre reinicios del servicio. Para habilitar la persistencia, configura una base de datos de bloqueos:

[DEFAULT]
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 86400

La configuración dbpurgeage controla cuánto tiempo (en segundos) se mantienen las entradas antiguas en la base de datos.

Alto Uso de Memoria con Muchos Jails

Si Fail2Ban usa memoria excesiva:

  • Reduce el número de jails activos a solo lo que necesitas
  • Establece dbpurgeage a un valor más bajo para reducir el tamaño de la base de datos
  • Asegúrate de que los archivos de log se estén rotando correctamente con logrotate

Resumen

Fail2Ban es una herramienta de seguridad esencial para cualquier servidor Linux expuesto a internet. Al monitorear archivos de log y bloquear automáticamente IPs que exhiben comportamiento malicioso, proporciona una capa de defensa proactiva que trabaja junto a tu firewall. Las configuraciones clave cubiertas en esta guía — protección SSH, jails de Nginx, integración con UFW y notificaciones por correo — abordan los vectores de ataque más comunes para servidores en producción.

Puntos clave:

  • Siempre crea un archivo jail.local en lugar de editar jail.conf directamente
  • Agrega tus propias direcciones IP a la lista blanca para prevenir bloqueos accidentales
  • Usa tiempos de bloqueo progresivos para penalizar a los reincidentes
  • Combina Fail2Ban con UFW para una gestión de firewall consistente
  • Prueba filtros personalizados con fail2ban-regex antes de implementarlos
  • Monitorea el log de Fail2Ban regularmente para entender el panorama de amenazas de tu servidor

Para una configuración de seguridad completa, combina Fail2Ban con las técnicas descritas en nuestras guías sobre Hardening de SSH, Configuración del Firewall UFW y la Lista de Verificación de Seguridad para Servidores Linux.