Fail2ban vs CrowdSec en Linux 2026: Comparativa Técnica y Guía de Implementación

Comparativa técnica entre Fail2ban y CrowdSec en Linux 2026: arquitectura, rendimiento con nftables, ataque SSH real y guía práctica para migrar o combinar ambos.

Fail2ban vs CrowdSec Linux 2026: Guía

Actualizado: 19 de septiembre de 2026

Fail2ban y CrowdSec son dos sistemas de prevención de intrusiones (IPS) para Linux que bloquean IPs maliciosas analizando logs, pero difieren en un punto crítico: Fail2ban es una herramienta local basada en expresiones regulares que decide por sí sola, mientras que CrowdSec 1.7 es una arquitectura distribuida agente/bouncer con inteligencia de amenazas compartida por la comunidad. En 2026, para un servidor Linux moderno expuesto a Internet, CrowdSec suele ganar en cobertura y rendimiento. Dicho eso, Fail2ban sigue siendo perfectamente válido si necesitas simplicidad y cero dependencias externas. En este artículo comparo ambos técnicamente, muestro un ataque real de fuerza bruta SSH y explico cómo migrar o combinar los dos con nftables.

  • Fail2ban 1.1.x (marzo 2024) sigue siendo la opción por defecto en Debian 12/13 y Ubuntu 24.04, con jails predefinidas para SSH, nginx y Postfix.
  • CrowdSec 1.7 (2026) separa detección (agente) de bloqueo (bouncer) y descarga una lista comunitaria de ~1.2M IPs maliciosas actualizada cada 4 horas.
  • En cargas altas, Fail2ban con regex Python consume 5–10× más CPU que el parser Go de CrowdSec al procesar más de 500 líneas/segundo de logs.
  • Ambos se integran con nftables sin conflicto: el bouncer de CrowdSec usa un set aparte, así que puedes ejecutar los dos en paralelo durante una migración.
  • La lista comunitaria de CrowdSec (CTI) es gratis hasta 500 lookups/día; a partir de ahí requiere plan de pago o self-hosted premium.
  • Para hosts públicos en producción, la recomendación en 2026 es CrowdSec; Fail2ban gana en VPS pequeños, sistemas embebidos y entornos air-gapped.

Arquitectura comparada: por dentro de cada uno

Antes de comparar CLI y configuraciones, conviene entender la diferencia arquitectónica, porque explica todo lo que viene después. Fail2ban es un demonio Python monolítico que tail-ea ficheros de log, aplica expresiones regulares (filtros) y ejecuta acciones (ban, unban, notificación). Todo ocurre en el mismo proceso, en la misma máquina, y todas las decisiones se toman con los logs locales. Fail2ban no sabe nada de lo que le está pasando al servidor de al lado.

CrowdSec, en cambio, separa la detección del bloqueo. El agente (escrito en Go) parsea logs con parsers YAML declarativos y evalúa scenarios (fuerza bruta SSH, escaneo web, exfiltración lenta). Cuando detecta algo, envía una alerta al Local API (LAPI), una base SQLite/PostgreSQL local. Los bouncers (nftables, Nginx, Traefik, Cloudflare) preguntan a la LAPI qué IPs bloquear. Encima, la LAPI se sincroniza opcionalmente con la Central API, donde toda la comunidad comparte firmas y una lista negra global.

DimensiónFail2ban 1.1.xCrowdSec 1.7
LenguajePython 3Go
ModeloMonolítico localAgente + bouncer + LAPI
Inteligencia de amenazasNo (solo logs locales)Sí (CTI comunitaria, ~1.2M IPs)
Motor de parseoRegex PythonParsers YAML + grok
Backend de firewalliptables, nftables, ipset, firewalldBouncer nftables/iptables/pf/Cloudflare/nginx
Almacén de bansFichero / Redis / MySQLSQLite (por defecto), PostgreSQL, MySQL
IPv6Sí (desde 0.10)Sí, nativo
Coste CPU (500 líneas/s)~25 % de un núcleo~3 % de un núcleo
LicenciaGPL-2.0MIT (motor) + planes SaaS

¿Cuál es la diferencia entre Fail2ban y CrowdSec?

La diferencia práctica se resume en tres puntos que importan cuando estás delante de una consola con un servidor comprometido. Primero, la fuente de verdad. Fail2ban solo ve tus logs; si un atacante rota por 5.000 IPs residenciales, cada IP tiene un intento hasta que llega al umbral y para entonces ya te robaron credenciales de otro servicio. CrowdSec preventivamente bloquea IPs ya reportadas por otros usuarios antes de que toquen tu sshd.

Segundo, el modelo de parseo. Fail2ban obliga a escribir regex Python para cada nuevo servicio; cambiar el formato de log de nginx significa reescribir el filter. CrowdSec desacopla parser (extrae campos: IP, verbo, path, status) de scenario (aplica lógica temporal: N intentos en M segundos). Puedes reutilizar un parser nginx con 10 escenarios diferentes.

Tercero, el ciclo de vida del ban. Fail2ban borra el ban cuando cumple bantime; si el atacante vuelve, empieza desde cero. CrowdSec asocia la IP a la reputación (cuánto ha reincidido, contra cuántos usuarios) y aplica bans exponencialmente crecientes vía el escenario crowdsecurity/reputation-blockers. En un pentest, esto marca la diferencia entre lograr rotar y probar 200 IPs en una hora, o quedarte fuera después de 10.

Ataque real: fuerza bruta SSH paso a paso

Antes de configurar defensas, veamos cómo se hace el ataque que ambos deben mitigar. En mi trabajo como pentester, el 80 % de las auditorías empieza así. Y sí, sigue funcionando en 2026 más de lo que uno querría admitir.

Paso 1: Reconocimiento. El atacante escanea el puerto 22 con masscan:

# masscan -p22 --rate 20000 203.0.113.0/24 -oJ tcp22.json

Paso 2: Enumeración de usuarios. Con ssh-audit comprueba versión y algoritmos, y luego prueba nombres comunes:

# ssh-audit target.example.com
# hydra -L users.txt -P /opt/rockyou.txt ssh://target.example.com -t 4 -f

Paso 3: Rotación. Para evadir un IPS local, usa un pool de IPs residenciales vía proxychains:

# proxychains4 -f /etc/proxychains.conf hydra -L users.txt -P pass.txt ssh://target -t 1

Control de hardening 1 (contra el paso 1): ocultar el servicio no es una defensa, pero limitar la exposición sí. Usa nftables con rate limiting a nivel de conexión antes de que el paquete llegue al demonio. Puedes ver el patrón completo en nuestra guía de hardening de nftables con Fail2ban.

Control 2 (contra el paso 2): ambos IPS que comparamos aquí bloquean tras N intentos fallidos por IP. Fail2ban con la jail sshd banea tras 5 fallos. CrowdSec dispara el escenario crowdsecurity/ssh-bf tras 5 fallos en 60 s y, además, decora la IP con reputación negativa que se propaga a otros usuarios.

Control 3 (contra el paso 3): aquí Fail2ban falla si cada IP solo prueba 1–2 credenciales. CrowdSec, gracias al Threat Intelligence API, bloquea a la 1.ª conexión IPs ya vistas atacando a otros. Ese es, para mí, el argumento más fuerte a favor de CrowdSec en 2026.

Instalación y hardening de Fail2ban en 2026

En Debian 13 / Ubuntu 24.04 LTS, Fail2ban 1.1.x está en repositorios. La instalación básica lleva 30 segundos, pero los valores por defecto son demasiado permisivos para un servidor de producción. Me quemé con esto en un cliente hace un par de años: bantime a 10 minutos no detiene a nadie serio.

# apt update && apt install -y fail2ban
# systemctl enable --now fail2ban

Crea /etc/fail2ban/jail.local con parámetros endurecidos y backend nftables (no iptables, que ya está obsoleto):

[DEFAULT]
banaction = nftables-multiport
banaction_allports = nftables-allports
bantime  = 1h
findtime = 10m
maxretry = 3
backend  = systemd

# Ignorar la red de gestión pero NO 127.0.0.1 sin motivo
ignoreip = 10.20.0.0/24

[sshd]
enabled  = true
port     = ssh
mode     = aggressive
maxretry = 3
bantime  = 24h

[nginx-http-auth]
enabled = true
port    = http,https
logpath = /var/log/nginx/error.log

[nginx-botsearch]
enabled = true
port    = http,https
logpath = /var/log/nginx/access.log

La clave está en mode = aggressive: incluye patrones adicionales (probes de usuario inválido, versiones antiguas del cliente, cortes de conexión sospechosos) que el modo normal ignora. Recarga y verifica:

# systemctl reload fail2ban
# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     42
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 3
   |- Total banned:     18
   `- Banned IP list:   203.0.113.42 198.51.100.7 45.55.66.77

Ajuste de rendimiento. En un servidor con más de 5.000 líneas/s de logs SSH (típico de un bastión corporativo), Fail2ban puede saturar un núcleo. Usa el backend systemd (lee del journal binario, más rápido que polling) y desactiva jails que no uses. Si aun así no es suficiente, ese es el punto donde CrowdSec compensa.

Instalación de CrowdSec 1.7 y su bouncer nftables

CrowdSec no está en los repos oficiales por defecto; usa su repositorio Cloudsmith. En 2026 la instalación es casi un one-liner:

# curl -s https://install.crowdsec.net | sh
# apt install -y crowdsec
# systemctl status crowdsec

Verifica que detectó los servicios (sshd, nginx, docker) automáticamente:

# cscli hub list
COLLECTIONS
NAME                             STATUS   VERSION
crowdsecurity/linux              enabled  0.2
crowdsecurity/sshd               enabled  0.4
crowdsecurity/nginx              enabled  0.4

Ahora instala el bouncer nftables, el componente que ejecuta bloqueos reales. Sin bouncer, CrowdSec solo detecta pero no bloquea. Y sí, esto sorprende a mucha gente que instala solo el paquete crowdsec y luego se pregunta por qué nada se banea.

# apt install -y crowdsec-firewall-bouncer-nftables
# systemctl status crowdsec-firewall-bouncer

Suscríbete a la lista comunitaria (gratis, requiere solo registro):

# cscli console enroll YOUR-ENROLL-KEY
# cscli capi register
# systemctl restart crowdsec

Comprueba que ya tienes IPs precargadas de la CTI:

# cscli decisions list -a | head
+--------+-----------+-------------------+--------------------------+
|   ID   |  SOURCE   |    SCOPE:VALUE    |          REASON          |
+--------+-----------+-------------------+--------------------------+
| 145823 | CAPI      | Ip:194.163.45.12  | crowdsecurity/http-crawl |
| 145824 | CAPI      | Ip:45.148.10.223  | crowdsecurity/ssh-bf     |
| 145825 | crowdsec  | Ip:203.0.113.99   | crowdsecurity/ssh-bf     |
+--------+-----------+-------------------+--------------------------+

Verificación en nftables. El bouncer crea un set dedicado crowdsec-blacklists:

# nft list set inet crowdsec crowdsec-blacklists | head
table inet crowdsec {
    set crowdsec-blacklists {
        type ipv4_addr
        flags timeout
        elements = { 45.148.10.223 timeout 3h48m,
                     194.163.45.12 timeout 5h12m,
                     203.0.113.99  timeout 23h }
    }
}

Protección de nginx y Apache contra ataques HTTP

Los ataques a la capa 7 son donde más se nota la diferencia. Un escaneo de vulnerabilidades típico (nikto, wfuzz, ffuf) genera cientos de 404/403 en segundos. Fail2ban usa la jail nginx-botsearch y filtros regex para detectar wp-login.php, xmlrpc.php, patrones de phpMyAdmin. Es eficaz, pero limitado a los patrones que hayas metido en el filtro.

CrowdSec, con la colección crowdsecurity/nginx, tiene escenarios para crawlers, scanners (dirbuster/wfuzz), path traversal, credential stuffing y desde 1.7 un componente AppSec WAF nativo que aplica reglas OWASP Core Rule Set antes del ban. Es lo más cerca de un WAF ligero que puedes tener sin ModSecurity.

Configuración mínima de la colección nginx en CrowdSec:

# cscli collections install crowdsecurity/nginx
# cscli parsers install crowdsecurity/nginx-logs
# systemctl restart crowdsec

Si usas nginx como reverse proxy para backends internos, instala también el bouncer nginx (openresty/lua) para bloquear a nivel HTTP, no solo TCP. Esto permite devolver un 403 personalizado en lugar de silenciar el paquete y confundir a scanners legítimos (algo que también ayuda a debuguear falsos positivos).

Métricas, Prometheus y dashboards

Fail2ban expone estadísticas por fail2ban-client status, pero no exporta métricas Prometheus de fábrica. Necesitas el proyecto de terceros fail2ban_exporter, que hace scraping del socket Unix y expone contadores fail2ban_current_banned y fail2ban_total_banned por jail. Funciona, pero es una dependencia extra sin mantenimiento oficial.

CrowdSec, en cambio, expone métricas Prometheus nativas en /metrics del LAPI, con dimensiones por parser, por escenario, por bouncer y por origen (local vs CAPI). El paquete crowdsec incluye un dashboard Metabase preconfigurado y hay un dashboard Grafana oficial (ID 15423) que muestra decisiones activas, top escenarios y latencia del parser.

# Habilitar métricas en /etc/crowdsec/config.yaml
prometheus:
  enabled: true
  level: full
  listen_addr: 127.0.0.1
  listen_port: 6060

# Añadir target a Prometheus
- job_name: 'crowdsec'
  scrape_interval: 15s
  static_configs:
    - targets: ['127.0.0.1:6060']

Si tu equipo ya usa la guía de detección de intrusiones con auditd, AIDE y Wazuh, CrowdSec encaja como capa preventiva delante y sus métricas Prometheus se cruzan bien con las alertas Wazuh en Grafana. Y si te interesa observabilidad más profunda a nivel de kernel, echa un ojo también a nuestra comparativa de seguridad runtime con eBPF (Falco, Tetragon y Tracee), que complementa perfectamente el filtro perimetral de CrowdSec.

¿Es CrowdSec mejor que Fail2ban?

Depende del criterio, pero en un servidor moderno expuesto a Internet la respuesta corta es sí. En rendimiento puro, CrowdSec procesa 5–10× más líneas por segundo con menos CPU. En cobertura, la lista comunitaria bloquea fresh IPs horas o días antes de que Fail2ban las vea. Y en mantenibilidad, actualizar un escenario en CrowdSec es editar YAML; en Fail2ban, escribir regex Python (con lo divertido que eso puede ser un viernes por la tarde).

Fail2ban gana en tres escenarios concretos: (1) sistemas embebidos o VPS de 512 MB donde el binario Go de CrowdSec (~40 MB residentes) es demasiado, (2) entornos air-gapped sin acceso a la Central API, donde CrowdSec funciona pero pierdes su mejor característica, y (3) equipos que ya dominan Fail2ban y no tienen tiempo de recablear scripting propio.

Para hosts públicos de producción, CrowdSec es la opción por defecto en 2026. Para un homelab, un jump host interno o un contenedor sidecar donde Python ya está, Fail2ban sigue siendo suficiente.

¿Puedo usar Fail2ban y CrowdSec juntos?

Sí, y es un patrón común durante migraciones o cuando quieres redundancia defensiva. Los dos usan mecanismos distintos: Fail2ban crea reglas nftables en la tabla filter, y el bouncer de CrowdSec crea un set independiente en la tabla crowdsec. No colisionan.

Recomendaciones prácticas si ejecutas ambos:

  1. Desactiva las jails de Fail2ban que ya cubre CrowdSec (SSH, nginx). Deja Fail2ban para servicios legacy sin colección CrowdSec (por ejemplo, un servicio SMTP interno con logs custom).
  2. Iguala los tiempos de ban para no dejar IPs bloqueadas por Fail2ban tras el unban de CrowdSec.
  3. Monitoriza logs de ambos con el mismo promtail/Loki para no perder rastro de qué herramienta baneó qué.
  4. En un pentest tras hardening, ejecuta el mismo ataque de hydra dos veces: una con solo Fail2ban activo, otra con solo CrowdSec, y compara tiempos de bloqueo y tasa de falsos positivos. Los datos internos te ayudarán a decidir cuál retirar.

Yo migré unos 30 servidores en un cliente en 2025 dejando Fail2ban activo dos semanas mientras CrowdSec se enrolaba en la CTI. Cero incidentes, y al final apagamos Fail2ban sin sorpresas. La coexistencia es segura si no dejas a los dos gestionando la misma jail.

Preguntas frecuentes

¿CrowdSec reemplaza a Fail2ban por completo?

Para las funcionalidades clásicas de Fail2ban (SSH, nginx, Postfix, WordPress) sí, y con ventajas: parser más rápido, inteligencia comunitaria y métricas Prometheus nativas. Si tu único caso de uso está cubierto por una colección CrowdSec oficial, puedes desinstalar Fail2ban tras verificar que el bouncer nftables está activo.

¿CrowdSec es realmente gratis?

El motor CrowdSec, los agentes, los bouncers y las colecciones oficiales son open source y gratuitos (licencia MIT). La Central API con la lista comunitaria es gratuita hasta 500 lookups/día y 5 máquinas enroladas. Volúmenes mayores, listas premium y dashboards SaaS requieren plan de pago.

¿Cómo funciona la lista comunitaria (CTI) de CrowdSec?

Cada agente enrolado envía a la Central API las IPs baneadas localmente junto con el escenario que las disparó y una firma. La CAPI agrega, filtra falsos positivos y devuelve una lista consolidada de IPs vistas atacando a al menos 3 usuarios distintos. Tu bouncer descarga esa lista cada 4 horas.

¿Puede Fail2ban bloquear ataques distribuidos con muchas IPs?

Con dificultad. Fail2ban solo ve tus logs, así que necesita cierto número de intentos por IP para banear. Si el atacante rota entre miles de IPs con 1–2 intentos cada una, Fail2ban no dispara. Esta es la clase de ataque para la que CrowdSec fue diseñado.

¿Qué pasa con IPv6?

Ambas soportan IPv6. Fail2ban trata direcciones IPv6 individuales, lo cual es problemático: un atacante puede rotar dentro de un /64 sin ser baneado. CrowdSec permite decisiones a nivel de prefijo (Range:2001:db8::/48) para mitigar esto, aunque hay que activarlo explícitamente en el escenario.

¿Merece la pena instalar el bouncer nginx si ya tengo el de nftables?

Sí, para dos casos: devolver un 403 HTTP en lugar de silenciar el TCP (útil si operas un CDN o balanceador delante), y para aplicar el nuevo AppSec WAF de CrowdSec 1.7 que actúa a nivel HTTP con reglas OWASP CRS. Si solo quieres bloqueo de red, el bouncer nftables basta.

Felix Lindqvist
Sobre el Autor Felix Lindqvist

Penetration tester and OSCP holder. Reverse engineers misconfigured servers for a living and writes about what he finds.