Proteger VPS Linux con Fail2Ban: bloquear bruteforce en SSH
Aprende a proteger tu VPS Linux con Fail2Ban: instalación, jail personalizada para SSH, integración con firewall y monitoreo de intentos de intrusión.
Cualquier VPS Linux con SSH expuesto a internet recibe cientos de intentos de bruteforce por día. Bots automatizados escanean todo IPv4 probando combinaciones comunes como root/admin, ubuntu/123456 y listas de contraseñas filtradas. Aunque tu contraseña sea fuerte, el ruido en los logs, el consumo de CPU y el riesgo de una credencial débil en algún usuario secundario hacen que estos intentos sean un problema real.
Fail2Ban resuelve esto leyendo logs de autenticación en tiempo real, identificando fallos repetidos desde la misma IP y añadiendo reglas temporales en el firewall para bloquear esa IP. Es ligero (sub-50 MB de RAM en uso típico), está en los repositorios oficiales de Debian y Ubuntu y funciona con cualquier firewall estándar.
Este tutorial cubre la instalación en Ubuntu/Debian, configuración de una jail personalizada para SSH, integración con UFW y ajuste fino del baneo progresivo. Tiempo estimado: 15-20 minutos.
Requisitos previos
VPS ejecutando Ubuntu 22.04/24.04 LTS o Debian 12 con acceso sudo, SSH conectado y UFW (u otro firewall) ya configurado. También necesitas tu IP fija de administración — sin ella, hay riesgo real de quedarte bloqueado fuera.
Ubuntu 24.04 LTS fail2ban ufw / nftables / iptables 22 Si no conoces tu IP pública desde donde administras el VPS, ejecuta curl -4 ifconfig.me en tu máquina local antes de comenzar. Apúntala — la vas a necesitar.
Instalar Fail2Ban
La instalación es directa mediante el gestor de paquetes. No es necesario compilar nada ni añadir repositorios externos.
Actualiza el índice de paquetes:
sudo apt updateEsto garantiza que descargues la versión más reciente de Fail2Ban disponible en los repositorios oficiales.
Instala el paquete:
sudo apt install -y fail2banEl instalador ya habilita e inicia el servicio automáticamente vía systemd. La configuración por defecto protege SSH con parámetros conservadores que vas a sobrescribir en el siguiente paso.
Verifica que el servicio está corriendo:
sudo systemctl status fail2banLa salida debe mostrar active (running) en verde. Si aparece failed, ejecuta sudo journalctl -u fail2ban -n 50 para ver el error — casi siempre es problema de permisos en /var/log/auth.log (se resuelve con sudo chmod 640 /var/log/auth.log).
Crear jail.local para SSH
Fail2Ban tiene dos archivos de configuración: jail.conf (por defecto del paquete, puede ser sobrescrito en updates) y jail.local (tus personalizaciones, preservado en updates). Nunca edites jail.conf — siempre crea jail.local.
Crea el archivo de configuración local:
sudo nano /etc/fail2ban/jail.localPega la configuración siguiente, reemplazando TU.IP.AQUI por tu IP de administración:
[DEFAULT]
# IPs que nunca son baneadas (whitelist)
ignoreip = 127.0.0.1/8 ::1 TU.IP.AQUI
# Tiempo de baneo: 1 hora
bantime = 3600
# Ventana de observación: 10 minutos
findtime = 600
# Intentos antes de banear
maxretry = 5
# Baneo progresivo (multiplica en reincidencias)
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 604800
# Backend: systemd en distribuciones modernas
backend = systemd
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = %(sshd_log)s
maxretry = 5Cada parámetro tiene un efecto directo. bantime = 3600 mantiene la IP baneada por 1 hora en la primera ofensa. Con bantime.increment = true y bantime.factor = 2, la segunda ofensa baneará por 2 horas, la tercera por 4 horas, y así sucesivamente — hasta el techo de 1 semana definido en bantime.maxtime.
Guarda (Ctrl+O, Enter) y sal (Ctrl+X). Recarga Fail2Ban:
sudo systemctl restart fail2banSi administras el VPS desde una IP residencial dinámica (la mayoría de las conexiones domésticas), ignoreip puede fallar cuando tu IP cambie. Considera usar un rango CIDR de tu ISP o autenticarte vía clave SSH (más robusto que depender de whitelist por IP).
Integrar con UFW
Por defecto, Fail2Ban usa iptables para aplicar baneos. Si usas UFW (interfaz más amigable sobre iptables), los bloqueos funcionan pero aparecen en una chain separada — lo que puede confundir la auditoría. La integración correcta delega el bloqueo al propio UFW.
Edita /etc/fail2ban/jail.local y añade dentro del bloque [DEFAULT]:
banaction = ufw
banaction_allports = ufwReinicia el servicio:
sudo systemctl restart fail2banAhora los baneos aparecen directamente en sudo ufw status numbered como reglas DENY en la parte superior de la lista — facilitando la inspección.
Verificación
Confirmar que Fail2Ban está realmente activo y monitoreando SSH toma 30 segundos.
Verifica el estado de la jail SSH:
sudo fail2ban-client status sshdSalida 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:Si la jail aparece listada y File list apunta al auth.log correcto, está funcionando. Después de algunas horas en producción, Total failed y Total banned comienzan a subir naturalmente — los bots de toda internet ya están intentándolo.
Prueba forzada (opcional, hazla desde una segunda IP, no desde tu IP de admin): intenta 6 logins SSH con contraseña incorrecta. El 6º debe fallar con “Connection refused” y la IP debe aparecer en Banned IP list.
Resolución de problemas
Fail2Ban no banea incluso tras varios fallos
Causa más común: el backend no está leyendo el log correcto. En Ubuntu 22.04+ el auth.log fue movido a journald y puede no existir como archivo. Confirma con ls -la /var/log/auth.log. Si no existe, mantén backend = systemd en jail.local — lo que ya está en el ejemplo de arriba.
Otra causa: filtro regex desactualizado. Ejecuta sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf y comprueba si “matched” tiene número > 0.
”Unable to start jail” en el log
Casi siempre es permiso. Fail2Ban corre como usuario fail2ban (o root en distros antiguas) y necesita leer /var/log/auth.log. Verifica con sudo -u fail2ban cat /var/log/auth.log | head — si da denegado, ajusta el ACL.
Me quedé fuera y no tengo IP fija
Si perdiste acceso SSH y tu IP de administración no está en ignoreip, NO intentes forzar más logins — eso solo extiende el baneo. Accede a la consola KVM de tu VPS desde el panel de Hostini, inicia sesión por la consola y ejecuta sudo fail2ban-client set sshd unbanip TU.IP para liberarla.
Próximos pasos
Fail2Ban resuelve una capa del problema — bruteforce ruidoso. Para una postura de seguridad completa, considera también:
- Deshabilitar login con contraseña: edita
/etc/ssh/sshd_configestableciendoPasswordAuthentication notras confirmar que tu clave pública funciona. Bruteforce contra claves es matemáticamente inviable. - Cambiar el puerto SSH por defecto: un puerto distinto al 22 elimina el 95% del escaneo automatizado (atacantes serios lo encuentran, pero los bots tontos no). Recuerda actualizar el UFW antes.
- Habilitar 2FA en SSH con Google Authenticator: añade un TOTP de 6 dígitos a la cadena de autenticación.
- Monitorear baneos: configura notificación por email en Fail2Ban (
action = %(action_mwl)s) para recibir detalles de cada baneo. - Extender a otros servicios: si expones Nginx o Postfix, activa los jails correspondientes en el mismo
jail.local.
Si estás ejecutando una aplicación crítica en producción, un VPS Hostini ya viene con protección DDoS de borde integrada — Fail2Ban sigue siendo útil para bruteforce en la capa de aplicación, pero los ataques volumétricos son filtrados antes de llegar al kernel de tu máquina. Conoce los planes en /vps.
Preguntas frecuentes
¿Fail2Ban reemplaza a un firewall como UFW o nftables?
No. Fail2Ban es una capa reactiva que añade reglas dinámicas al firewall ya existente en tu VPS. Necesita iptables, nftables o UFW funcionando para aplicar los baneos. La combinación correcta es firewall cerrando puertos + Fail2Ban respondiendo a intentos en puertos que deben permanecer abiertos (como SSH).
¿Cuánto tiempo permanece baneada la IP atacante por defecto?
Por defecto son 10 minutos (600 segundos). Para producción es poco — los bots simplemente esperan y vuelven a intentarlo. En entornos reales aumenta bantime a 1 hora (3600) o activa bantime.increment=true para baneo progresivo: cada reincidencia multiplica el tiempo automáticamente.
¿Fail2Ban puede dejarme fuera de mi propio VPS?
Sí, si fallas la contraseña SSH 5 veces desde tu IP. Solución: añade tu IP fija (o rango corporativo) a ignoreip en jail.local. Si aun así te quedas bloqueado, accede a la consola KVM desde el panel de Hostini — te da shell directo sin pasar por SSH, incluso con el firewall activo.
¿Cómo ver qué IPs están baneadas en este momento?
Usa `sudo fail2ban-client status sshd`. La línea 'Banned IP list' muestra las IPs actualmente bloqueadas en la jail sshd. Para desbanear manualmente: `sudo fail2ban-client set sshd unbanip 1.2.3.4`.
¿Fail2Ban funciona con SSH usando claves públicas en lugar de contraseña?
Funciona, pero el riesgo de bruteforce baja drásticamente cuando deshabilitas la autenticación por contraseña (PasswordAuthentication no en /etc/ssh/sshd_config). En ese escenario Fail2Ban sigue siendo útil para bloquear escáneres ruidosos que ocupan log y consumen CPU aunque no consigan entrar.
¿Puedo usar Fail2Ban para proteger otros servicios además de SSH?
Sí. Fail2Ban incluye filtros listos para Nginx, Apache, Postfix, Dovecot, vsftpd, entre otros. Activas cada uno añadiendo una sección [nombre-del-jail] con enabled = true en jail.local. El mismo principio aplica: lee el log del servicio, hace match con un regex de fallo y añade regla al firewall.