fail2ban contra los intentos de adivinar contraseñas
Módulo 5: Proteger la red · Tiempo de lectura: 10 minutos
Objetivo de aprendizaje: Después de esta lección podrá configurar fail2ban para SSH, leer su estado y su registro, desbloquear de nuevo una dirección y explicar qué protege fail2ban y qué no.
Conceptos clave: fuerza bruta, jail, filtro, acción (banaction), maxretry, findtime, bantime, bantime.increment, ignoreip, backend systemd, jail.conf, jail.local y jail.d, fail2ban-client, recidive
Los que prueban todas las puertas de internet
Mire el registro de SSH un día después de la instalación y lo verá: cientos de intentos de inicio de sesión, con nombres como root, admin, test, ubuntu y oracle, desde direcciones de todo el mundo.
anna@web1:~$ sudo journalctl -u ssh --since today | grep -c "Invalid user"
412
anna@web1:~$ sudo journalctl -u ssh --since today | grep "Invalid user" | tail -n 3
nov 09 14:02:11 web1 sshd-session[20311]: Invalid user admin from 203.0.113.77 port 51522
nov 09 14:02:13 web1 sshd-session[20313]: Invalid user oracle from 203.0.113.77 port 51544
nov 09 14:02:16 web1 sshd-session[20315]: Invalid user test from 203.0.113.77 port 51560(En Ubuntu el servicio se llama ssh, en AlmaLinux y Rocky sshd. El nombre del proceso puede ser sshd o sshd-session, según la versión de OpenSSH.) Eso es un ataque de fuerza bruta: bots que simplemente prueban todos los nombres y contraseñas habituales. Si inicia sesión con claves y tiene desactivado el inicio de sesión con contraseña (lección 2.2), nunca entrarán, por muchas veces que lo intenten. Pero llenan su registro, consumen algo de capacidad de cálculo y, en servicios donde sí se necesita una contraseña (un webmail, un panel de administración), pueden ser realmente peligrosos.
fail2ban lee registros, reconoce los intentos fallidos y bloquea durante un tiempo en el firewall una dirección que falla demasiadas veces.
Cómo piensa fail2ban: jails
fail2ban trabaja con jails (celdas). Un jail combina tres cosas:
- un filtro: expresiones regulares que reconocen intentos fallidos en un registro (por ejemplo, la línea "Invalid user ... from <dirección>");
- una acción: lo que ocurre cuando hay demasiados intentos, normalmente una regla de firewall que bloquea la dirección (
banaction, en Debian 13 por defecto mediante nftables); - umbrales: cuántos intentos fallidos (
maxretry) dentro de cuánto tiempo (findtime) provocan un bloqueo de qué duración (bantime).
Los valores por defecto de jail.conf son: maxretry = 5, findtime = 10m, bantime = 10m. Es decir: cinco intentos fallidos en diez minutos suponen diez minutos de bloqueo.
Instalación y la trampa de Debian 12
anna@web1:~$ sudo apt install fail2ban
anna@web1:~$ sudo systemctl status fail2banEn Debian y Ubuntu, el jail para SSH ([sshd]) ya está activado tras la instalación, mediante el archivo /etc/fail2ban/jail.d/defaults-debian.conf.
Hay una trampa conocida. fail2ban tiene que saber dónde está el registro. Antes era el archivo de texto /var/log/auth.log. Desde Debian 12, rsyslog ya no se instala por defecto y los mensajes solo se guardan en el journal de systemd (lección 6.2). El paquete fail2ban de Debian 12 seguía buscando /var/log/auth.log, no lo encontraba y no arrancaba. Debian 13 lo ha resuelto poniendo backend = systemd para SSH en defaults-debian.conf. En Debian 12 lo resuelve usted mismo (véase más abajo) haciendo lo mismo. Ubuntu sí sigue teniendo rsyslog por defecto, pero backend = systemd también funciona allí.
Su propia configuración: jail.local
No modifique nunca jail.conf: ese archivo se sustituye con cada actualización. Ponga su propia configuración en /etc/fail2ban/jail.local o en un archivo dentro de /etc/fail2ban/jail.d/ con la extensión .local:
# /etc/fail2ban/jail.d/eigen.local
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
bantime.increment = true
ignoreip = 127.0.0.1/8 ::1 198.51.100.20
[sshd]
enabled = true
backend = systemdQué hacen estas líneas:
bantime = 1h: una hora de bloqueo en lugar de diez minutos.bantime.increment = true: quien vuelve después de un bloqueo recibe cada vez un bloqueo más largo.ignoreip: direcciones que nunca se bloquean. Ponga aquí la dirección IP fija de su oficina, si la tiene. No ponga aquí rangos grandes "por si acaso".backend = systemd: leer el journal en lugar de un archivo de texto (necesario en Debian 12, recomendable en todas partes). Para ello debe estar instalado el paquetepython3-systemd; normalmente ya lo está como dependencia.
Recargar y comprobar:
anna@web1:~$ sudo fail2ban-client -t # probar la configuración
OK: configuration test is successful
anna@web1:~$ sudo systemctl reload fail2ban
anna@web1:~$ sudo fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshdLeer el estado, bloquear y desbloquear
anna@web1:~$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 3
| |- Total failed: 1288
| `- Journal matches: _SYSTEMD_UNIT=ssh.service + _COMM=sshd
`- Actions
|- Currently banned: 2
|- Total banned: 117
`- Banned IP list: 203.0.113.77 198.51.100.140"Currently failed" son las direcciones que ya han hecho intentos pero todavía no han superado el umbral. "Currently banned" son las direcciones que están bloqueadas en este momento.
Si se ha bloqueado a sí mismo (por ejemplo, al intentarlo varias veces con la clave o el nombre de usuario equivocados), inicie sesión desde otra red o desde la consola y desbloquee su dirección:
anna@web1:~$ sudo fail2ban-client set sshd unbanip 198.51.100.20El registro del propio fail2ban está en /var/log/fail2ban.log y muestra cuándo se bloqueó y desbloqueó cada dirección:
2026-11-09 14:02:16,903 fail2ban.actions [811]: NOTICE [sshd] Ban 203.0.113.77
2026-11-09 15:02:17,120 fail2ban.actions [811]: NOTICE [sshd] Unban 203.0.113.77Reincidentes: recidive
Algunos bots simplemente vuelven después de cada bloqueo. Para eso hay dos herramientas. bantime.increment (véase arriba) alarga el bloqueo cada vez. Además existe el jail recidive: lee el registro del propio fail2ban y bloquea durante una semana, en todos los puertos, una dirección que ha sido bloqueada a menudo en un mismo día. Se activa en su archivo .local:
[recidive]
enabled = trueLo que fail2ban hace y lo que no
fail2ban es útil, pero no es la cerradura de la puerta. La cerradura es iniciar sesión con una clave y tener las contraseñas desactivadas (lección 2.2). Por eso conviene saber también lo que fail2ban no puede hacer:
- Un ataque distribuido desde miles de direcciones, con uno o dos intentos cada una, nunca supera
maxretry. - Una contraseña débil sigue siendo débil. fail2ban ralentiza el adivinar, nada más.
- Solo lo que aparece en un registro: si un servicio no registra los intentos fallidos, o si fail2ban no lee ese registro, no lo ve.
- Docker: los bloqueos en la cadena normal del firewall no se aplican a los puertos publicados de los contenedores (lección 9.3). Para servicios en contenedores hace falta una configuración aparte (acción sobre la cadena
DOCKER-USER).
Lo que fail2ban sí hace bien: mantener tranquilo el registro, reducir la carga de los bots y proteger servicios en los que (todavía) usa contraseñas, como un webmail o un panel de administración. Para esos servicios existen filtros para nginx, Postfix, Dovecot y muchos otros.
En AlmaLinux y Rocky Linux
Allí fail2ban viene de EPEL: dnf install epel-release y después dnf install fail2ban. El paquete fail2ban instala también la integración con firewalld. El servicio SSH se llama sshd. Active usted mismo el jail en un archivo .local; a diferencia de Debian, no se activa automáticamente.
Resumen
- Los bots intentan iniciar sesión todo el día; con claves y el inicio de sesión con contraseña desactivado no entran, y fail2ban además los mantiene a distancia.
- Un jail es filtro + acción + umbrales (
maxretry,findtime,bantime); por defecto 5 intentos en 10 minutos, 10 minutos de bloqueo. - Su propia configuración va en
jail.localojail.d/*.local, nunca enjail.conf; usebackend = systemd(necesario en Debian 12). fail2ban-client status sshdmuestra las direcciones bloqueadas,set sshd unbaniplas desbloquea; recidive ybantime.incrementse ocupan de los reincidentes.- fail2ban no detiene ataques distribuidos ni contraseñas débiles y no ve por sí solo los puertos de Docker.
Cuestionario
Ejercicio
Ejercicio Z5.3: Leer un registro de intrusión. El archivo de ejemplo ssh-journal-1.txt contiene un fragmento del journal de un servidor SSH con fail2ban, además de la salida de fail2ban-client status sshd. Responda: ¿qué dirección probó más nombres de usuario?, ¿qué dirección logró iniciar sesión con una clave y con qué usuario?, ¿qué dirección está bloqueada y a qué hora? y ¿habría quedado bloqueada también esa dirección con la configuración por defecto (maxretry = 5, findtime = 10m)? El programa compara sus respuestas con la clave fija. Si tiene un servidor propio con fail2ban, consulte allí también fail2ban-client status sshd.
Para saber más
- Proteger su VPS: los primeros cinco minutos
- ¿Estoy bloqueado? Su dirección IP y nuestro cortafuegos
- fail2ban, configuración por defecto
jail.conf: https://github.com/fail2ban/fail2ban/blob/master/config/jail.conf - Manual de
jail.conf(5): https://manpages.debian.org/trixie/fail2ban/jail.conf.5.en.html
