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:
- Archivos de log — la fuente de verdad. Los servicios registran fallos de autenticación y errores en archivos de log
- Filtros — expresiones regulares que coinciden con patrones específicos en archivos de log (por ejemplo, “Failed password for” en auth.log)
- Jails — unidades de configuración que combinan un filtro con una ruta de archivo de log, umbrales (maxretry, findtime) y una acción
- 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:
| Archivo | Propósito | ¿Editable? |
|---|---|---|
/etc/fail2ban/fail2ban.conf | Configuración del demonio (nivel de log, socket) | No — usar fail2ban.local |
/etc/fail2ban/jail.conf | Definiciones de jails predeterminadas | No — usar jail.local |
/etc/fail2ban/jail.local | Tus sobrescrituras personalizadas de jails | Sí — esta es tu config principal |
/etc/fail2ban/jail.d/*.conf | Configuraciones adicionales de jails | Sí |
/etc/fail2ban/filter.d/*.conf | Definiciones de filtros (patrones regex) | Sí — para filtros personalizados |
/etc/fail2ban/action.d/*.conf | Definiciones de acciones (comandos ban/unban) | Sí — para acciones personalizadas |
Importante: Nunca edites
jail.confofail2ban.confdirectamente. Estos archivos se sobrescriben durante las actualizaciones del paquete. Siempre crea archivos.localque 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ón | Comportamiento |
|---|---|
%(action_)s | Solo bloqueo (sin notificación) |
%(action_mw)s | Bloqueo + correo con información WHOIS |
%(action_mwl)s | Bloqueo + 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
| Comando | Descripción |
|---|---|
sudo systemctl start fail2ban | Iniciar el servicio Fail2Ban |
sudo systemctl stop fail2ban | Detener el servicio Fail2Ban |
sudo systemctl restart fail2ban | Reiniciar el servicio Fail2Ban |
sudo systemctl status fail2ban | Verificar el estado del servicio |
sudo fail2ban-client status | Listar todos los jails activos |
sudo fail2ban-client status sshd | Mostrar estado e IPs bloqueadas del jail sshd |
sudo fail2ban-client set sshd banip 203.0.113.100 | Bloquear manualmente una IP en el jail sshd |
sudo fail2ban-client set sshd unbanip 203.0.113.100 | Desbloquear una IP específica del jail sshd |
sudo fail2ban-client unban --all | Desbloquear todas las IPs en todos los jails |
sudo fail2ban-client get sshd bantime | Mostrar la duración actual del bloqueo para un jail |
sudo fail2ban-client get sshd maxretry | Mostrar el límite actual de reintentos para un jail |
sudo fail2ban-client get sshd ignoreip | Mostrar IPs en lista blanca para un jail |
sudo fail2ban-client reload | Recargar configuración sin reiniciar |
sudo fail2ban-client reload sshd | Recargar un jail específico |
sudo tail -100 /var/log/fail2ban.log | Ver 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.logcuando 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:
- Desbloquéalos inmediatamente:
sudo fail2ban-client set sshd unbanip IP_DEL_USUARIO
- Agrega su IP o red a la lista blanca:
sudo fail2ban-client set sshd addignoreip IP_DEL_USUARIO
- Para una corrección permanente, agrega la IP a
ignoreipenjail.localy 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
dbpurgeagea 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.localen lugar de editarjail.confdirectamente - 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-regexantes 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.