Seguridad

Protege tu SSH con Fail2ban: Guía Completa para Sysadmins Linux

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 1-2 horas para un server nuevo.
  • Requisitos: Acceso root, 2 sesiones SSH abiertas durante cambios.
  • Resultado: Login por clave ed25519, fail2ban activo, 99% de ataques bloqueados.
  • Troubleshooting: Consola del proveedor, journalctl -u sshd, fail2ban-client status.

Por qué Fail2ban sigue siendo la primera línea de defensa en 2026

Cada servidor Linux expuesto a internet recibe miles de intentos de autenticación SSH al día. Los bots que prueban combinaciones root:root, admin:admin o listas de contraseñas filtradas no han desaparecido con la adopción masiva de claves SSH: ahora rotan entre direcciones IP residenciales y de datacenter a una velocidad que ningún sysadmin puede seguir a mano. Fail2ban cumple una función simple y contundente: leer los logs de tu servidor, detectar patrones de fallo repetidos y bloquear al responsable en el firewall durante un tiempo configurable.

La versión 1.1.1, publicada el 15 de agosto de 2026 bajo el sobrenombre «triple-one-win», confirma que el proyecto sigue maduro y empujado por su maintainer. Los cambios de esta entrega (resumidos en el ChangeLog oficial) incluyen activación por socket systemd, soporte nativo para journald, filtros nuevos para Proxmox, OpenVPN, Vaultwarden y XRDP, y mejoras en las acciones nftables e iptables. Si administras un servidor SSH en producción en 2026, Fail2ban sigue siendo la opción más sólida, reproducible y documentada para mitigar fuerza bruta.

Cómo funciona Fail2ban: jail, filter y action

La arquitectura se entiende en tres piezas:

  • Filter: una expresión regular que Fail2ban aplica sobre un archivo de log (o sobre journald) para identificar intentos fallidos. El filtro sshd.conf, incluido por defecto, sabe leer Failed password, Invalid user y Connection closed by authenticating user.
  • Action: lo que Fail2ban hace cuando el filtro dispara. Lo habitual es añadir la IP a una cadena de firewall (iptables, nftables o ipset) durante un tiempo, pero también puede mandar notificaciones por correo, Telegram, Slack o webhooks genéricos.
  • Jail: la combinación de filter + action + umbrales (maxretry, findtime, bantime). Un jail es una «celda» donde un atacante cumple su castigo antes de ser liberado.

Esta separación permite activar varios jails sobre el mismo filtro con políticas diferentes: por ejemplo, un jail agresivo para descartar escaneos masivos y otro más laxo para no bloquear a tu propio operador que tipea mal la passphrase del YubiKey.

Instalación en Debian, Ubuntu y RHEL

En Debian y derivados el paquete vive en los repos oficiales y se mantiene al día. En RHEL/Fedora/Rocky la situación es idéntica desde EPEL. La instalación es trivial, pero el primer paso después de instalar siempre es verificar la versión y arrancar el servicio:

# Debian 12+, Ubuntu 22.04+
sudo apt update
sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
fail2ban-client version

La salida de fail2ban-client version debe coincidir con la versión del paquete. En Debian 12 a mediados de 2026 ya viene con Fail2ban 1.1.1; si ves 0.11.x o anterior estás en una distro LTS que necesita el repo backports o un paquete manual desde el release oficial.

En RHEL 9, Rocky Linux 9 o AlmaLinux 9, Fail2ban se distribuye en EPEL y requiere habilitar ese repositorio:

# RHEL 9 / Rocky 9 / AlmaLinux 9 / Fedora
sudo dnf install -y epel-release
sudo dnf install -y fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client version

Verifica que el servicio queda active (running) con systemctl status fail2ban. Si systemd informa que la unidad «failed», revisa journalctl -u fail2ban -n 50: lo más común es un /etc/fail2ban/jail.local mal formado de un intento anterior.

Consejo de operación: nunca edites /etc/fail2ban/jail.conf directamente. Fail2ban lo sobrescribe en cada upgrade. En lugar de eso, crea /etc/fail2ban/jail.local con tus overrides; Fail2ban lo lee después del .conf y tus cambios sobreviven a las actualizaciones.

Configurar el jail SSH paso a paso

El archivo jail.local acepta una sección [DEFAULT] que aplica a todos los jails, y secciones [nombre] para jails específicos. Empezamos con una configuración robusta y conservadora que funciona en la mayoría de servidores:

sudo tee /etc/fail2ban/jail.local > /dev/null <<'EOF'
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16 10.0.0.0/8
bantime  = 1h
findtime = 10m
maxretry = 5
backend  = systemd
[sshd]
enabled  = true
port     = ssh
filter   = sshd
logpath  = %(sshd_log)s
maxretry = 4
findtime = 10m
bantime  = 24h
EOF
sudo systemctl restart fail2ban

Lo importante aquí: ignoreip lista tus redes internas y tu IP fija de administración. Si te bloqueas a ti mismo durante la configuración, siempre puedes volver desde la consola KVM/iDRAC del proveedor o esperando a que expire el bantime. El parámetro backend = systemd le dice a Fail2ban que lea journalctl en lugar de un archivo, lo cual es más robusto en servidores modernos donde rsyslog puede rotar agresivamente.

Reinicia y comprueba el estado del jail:

sudo fail2ban-client status
sudo fail2ban-client status sshd

El segundo comando debe listar el jail [sshd] con Currently banned: 0, el número de Total banned acumulado y los intentos fallidos (Total matched). Si todo está en cero después de esperar unas horas, el jail está atrapando intentos de bots automáticamente.

Endurecer el filtro: recidive y filtros por regex

El jail [sshd] por defecto protege bien contra un atacante insistente desde una sola IP. Pero los bots modernos rotan: prueban 2 o 3 veces desde una IP, la queman, saltan a la siguiente y repiten. Para cubrirlos necesitas el jail [recidive], que monitoriza los propios logs de Fail2ban en busca de reincidencia:

sudo tee -a /etc/fail2ban/jail.local > /dev/null <<'EOF'
[recidive]
enabled  = true
filter   = recidive
logpath  = /var/log/fail2ban.log
bantime  = 1w
findtime = 1d
maxretry = 5
action   = %(action_mwl)s
EOF
sudo systemctl restart fail2ban

Con esta regla, un host que sea baneado cinco veces en un día por cualquier otro jail queda bloqueado durante una semana completa y, con la acción action_mwl, además te llega un correo con whois y logs relevantes. Es el equivalente Fail2ban del baneo progresivo de CrowdSec, sin abandonar el proyecto original.

Para servidores expuestos a internet en LATAM y Europa, este jail por sí solo reduce un orden de magnitud el número de intentos que llegan a tu servidor SSH real cada día, porque los bots rápidos se queman a las pocas direcciones y caen en recidive antes de encontrar una contraseña válida.

La combinación mínima razonable en un servidor expuesto a internet se resume así:

Jail Filtro maxretry findtime bantime
sshd Intentos de autenticación fallidos 4 10m 24h
sshd-ddos Conexiones que no completan auth 5 10m 48h
recidive Reincidencia global sobre el log de Fail2ban 5 1d 1w

Notificaciones: correo, Telegram y registro estructurado

Fail2ban incluye acciones listas para casi cualquier canal. Las tres más útiles en 2026 son:

  • sendmail (por defecto en action_mwl): envía un correo cuando hay ban y unban. Configura el MTA en /etc/fail2ban/action.d/sendmail-common.conf.
  • Telegram: notifica a tu chat privado o grupo de sysadmins con el bot API. Edita /etc/fail2ban/action.d/telegram.conf con tu bot_token y chat_id.
  • syslog: deja que tu colector centralizado (Graylog, Loki, Elastic) ingiera los bans para alertas en Grafana.

Para Telegram, el bloque en jail.local se ve así:

sudo tee /etc/fail2ban/action.d/telegram.local > /dev/null <<'EOF'
[Definition]
actionban   = curl -sSf -X POST https://api.telegram.org/bot%(telegram_token)s/sendMessage -d chat_id=%(telegram_chat_id)s -d text='[Fail2ban] %(name)s ban: <ip>'
actioncheckockwolf = flash
EOF
# Luego en jail.local:
[sshd]
action = iptables-multiport[name=sshd, port="ssh", protocol=tcp]
         telegram[name=%(name)s, token="TOKEN:XXX", chat_id="-1001234567890"]

En cuanto entra un ban, te suena el móvil. Útil cuando quieres saber al instante si un operador legítimo se equivocó o si un atacante está probando tu servidor.

Casos reales: sshd-ddos y rotación de atacantes

Los filtros por defecto de Fail2ban capturan los intentos con Failed password, pero hay patrones más sutiles que merecen un filtro dedicado. Uno habitual es el «sshd-ddos», donde el atacante no llega a autenticarse: cierra la conexión TCP antes de enviar credenciales, consumiendo slots del daemon:

sudo tee /etc/fail2ban/filter.d/sshd-ddos.local > /dev/null <<'EOF'
[Definition]
failregex = ^.*Connection closed by authenticating user .* <HOST> port d+ [preauth]$
            ^.*Did not receive identification string from <HOST>$
            ^.*bad protocol version identification .* from <HOST>$
ignoreregex =
EOF

Y en jail.local activas el jail que lo usa:

sudo tee -a /etc/fail2ban/jail.local > /dev/null <<'EOF'
[sshd-ddos]
enabled  = true
filter   = sshd-ddos
logpath  = %(sshd_log)s
maxretry = 5
findtime = 10m
bantime  = 48h
EOF
sudo systemctl restart fail2ban

Esta capa adicional es lo que detiene a los escáneres tipo Shodan antes de que tu sshd desperdicie procesos atendiéndolos.

Monitoreo y operación diaria

Tres comandos cubren el 90 % de la operación del día a día:

# Estado global
sudo fail2ban-client status
# Estado de un jail concreto
sudo fail2ban-client status sshd
# Desbloquear un IP manualmente (útil cuando te bloqueas a ti mismo)
sudo fail2ban-client set sshd unbanip 203.0.113.42
# Añadir un IP a la lista de ignorados sin reiniciar
sudo fail2ban-client set sshd addignoreip 192.0.2.10

Para una vista rápida de los bans activos y los reincidentes, ejecuta sudo fail2ban-client status recidive: si ves decenas de direcciones con Currently banned: N significa que tu servidor está bajo un ataque distribuido. Lo habitual en servidores personales es ver entre 0 y 5 bans activos en sshd y entre 0 y 2 en recidive.

Si quieres llevar el monitoreo a Grafana, el truco estándar es parsear /var/log/fail2ban.log con Promtail o Filebeat y graficar la métrica «bans por hora por jail». La métrica más accionable es «bans en recidive»: si sube, tu servidor está en el radar de una botnet.

Cuándo Fail2ban no es suficiente

Fail2ban es excelente como primera capa, pero tiene límites honestos que conviene reconocer:

  • No escala a millones de direcciones IP: si tu servidor recibe intentos desde rangos enteros de datacenter, el matching de iptables empieza a resentirse. CrowdSec, con su blocklist comunitaria, maneja mejor ese volumen.
  • No protege contra credenciales filtradas: si un atacante tiene la contraseña correcta, Fail2ban no lo detecta. Por eso claves SSH ed25519 + 2FA siguen siendo obligatorios.
  • Depende de logs correctos: si tu rsyslog rota demasiado rápido, Fail2ban con backend = polling puede perder bans. backend = systemd lo arregla en la mayoría de distros modernas.

La defensa en profundidad razonable en 2026 combina Fail2ban + claves ed25519 + 2FA + nftables con política por defecto restrictiva. Ninguna herramienta sola cubre todo el espectro; Fail2ban es la pieza que pone el freno de mano cuando los bots empiezan a golpear la puerta.

Una comparativa rápida para decidirte:

Criterio Fail2ban CrowdSec
Curva de aprendizaje Baja — un archivo jail.local Media — agente + API + blocklists
Dependencia externa Ninguna Cuenta gratuita en crowdsec.net
Funciona offline Sí Parcial — degrada sin API
Blocklist compartida No Sí (comunitaria)
Backends firewall iptables, nftables, ipset, firewalld iptables, nftables, ipset, cloudflare, AWS

Conclusión

Fail2ban sigue siendo en 2026 la herramienta de cabecera para sysadmins Linux que quieren proteger SSH sin complicar la operativa. Es estable, está en repos oficiales de todas las distros, y su configuración por defecto ya detiene la mayoría del ruido automatizado. Si combinas el jail [sshd] con [recidive] y dejas un backend = systemd, tu servidor SSH pasa de recibir cientos de intentos diarios a apenas unos pocos. Y si más adelante necesitas escalar a una solución colaborativa, CrowdSec comparte el mismo modelo mental y la migración es directa.

Preguntas frecuentes

¿Por qué Protege tu SSH con Fail2ban: Guía Completa para Sysadmins Linux es relevante para sysadmins Linux?

Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.

¿Qué necesito para empezar con Protege tu SSH con Fail2ban:?

Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.

¿Cuáles son los errores más comunes con Protege tu SSH con Fail2ban:?

Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.

¿Cuándo usar Protege tu SSH con Fail2ban: y cuándo una alternativa?

Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.

¿Cómo migro desde una configuración previa a Protege tu SSH con Fail2ban:?

Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *