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 filtrosshd.conf, incluido por defecto, sabe leerFailed password,Invalid useryConnection 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,nftablesoipset) 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.confcon tubot_tokenychat_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
iptablesempieza 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
rsyslogrota demasiado rápido, Fail2ban conbackend = pollingpuede perder bans.backend = systemdlo 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
- Guía Fedora 44: Novedades, Instalación y Upgrade para Sysadmins Linux
- Configura VLANs en Linux con nmcli: Guía paso a paso para sysadmins
- Protege tu SSH: Guía esencial para configurar Fail2ban en Linux
- Guía Definitiva: Configura Kubernetes con kubeadm en Ubuntu para Sysadmins Linux
- Configura Prometheus y Grafana: Guía DevOps para SysAdmins Linux
