Seguridad

fail2ban + CrowdSec en 2026: defensa en capas para SSH y servicios web

Si tu servidor Linux todavía depende solo de fail2ban para defenderse del brute-force de SSH, o si está corriendo solo CrowdSec sin saber bien cómo combinarlo, este artículo es para ti. La defensa en capas con fail2ban + CrowdSec ya no es opcional en 2026: los ataques automatizados son más rápidos y distribuidos, y una sola capa deja huecos.

La idea es simple: fail2ban corta el ataque local en milisegundos con iptables, y CrowdSec aporta inteligencia comunitaria que comparte bloqueos entre miles de servidores. Juntos cubren dos problemas distintos — el ruido automatizado y los ataques dirigidos — con poco overhead.

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é una sola capa no alcanza en 2026

fail2ban es un sistema probado y liviano. Lee logs (sshd, nginx, postfix, etc.), detecta patrones y aplica bans via iptables/nftables localmente. Funciona excelente contra atacantes que repiten el mismo ataque desde una IP o un rango pequeño.

El problema es que los atacantes modernos rotan IPs en segundos, usan botnets distribuidas y combinan payloads. fail2ban ve cada IP una vez, la banea diez minutos, y a la siguiente conexión el atacante ya está en otra IP. Tu servidor sigue gastando ciclos en intentos fallidos.

CrowdSec resuelve el otro lado: es un motor de detección moderno (escrito en Go, lanzado en 2020) que comparte señales entre servidores miembros. Cuando un atacante te pega a tú, también le pegó a otros 1.000 servidores de la red comunitaria; si tú lo bloqueas, todos los demás lo bloquean automáticamente en minutos.

Pero CrowdSec por sí solo tiene una limitación: si el atacante te pega primero a tú (antes de que la red lo sepa), tu servidor sufre el intento igual hasta que la señal se propaga. Aquí es donde fail2ban vuelve a entrar: bloquea al instante local, mientras CrowdSec propaga y bloquea global.

Cómo se complementan en la práctica

El flujo típico de defensa en capas con ambas herramientas funciona así:

  • fail2ban detecta y banea localmente en segundos, basándose en reglas locales (intentos SSH fallidos, requests HTTP malformados, etc.). El ban se aplica vía iptables en el mismo servidor.
  • CrowdSec detecta patrones más complejos (credential stuffing distribuido, scraping agresivo, ataques a APIs) usando parsers compartidos, y publica la señal en su API comunitaria.
  • El bouncer local de CrowdSec (típicamente un firewall bouncer) consulta la API y aplica bans adicionales a nivel de nftables antes de que fail2ban siquiera termine de contar.

El resultado es que un atacante que rote IPs rápido cae igual: fail2ban lo banea por unos minutos, CrowdSec detecta el patrón y propaga, y el bouncer lo bloquea permanentemente mientras la señal esté activa en la comunidad.

Instalación paso a paso

Antes de empezar, asumimos Debian 12 o Ubuntu 24.04 con acceso root. Si usas otra distro los nombres de paquetes cambian pero la lógica es la misma.

1. Instalar fail2ban

fail2ban está en los repos oficiales de las dos distros más comunes:

sudo apt update
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban

El servicio queda corriendo pero con configuración por defecto. Vamos a personalizarla.

2. Configurar fail2ban con jail.local

La práctica correcta es crear jail.local en lugar de editar jail.conf directamente, así tus cambios sobreviven a upgrades del paquete:

sudo nano /etc/fail2ban/jail.local

Agregá una configuración base que endurece SSH sin ser agresiva con IPs legítimas:

[DEFAULT]
# Bantime inicial: 10 minutos. Lo subimos a 1h en el jail de SSH.
bantime = 10m
# Ventana de detección: contar intentos en los últimos 10 minutos.
findtime = 10m
# Máximo de intentos antes del ban.
maxretry = 5
[sshd]
enabled = true
port = ssh
filter = sshd
backend = systemd
maxretry = 4
findtime = 10m
bantime = 1h
# Opcional: notificar a un canal de Telegram o email
# action = iptables-multiport[name=sshd, port="ssh", protocol=tcp]

Reiniciamos fail2ban para que tome la nueva config:

sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

El último comando debe listar el jail sshd con 0 banned IPs actualmente. Si ves banned: 0, estás bien. Para monitorear en vivo:

sudo tail -f /var/log/fail2ban.log

3. Instalar CrowdSec

CrowdSec tiene su propio repositorio. Lo agregamos e instalamos:

# Agregar el repo oficial de CrowdSec
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
sudo apt install crowdsec -y

CrowdSec viene con un set de parsers y escenarios preconfigurados que cubren SSH, HTTP, y otros servicios comunes. Para activar el parser específico de SSH (que comparte señales con la red comunitaria):

sudo cscli parsers install crowdsecurity/sshd
sudo cscli scenarios install crowdsecurity/ssh-bf
sudo systemctl reload crowdsec

verifica que el agente está corriendo y reportando:

sudo systemctl status crowdsec
sudo cscli metrics

4. Instalar el bouncer (firewall)

CrowdSec detecta pero no bloquea por sí mismo: necesita un bouncer que aplique las decisiones. El más común para servidores Linux es el firewall bouncer que manipula nftables:

sudo apt install crowdsec-firewall-bouncer -y
sudo systemctl enable --now crowdsec-firewall-bouncer

El bouncer crea una cadena dedicada en nftables llamada CROWDSEC_CHAIN. verifica que esté activa:

sudo nft list chain inet crowdsec blackholes

Si todo está bien, vas a ver la cadena con una regla que redirige al set de IPs baneadas. Cuando CrowdSec reciba una decisión de ban, agregará la IP a ese set automáticamente.

Por qué no entran en conflicto

Una pregunta frecuente: si fail2ban y CrowdSec bouncer aplican iptables/nftables, ¿no se chocan? La respuesta corta es no, porque:

  • fail2ban y CrowdSec bouncer usan chains separadas en nftables. fail2ban trabaja en f2b-sshd, CrowdSec en CROWDSEC_CHAIN o equivalente según el bouncer.
  • Si una IP está baneada por ambos, el ban sigue siendo el mismo — no se duplican paquetes descartados, simplemente cae por la primera chain que matchea.
  • El orden de evaluación de chains en nftables es determinístico y no genera race conditions.

Para verificar que ambas capas están activas y no se superponen de forma problemática:

# Ver bans activos de fail2ban
sudo fail2ban-client status sshd
# Ver bans activos de CrowdSec
sudo cscli decisions list --all
# Ver chains de nftables relacionadas
sudo nft list ruleset | grep -E 'CROWDSEC|f2b'

Monitoreo y métricas

Una vez que ambas herramientas están corriendo, queremos ver qué está pasando. fail2ban tiene un comando directo para ver estadísticas del jail:

sudo fail2ban-client status sshd

El output muestra: total de IPs baneadas actualmente, total de bans históricos, y lista de las IPs baneadas. Útil para verificar que el sistema está reaccionando a intentos.

CrowdSec tiene un dashboard local opcional (web UI) pero la CLI es más práctica para servidores headless:

# Ver decisiones de ban activas
sudo cscli decisions list
# Ver alertas generadas
sudo cscli alerts list
# Ver el estado general del agente
sudo cscli hub status

El hub status confirma si tu servidor está compartiendo señales con la comunidad y si está recibiendo señales de otros miembros.

Troubleshooting común

fail2ban no banea después de muchos intentos

verifica que el backend sea correcto. En Debian/Ubuntu modernos con systemd, debe ser backend = systemd en jail.local. Si dice pyinotify o polling, fail2ban está intentando leer archivos de log directamente y puede no tener acceso.

CrowdSec no comparte señales

Si cscli hub status muestra not registered, tu servidor no está enrolado. necesitas una cuenta en app.crowdsec.net y ejecutar:

sudo cscli console enroll --instance-name <nombre>

Sin enrolamiento, el agente igual detecta localmente y aplica bans, pero no comparte con la comunidad. Sigue siendo útil, pero perdés la inteligencia colectiva.

Me baneé a mí mismo

Pasa más de lo que uno quisiera. Para desbanear:

# fail2ban
sudo fail2ban-client set sshd unbanip <tu_ip>
# CrowdSec
sudo cscli decisions delete --ip <tu_ip>
# También limpiar el bouncer
sudo cscli bouncers reload

Para evitar que se repita, agregá tu IP a ignoreip en jail.local de fail2ban y a la lista de IPs permitidas en la config del bouncer de CrowdSec.

Cuándo alcanza con solo una capa

No todo servidor necesita las dos. Si tu servidor:

  • Tiene SSH solo con clave pública y detrás de un firewall que limita el rate de intentos: fail2ban solo es probablemente suficiente. Sin password auth, el brute-force es ruido de log, no riesgo.
  • Está expuesto a internet con password auth habilitado: agregá CrowdSec sí o sí. Los botnets probarán combinaciones en segundos y fail2ban solo no da abasto.
  • Sirve aplicaciones web públicas: las dos. fail2ban para el SSH y patrones HTTP locales, CrowdSec para ataques distribuidos contra tus APIs y formularios de login.

Resumen

fail2ban + CrowdSec en capas es una de las configuraciones de defensa más accesibles y livianas que puedes tener en un servidor Linux en 2026. fail2ban solo te cubre ataques locales repetitivos, CrowdSec solo te cubre ataques distribuidos después de la primera detección — juntos te cubren ambos desde el primer intento.

Lo que recomendamos para la mayoría de servidores:

  • fail2ban con jail.local personalizado (bantime 1h en SSH, maxretry 4)
  • CrowdSec con el firewall bouncer y al menos los parsers de SSH y HTTP
  • Monitoreo semanal de cscli decisions list para ver qué está pasando
  • Si el servidor es crítico, agregar un bouncer de Cloudflare o nginx para protección en capa de aplicación

Si tienes dudas sobre tu setup particular o quieres que revisemos logs reales de tu servidor (anónimos), abre un hilo en los comentarios.

Preguntas frecuentes

¿Por qué fail2ban + CrowdSec en 2026: defensa en capas para SSH y servicios web 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 fail2ban + CrowdSec en 2026:?

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 fail2ban + CrowdSec en 2026:?

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 fail2ban + CrowdSec en 2026: 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 fail2ban + CrowdSec en 2026:?

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 *