Fail2Ban vigila los logs de tus servicios y, cuando una IP acumula demasiados fallos de autenticación en poco tiempo, la bloquea en el firewall durante un periodo configurable. Así frena los ataques de fuerza bruta contra SSH y otros servicios y reduce el ruido en los logs. En este tutorial instalarás Fail2Ban en Ubuntu 24.04, protegerás SSH con bloqueos que se alargan para los reincidentes, añadirás una jaula para Nginx y aprenderás a consultar, bloquear y desbloquear IP a mano.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con acceso por SSH.
- Un usuario no root con privilegios
sudo. - La IP pública desde la que te conectas (
your_ip), para añadirla a la lista blanca. Puedes verla desde tu equipo en cualquier servicio de "cuál es mi IP" o, ya conectado al servidor, conecho "$SSH_CLIENT" | cut -d' ' -f1. - Opcional: Nginx instalado, si quieres seguir el paso 5.
Cómo funciona Fail2Ban
Antes de configurarlo, conviene conocer tres conceptos:
- Filtro (
/etc/fail2ban/filter.d/): expresiones regulares que reconocen un intento fallido en un log, por ejemploInvalid user admin from 203.0.113.45. - Acción (
/etc/fail2ban/action.d/): lo que se hace al bloquear, normalmente añadir una regla de iptables o nftables. - Jaula (jail): une un filtro, una fuente de logs y una acción, con sus límites:
maxretryfallos dentro defindtimeprovocan un bloqueo debantime.
Los valores por defecto están en /etc/fail2ban/jail.conf, que se sobrescribe en cada actualización del paquete. Tus cambios van en /etc/fail2ban/jail.local o en archivos dentro de /etc/fail2ban/jail.d/, que tienen prioridad. No hace falta copiar jail.conf entero: basta con escribir lo que quieres cambiar.
Paso 1: Instalar Fail2Ban
Fail2Ban está en los repositorios oficiales de Ubuntu:
sudo apt update
sudo apt install fail2ban
El paquete deja el servicio habilitado y en marcha. Compruébalo:
sudo systemctl status fail2ban --no-pager
● fail2ban.service - Fail2Ban Service
Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-09-24 10:40:12 UTC; 8s ago
Docs: man:fail2ban(1)
Main PID: 2210 (fail2ban-server)
Si no está activo, arráncalo y habilítalo con sudo systemctl enable --now fail2ban.
Notaen Rocky Linux 9, Fail2Ban está en EPEL. Instálalo con
sudo dnf install epel-releasey despuéssudo dnf install fail2ban, que incluye la integración con firewalld. El resto de la guía es igual, salvo que la unidad de SSH se llamasshd.
Paso 2: Crear la configuración global
Crea /etc/fail2ban/jail.local con los valores que se aplicarán a todas las jaulas:
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
# Tu IP y redes de confianza nunca se bloquean
ignoreip = 127.0.0.1/8 ::1 your_ip
# 5 fallos en 10 minutos provocan un bloqueo de 1 hora
maxretry = 5
findtime = 10m
bantime = 1h
# Cada nuevo bloqueo de la misma IP dura el doble, hasta 1 semana
bantime.increment = true
bantime.maxtime = 1w
Sustituye your_ip por tu IP pública. Puedes añadir varias direcciones o rangos en CIDR separados por espacios, por ejemplo la IP de una VPN corporativa.
Qué hace cada opción:
ignoreip: direcciones que Fail2Ban nunca bloquea. Es tu salvavidas si te equivocas varias veces con tu clave.maxretry,findtimeybantime: el umbral de fallos, la ventana de tiempo en la que se cuentan y la duración del bloqueo. Admiten sufijos comom,h,dow.bantime.incrementybantime.maxtime: Fail2Ban recuerda las IP bloqueadas en su base de datos y alarga el bloqueo cada vez que una IP reincide, hasta el máximo indicado.
Paso 3: Proteger SSH
Añade la jaula de SSH al final del mismo archivo jail.local:
[sshd]
enabled = true
backend = systemd
maxretry = 3
La jaula sshd ya trae definidos en jail.conf el filtro, el puerto y la acción, así que solo cambias lo necesario:
backend = systemd: lee los fallos directamente del journal en lugar de/var/log/auth.log, así funciona aunque el servidor no tenga rsyslog (por ejemplo en instalaciones mínimas o en Debian 12).maxretry = 3: SSH es el servicio más atacado, así que se usa un umbral más estricto que el global.
Si has cambiado el puerto de SSH, indícalo con port = 2222 (sustituyendo el número) para que el bloqueo se aplique al puerto correcto.
Valida la configuración antes de aplicarla:
sudo fail2ban-client -t
OK: configuration test is successful
Recarga Fail2Ban y comprueba las jaulas activas:
sudo systemctl reload fail2ban
sudo fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd
Consulta el detalle de la jaula de SSH. En un servidor expuesto a Internet es normal ver fallos a los pocos minutos:
sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 17
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 203.0.113.45
Journal matches confirma que la jaula está leyendo del journal. El filtro coincide por el nombre del proceso (_COMM=sshd), por lo que funciona aunque en Ubuntu la unidad se llame ssh.service.
Paso 4: Bloquear más tiempo a los reincidentes
La jaula recidive vigila el propio log de Fail2Ban (/var/log/fail2ban.log) y, si una IP ha sido bloqueada varias veces en un día, la bloquea en todos los puertos durante una semana. Complementa bien al bloqueo progresivo del paso 2, porque cubre IP que atacan a varias jaulas distintas.
Añade al final de jail.local:
[recidive]
enabled = true
Los valores por defecto de jail.conf para esta jaula son razonables: 5 bloqueos (maxretry) en 1 día (findtime) provocan un bloqueo de 1 semana en todos los puertos. Aplica y comprueba:
sudo fail2ban-client -t && sudo systemctl reload fail2ban
sudo fail2ban-client status
Status
|- Number of jail: 2
`- Jail list: recidive, sshd
Paso 5: Proteger Nginx
Si tienes zonas de Nginx protegidas con autenticación básica (auth_basic), la jaula nginx-http-auth bloquea las IP que fallan repetidamente la contraseña. Usa el filtro del mismo nombre, que analiza /var/log/nginx/error.log.
Añade la jaula al final de jail.local:
[nginx-http-auth]
enabled = true
Esta jaula lee un archivo de log, no el journal, así que usa el backend por defecto. No añadas backend = systemd aquí.
Importantesi activas una jaula cuyo archivo de log no existe (por ejemplo, porque Nginx no está instalado), Fail2Ban no arrancará. Activa solo jaulas de servicios que tengas en el servidor.
Antes de activarla en producción, comprueba que el filtro reconoce las líneas de tu log con fail2ban-regex, que prueba un filtro contra un archivo sin bloquear nada:
sudo fail2ban-regex /var/log/nginx/error.log nginx-http-auth
La salida es larga; lo importante está en la última línea del resumen:
Lines: 312 lines, 0 ignored, 4 matched, 308 missed
Si matched es mayor que cero cuando hay fallos de contraseña en el log, el filtro funciona. Aplica la configuración:
sudo fail2ban-client -t && sudo systemctl reload fail2ban
sudo fail2ban-client status nginx-http-auth
En /etc/fail2ban/filter.d/ encontrarás filtros para muchos otros servicios (postfix, dovecot, nginx-botsearch, nginx-limit-req...). Se activan igual, con una sección [nombre] y enabled = true, tras revisar en jail.conf qué log esperan.
Paso 6: Gestionar IP bloqueadas
Para bloquear una IP a mano, por ejemplo una que ves en los logs de tu aplicación, usa banip sobre la jaula que corresponda:
sudo fail2ban-client set sshd banip 198.51.100.23
1
La salida 1 indica cuántas IP se han añadido. Para levantar un bloqueo, por ejemplo si un cliente legítimo se ha bloqueado a sí mismo:
sudo fail2ban-client set sshd unbanip 198.51.100.23
Si no sabes en qué jaula está la IP, unban la elimina de todas:
sudo fail2ban-client unban 198.51.100.23
Ver las reglas en el firewall
Fail2Ban aplica los bloqueos con la acción configurada (banaction), que según la versión del paquete es iptables o nftables. Consulta cuál usa la jaula:
sudo fail2ban-client get sshd actions
Si la salida muestra iptables-multiport, los bloqueos están en la cadena f2b-sshd:
sudo iptables -L f2b-sshd -n
Chain f2b-sshd (1 references)
target prot opt source destination
REJECT all -- 203.0.113.45 0.0.0.0/0 reject-with icmp-port-unreachable
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Si muestra una acción de nftables, están en la tabla f2b-table:
sudo nft list table inet f2b-table
Revisar el historial
Todos los bloqueos y desbloqueos quedan en /var/log/fail2ban.log. Para ver los últimos:
sudo grep -E "Ban|Unban" /var/log/fail2ban.log | tail -10
2026-09-24 11:02:47,318 fail2ban.actions [2210]: NOTICE [sshd] Ban 203.0.113.45
2026-09-24 12:02:47,512 fail2ban.actions [2210]: NOTICE [sshd] Unban 203.0.113.45
Solución de problemas
- Fail2Ban no arranca tras un cambio: ejecuta
sudo fail2ban-client -t, que indica el archivo y la línea con el error, y revisasudo journalctl -u fail2ban -n 50. La causa más habitual es una jaula activada con unlogpathque no existe. - La jaula no bloquea nada: comprueba en
fail2ban-client status nombre_jaulaqueTotal failedaumenta. Si se queda en 0, el filtro no encuentra las líneas: pruébalo confail2ban-regexcontra el log real y verifica que el backend (archivo osystemd) es el adecuado. - Te has bloqueado a ti mismo: entra desde otra IP o por la consola web del panel, ejecuta
sudo fail2ban-client unban your_ipy añade tu IP aignoreip. - La IP bloqueada es siempre la del proxy o balanceador: si Nginx está detrás de un proxy, el log registra la IP del proxy. Configura el módulo
real_ipde Nginx para registrar la IP del cliente o bloquearás a todos tus visitantes a la vez.
Conclusión
Fail2Ban vigila ahora SSH y Nginx en tu servidor Ubuntu 24.04, bloquea las IP que acumulan fallos, alarga el bloqueo a los reincidentes y respeta tu lista blanca. También sabes comprobar los filtros con fail2ban-regex y gestionar bloqueos a mano con fail2ban-client.
Como siguientes pasos puedes:
- Desactivar el acceso SSH con contraseña y usar solo claves, que elimina el riesgo de que un ataque de fuerza bruta tenga éxito.
- Activar jaulas para tu servidor de correo u otras aplicaciones expuestas usando los filtros de
/etc/fail2ban/filter.d/. - Combinar Fail2Ban con un firewall de red para cerrar por completo los puertos que no necesitas exponer.
