Cada VPS conectado a internet recibe cientos de intentos de acceso no autorizado al día. Bots automatizados prueban contraseñas las 24 horas del día.
Fail2ban detecta estos intentos y bloquea automáticamente las IPs atacantes. Es como tener un guardia de seguridad que nunca duerme.
Esta guía te enseña a instalar y configurar Fail2ban para proteger todos tus servicios.
Qué es Fail2ban
Fail2ban es un software que monitoriza los logs de tu servidor buscando patrones de ataque. Cuando detecta múltiples intentos fallidos desde una IP, la bloquea temporalmente en el firewall.
El problema que resuelve
Sin Fail2ban:
IP Atacante → Intento 1 → Fallido
IP Atacante → Intento 2 → Fallido
IP Atacante → Intento 3 → Fallido
... (miles de intentos) ...
IP Atacante → Intento 10.000 → ¿Éxito?
Con Fail2ban:
IP Atacante → Intento 1 → Fallido (registrado)
IP Atacante → Intento 2 → Fallido (registrado)
IP Atacante → Intento 3 → Fallido (registrado)
IP Atacante → Intento 4 → BLOQUEADO por 10 minutos
IP Atacante → Intento 5 → BLOQUEADO
... (no puede continuar) ...
Servicios que puede proteger
| Servicio | Tipo de ataque | Protección |
|---|---|---|
| SSH | Fuerza bruta login | ✅ |
| Nginx/Apache | Auth básica, exploits | ✅ |
| WordPress | wp-login, xmlrpc | ✅ |
| Postfix | Spam, auth SMTP | ✅ |
| FTP | Login fuerza bruta | ✅ |
| MySQL | Conexiones no autorizadas | ✅ |
Cómo funciona
El flujo de detección
- Monitoriza logs: Fail2ban lee archivos de log en tiempo real
- Aplica filtros: Busca patrones (regex) de intentos fallidos
- Cuenta intentos: Lleva registro por IP
- Ejecuta acción: Cuando supera el umbral, bloquea la IP
Conceptos clave
Jail (cárcel): Configuración para un servicio específico. Combina:
- Filtro (qué buscar en logs)
- Acción (qué hacer al detectar)
- Parámetros (intentos, tiempo)
Filter (filtro): Expresiones regulares que identifican intentos fallidos en logs.
Action (acción): Qué hacer cuando se detecta un ataque (normalmente bloquear con iptables/ufw).
Ban time: Tiempo que la IP permanece bloqueada.
Find time: Ventana de tiempo para contar intentos.
Max retry: Número de intentos permitidos antes de bloquear.
Instalación
Ubuntu/Debian
sudo apt update
sudo apt install fail2ban -y
Verificar instalación
sudo systemctl status fail2ban
Estructura de archivos
/etc/fail2ban/
├── fail2ban.conf # Config general (no editar)
├── jail.conf # Jails por defecto (no editar)
├── jail.local # TU configuración (crear/editar)
├── jail.d/ # Configuraciones adicionales
├── filter.d/ # Filtros (regex)
└── action.d/ # Acciones
Importante: Nunca edites jail.conf. Crea jail.local que sobrescribe la configuración por defecto.
Configuración básica
Crear jail.local
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
# Tiempo de bloqueo (10 minutos)
bantime = 10m
# Ventana para contar intentos (10 minutos)
findtime = 10m
# Intentos permitidos antes de bloquear
maxretry = 5
# IPs que nunca se bloquean (tu IP, localhost)
ignoreip = 127.0.0.1/8 ::1 TU_IP_FIJA
# Backend para monitorizar logs
backend = systemd
# Acción por defecto
banaction = iptables-multiport
banaction_allports = iptables-allports
# Email para notificaciones (opcional)
destemail = [email protected]
sender = [email protected]
# Acción: ban y enviar email
action = %(action_mwl)s
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 1h
Reiniciar Fail2ban
sudo systemctl restart fail2ban
Verificar que funciona
sudo fail2ban-client status
sudo fail2ban-client status sshd
Jails importantes para VPS
SSH (obligatorio)
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 10m
bantime = 1h
Si usas puerto SSH no estándar:
port = 2222
Nginx - Autenticación básica
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 1h
Nginx - Bots y scanners
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 1d
Nginx - Errores 4xx excesivos
Crear filtro personalizado:
sudo nano /etc/fail2ban/filter.d/nginx-4xx.conf
[Definition]
failregex = ^<HOST>.*"(GET|POST|HEAD).*" (400|401|403|404|405|444) .*$
ignoreregex = \.(?:css|js|ico|gif|jpg|jpeg|png|svg|woff|woff2)
Añadir jail:
[nginx-4xx]
enabled = true
port = http,https
filter = nginx-4xx
logpath = /var/log/nginx/access.log
maxretry = 20
findtime = 1m
bantime = 10m
Apache
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/error.log
maxretry = 3
bantime = 1h
[apache-badbots]
enabled = true
port = http,https
filter = apache-badbots
logpath = /var/log/apache2/access.log
maxretry = 2
bantime = 1d
WordPress - wp-login
Crear filtro:
sudo nano /etc/fail2ban/filter.d/wordpress-login.conf
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
^<HOST> .* "POST /xmlrpc.php
ignoreregex =
Añadir jail:
[wordpress-login]
enabled = true
port = http,https
filter = wordpress-login
logpath = /var/log/nginx/access.log
maxretry = 3
findtime = 5m
bantime = 1h
WordPress - xmlrpc (muy atacado)
[wordpress-xmlrpc]
enabled = true
port = http,https
filter = wordpress-login
logpath = /var/log/nginx/access.log
failregex = ^<HOST> .* "POST /xmlrpc.php
maxretry = 1
bantime = 1d
Postfix (correo)
[postfix]
enabled = true
port = smtp,465,submission
filter = postfix
logpath = /var/log/mail.log
maxretry = 3
bantime = 1h
[postfix-sasl]
enabled = true
port = smtp,465,submission
filter = postfix[mode=auth]
logpath = /var/log/mail.log
maxretry = 3
bantime = 1d
Dovecot (IMAP/POP3)
[dovecot]
enabled = true
port = pop3,pop3s,imap,imaps
filter = dovecot
logpath = /var/log/mail.log
maxretry = 3
bantime = 1h
Comandos esenciales
Estado general
# Ver jails activos
sudo fail2ban-client status
# Ver estado de un jail específico
sudo fail2ban-client status sshd
Gestionar IPs bloqueadas
# Ver IPs bloqueadas en un jail
sudo fail2ban-client status sshd
# Desbloquear IP manualmente
sudo fail2ban-client set sshd unbanip 192.168.1.100
# Bloquear IP manualmente
sudo fail2ban-client set sshd banip 192.168.1.100
Gestionar jails
# Recargar configuración
sudo fail2ban-client reload
# Reiniciar un jail específico
sudo fail2ban-client restart sshd
# Parar un jail
sudo fail2ban-client stop sshd
# Iniciar un jail
sudo fail2ban-client start sshd
Probar filtros
# Probar regex contra un log
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
# Probar filtro personalizado
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress-login.conf
Configuración avanzada
Ban progresivo (reincidentes)
Bloqueos más largos para IPs que vuelven a atacar:
[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
action = iptables-allports[name=recidive]
bantime = 1w
findtime = 1d
maxretry = 3
Bloqueo permanente
Para IPs muy problemáticas:
[permanent]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
bantime = -1
findtime = 1y
maxretry = 10
Whitelist por jail
[sshd]
enabled = true
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 TU_IP_OFICINA
Notificaciones por email
[DEFAULT]
destemail = [email protected]
sender = [email protected]
mta = sendmail
action = %(action_mwl)s
Acciones disponibles:
%(action_)s- Solo bloquear%(action_mw)s- Bloquear + email con whois%(action_mwl)s- Bloquear + email con whois + logs relevantes
Integración con UFW
Si usas UFW en lugar de iptables directo:
[DEFAULT]
banaction = ufw
Monitorización y logs
Ver actividad en tiempo real
sudo tail -f /var/log/fail2ban.log
Estadísticas de un jail
sudo fail2ban-client status sshd
Output:
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 847
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 5
|- Total banned: 123
`- Banned IP list: 192.168.1.100 10.0.0.50 ...
Script de resumen diario
#!/bin/bash
# /root/scripts/fail2ban-report.sh
echo "=== Fail2ban Report $(date) ==="
echo ""
for jail in $(sudo fail2ban-client status | grep "Jail list" | sed 's/.*://;s/,//g'); do
echo "--- $jail ---"
sudo fail2ban-client status $jail | grep -E "Currently|Total"
echo ""
done
Añadir a cron para reporte diario:
0 8 * * * /root/scripts/fail2ban-report.sh | mail -s "Fail2ban Daily Report" [email protected]
Errores comunes
Error 1: Bloquearte a ti mismo
Solución: Siempre añade tu IP a ignoreip:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 TU_IP_FIJA
Si te bloqueaste: Accede por consola VNC y ejecuta:
sudo fail2ban-client set sshd unbanip TU_IP
Error 2: Filtro no coincide
# Probar que el filtro funciona
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
Si muestra 0 matches, revisa:
- Ruta del log correcta
- Formato del log coincide con regex
- Backend configurado (systemd vs file)
Error 3: Jail no se activa
Verificar:
sudo fail2ban-client status
Revisar logs:
sudo journalctl -u fail2ban -f
Causas comunes:
- Archivo de log no existe
- Permisos incorrectos
- Sintaxis errónea en jail.local
Error 4: IPs se desbloquean muy rápido
Aumenta bantime:
bantime = 1h # o 1d para 1 día
Para reincidentes:
[recidive]
enabled = true
bantime = 1w
Optimización
Reducir carga del servidor
[DEFAULT]
# Usar systemd para logs (más eficiente)
backend = systemd
# No analizar logs muy antiguos al reiniciar
dbpurgeage = 1d
Limitar memoria
[DEFAULT]
# Máximo de IPs a trackear
dbmaxmatches = 10
# Purgar DB regularmente
dbpurgeage = 1d
Fail2ban + otras herramientas
Con Cloudflare
Bloquear en Cloudflare en lugar de localmente (más efectivo):
sudo apt install python3-pip
pip3 install cloudflare
Crear action /etc/fail2ban/action.d/cloudflare.conf y configurar API key.
Con firewall UFW
[DEFAULT]
banaction = ufw
Con scripts personalizados
Puedes ejecutar cualquier script al detectar ataque:
[sshd]
action = iptables-multiport[name=sshd, port="ssh"]
custom-script[name=sshd]
Checklist de configuración
| Tarea | Verificación | ✓ |
|---|---|---|
| Fail2ban instalado | systemctl status fail2ban | ☐ |
| jail.local creado | ls /etc/fail2ban/jail.local | ☐ |
| SSH jail activo | fail2ban-client status sshd | ☐ |
| Tu IP en whitelist | Verificar ignoreip | ☐ |
| Nginx/Apache jail | Si tienes web | ☐ |
| WordPress jail | Si tienes WP | ☐ |
| Recidive activo | Para reincidentes | ☐ |
Preguntas frecuentes
¿Fail2ban afecta el rendimiento?
Mínimamente. Usa pocos recursos monitorizando logs.
¿Puedo bloquear países enteros?
Sí, pero es mejor usar el firewall o Cloudflare para eso.
¿Qué pasa si me bloqueo?
Accede por consola VNC desde el panel de tu proveedor y desbloquéate.
¿Funciona con IPv6?
Sí, pero necesitas configurar acciones para IPv6 también.
Nuestra recomendación
Configuración mínima:
- Jail SSH con maxretry=3 y bantime=1h
- Tu IP en whitelist
- Recidive para reincidentes
Si tienes web: Añade jails para Nginx/Apache y WordPress.
¿No quieres complicarte? La administración gestionada incluye Fail2ban preconfigurado y monitorizado.
Conclusión
Fail2ban es esencial para cualquier VPS. Con 10 minutos de configuración, bloqueas automáticamente la mayoría de ataques de fuerza bruta.
Instálalo hoy. Tu VPS estará mucho más seguro esta noche.
¿Quieres un VPS con seguridad preconfigurada? Explora los VPS de Avantys con Fail2ban incluido.
Guías relacionadas
- Firewall en VPS: UFW e iptables
- Securizar un VPS Linux
- Monitorizar tu VPS con Netdata
- Automatizar tareas con cron
¿Quieres la guía completa con todos los casos de uso?
¿Quieres que lo hagamos por ti?
En Avantys gestionamos tu web, hosting y crecimiento digital de punta a punta. Tú a lo importante.