Files
2026-07-25 11:20:27 +00:00

14 KiB

CrowdSec - Sistema de Seguridad y Prevención de Intrusiones

CrowdSec es un IPS/IDS colaborativo que analiza logs, detecta comportamientos maliciosos y bloquea atacantes en tiempo real. Usa inteligencia comunitaria para compartir reputación de IPs entre todos los usuarios.

📋 Descripción

Este stack despliega:

  • CrowdSec Engine: Motor de detección que analiza logs de Traefik y otros contenedores
  • CrowdSec Bouncer (Traefik Plugin): Middleware que bloquea IPs maliciosas a nivel HTTP (L7)
  • Grafana: Dashboard web para visualizar alertas, decisiones y métricas (protegido con Authentik)
  • Baneos automáticos contra ataques de fuerza bruta, escaneos, CVEs conocidos y más

🚀 Despliegue

Prerequisitos

  1. Red Docker: La red proxy debe existir

    docker network create proxy
    
  2. Registro DNS: Configura el registro A para el dashboard

    • grafana.tudominio.com → IP del servidor
  3. Directorios: Créalos automáticamente con el setup:

    cd crowdsec && ./setup.sh
    

Paso 1: Configurar variables de entorno

Edita el .env local con las variables reales:

nano crowdsec/.env

Variables críticas:

# Clave API del bouncer (generada automáticamente por setup.sh o pon una manual)
CROWDSEC_BOUNCER_API_KEY=tu-key-de-64-caracteres

# Dominio del dashboard Grafana
CROWDSEC_GRAFANA_DOMAIN=grafana.tudominio.com

# Colecciones a instalar
CROWDSEC_COLLECTIONS=crowdsecurity/traefik

# Rutas de datos
CROWDSEC_CONFIG_PATH=/opt/crowdsec/config
CROWDSEC_DATA_PATH=/opt/crowdsec/data
TRAEFIK_LOG_PATH=/opt/traefik/logs

Paso 2: Ejecutar el script de setup

cd crowdsec
./setup.sh

El script:

  1. Genera una clave aleatoria para el bouncer (si no está definida)
  2. Crea los directorios necesarios en /opt/crowdsec/ y /opt/traefik/logs
  3. Genera la configuración dinámica de Traefik (crowdsec-bouncer.yml)
  4. Crea los archivos acquis.yaml para leer logs de Traefik y Docker
  5. Aplica contextos SELinux si es necesario

Paso 3: (Re)desplegar Traefik

Importante: Traefik necesita reiniciarse para cargar el plugin de CrowdSec y los nuevos volúmenes.

Actualiza el archivo .env de Traefik para incluir TRAEFIK_LOG_DIR=/opt/traefik/logs y redespliega:

cd Traefik
docker compose --env-file .env up -d

Paso 4: Desplegar CrowdSec

cd crowdsec
docker compose --env-file .env up -d

Paso 5: Verificar el despliegue

# Ver contenedores
docker ps | grep crowdsec

# Ver logs del engine
docker logs crowdsec

# Verificar decisiones activas
docker exec crowdsec cscli decisions list

# Verificar métricas
docker exec crowdsec cscli metrics

# Verificar estado del bouncer
docker exec crowdsec cscli bouncers list

🔐 Configurar Authentik para el Dashboard (Grafana)

El dashboard de Grafana (grafana.tudominio.com) está protegido con ths-authentik@docker. Para que funcione:

En el panel de Authentik:

  1. Crear Proxy Provider:

    • Ve a ApplicationsProvidersCreate
    • Tipo: Proxy Provider
    • Name: CrowdSec Grafana
    • External host: https://grafana.tudominio.com
    • Authentication flow: default-authentication-flow
    • Authorization flow: default-provider-authorization-implicit-consent
    • Mode: Forward auth (single application)
  2. Crear Application:

    • Ve a ApplicationsCreate
    • Name: CrowdSec Grafana
    • Slug: grafana
    • Provider: selecciona el creado en paso 1
    • UI Settings: opcional (icono, descripción)
  3. Asociar al Embedded Outpost:

    • Ve a Outpostsauthentik Embedded OutpostEdit
    • Asegúrate de que la aplicación CrowdSec Grafana está seleccionada
    • Haz clic en Update

El middleware ths-authentik@docker ya está configurado en las labels del servicio crowdsec-grafana. Si otros stacks también lo usan, comparte la misma configuración de Authentik.

🛡️ Proteger servicios con CrowdSec

Método 1: Middleware global (recomendado)

Añade el middleware crowdsec-bouncer@file a los routers de Traefik que quieras proteger:

labels:
  # ... labels existentes ...
  traefik.http.routers.mi-app.middlewares: "ths-authentik@docker,crowdsec-bouncer@file"

Importante: los middlewares se encadenan en orden. crowdsec-bouncer primero bloquea IPs maliciosas, luego ths-authentik autentica.

Método 2: Solo CrowdSec (sin Authentik)

Para servicios que no requieren login pero sí protección anti-ataques (ej: APIs):

labels:
  traefik.http.routers.mi-api.middlewares: "crowdsec-bouncer@file"

Lista de servicios recomendados para proteger

Prioridad Servicio Motivo
Alta Traefik Dashboard Expuesto, blanco de escaneos
Alta Authentik Puerta de entrada SSO, blanco de brute force
Alta Gitea Expuesto a clonaciones maliciosas
Media n8n Webhooks públicos, riesgo de SSRF
Media Nextcloud Login expuesto, brute force
Media Homepage Aunque es solo dashboard, expuesto

🔍 Comandos útiles

Ver estado de CrowdSec

# Estadísticas generales
docker exec crowdsec cscli metrics

# Decisiones activas (baneos)
docker exec crowdsec cscli decisions list

# Alertas recientes
docker exec crowdsec cscli alerts list --limit 20

# Inspeccionar una IP específica
docker exec crowdsec cscli decisions inspect --ip 1.2.3.4

# Ver bouncers registrados
docker exec crowdsec cscli bouncers list

Gestión de decisiones

# Banear una IP manualmente (1 hora)
docker exec crowdsec cscli decisions add --ip 1.2.3.4 --duration 1h --reason "manual"

# Desbanear una IP
docker exec crowdsec cscli decisions delete --ip 1.2.3.4

# Listar escenarios activos
docker exec crowdsec cscli scenarios list

Allowlists (IPs que nunca se banean)

Usar cscli allowlists (disponible desde CrowdSec v1.6+) en lugar del antiguo truco de decisions add --duration 99999h. Las allowlists son permanentes y sobreviven a reinicios.

# Crear una allowlist nueva
docker exec crowdsec cscli allowlists create <nombre> -d "Descripción"

# Añadir una IP o CIDR a una allowlist
docker exec crowdsec cscli allowlists add <nombre> <ip-o-cidr>

# Quitar una IP de una allowlist
docker exec crowdsec cscli allowlists remove <nombre> <ip-o-cidr>

# Listar todas las allowlists y su contenido
docker exec crowdsec cscli allowlists list
docker exec crowdsec cscli allowlists inspect <nombre>

Allowlists configuradas en este servidor

Allowlist Contenido Propósito
vpn-local 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 10.8.0.0/24 Redes privadas y WireGuard VPN
cloudflare Todos los rangos IPv4 de Cloudflare Tráfico legítimo de Cloudflare (si se usa Cloudflare Tunnel)
telegram-bot IPs añadidas dinámicamente con /allow <ip> IPs gestionadas por el bot de Telegram

Para recrearlas desde cero:

# vpn-local
docker exec crowdsec cscli allowlists create vpn-local -d "Redes privadas y VPN"
docker exec crowdsec cscli allowlists add vpn-local 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 10.8.0.0/24

# cloudflare
docker exec crowdsec cscli allowlists create cloudflare -d "Rangos IPv4 de Cloudflare"
docker exec crowdsec cscli allowlists add cloudflare \
  173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 \
  141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 \
  197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 \
  104.24.0.0/14 172.64.0.0/13 131.0.72.0/22

# telegram-bot (vacía, el bot la gestiona)
docker exec crowdsec cscli allowlists create telegram-bot -d "IPs allowlisteadas via bot de Telegram"

Actualizar la blocklist comunitaria

# Actualizar manualmente
docker exec crowdsec cscli hub update

# Ver si hay actualizaciones pendientes
docker exec crowdsec cscli hub list

⚙️ Configuración adicional

Añadir más colecciones

Edita crowdsec/.env y añade colecciones separadas por coma:

CROWDSEC_COLLECTIONS=crowdsecurity/traefik,crowdsecurity/http-cve,crowdsecurity/whitelist-good-actors

Luego redeploya el stack. Colecciones recomendadas:

Colección Descripción
crowdsecurity/traefik Parsea logs de acceso de Traefik
crowdsecurity/http-cve Detecta intentos de explotación de CVEs HTTP
crowdsecurity/whitelist-good-actors Whitelist de servicios legítimos (Google, CloudFlare, etc.)
crowdsecurity/nginx Escenarios extra para servidores web
crowdsecurity/base-http-scenarios Escaneos básicos HTTP (path traversal, SQLi, etc.)

Configurar whitelist de IPs locales

Para que CrowdSec no banee IPs de tu red local/VPN, edita /opt/crowdsec/config/parsers/s02-enrich/whitelists.yaml:

docker exec crowdsec cscli parsers install crowdsecurity/whitelists

O añade manualmente en notifications/http.yaml el parámetro whitelist_ips.

Añadir adquisición de logs adicionales

Edita /opt/crowdsec/config/acquis.yaml para añadir fuentes de log adicionales:

---
# Logs de Traefik (ya configurado)
source: file
filenames:
  - /var/log/traefik/access.log
labels:
  type: traefik

# Logs de Authentik (ejemplo adicional)
# source: docker
# container_name:
#   - ths-authentik-server
# labels:
#   type: authentik

🤖 Integración con el bot de Telegram

El bot f2b-telegram-bot (en /home/felidae/f2b-telegram-bot/) gestiona fail2ban, firewalld y CrowdSec de forma unificada. El comando /allow <ip> ejecuta en una sola operación:

  1. Añade la IP a la allowlist persistente del bot
  2. Sincroniza ignoreip en fail2ban
  3. Permite la IP en firewalld (ipset)
  4. Elimina cualquier decisión activa en CrowdSec (cscli decisions delete)
  5. Añade la IP a la allowlist telegram-bot en CrowdSec (nunca volverá a banearse)

Comandos relevantes del bot

Comando Efecto en CrowdSec
/allow <ip> Unban + añade a allowlist telegram-bot
/unallow <ip> Quita de allowlist telegram-bot
/unban <ip> Solo unban (sin añadir a allowlist)
/health Muestra estado de LAPI + disponibilidad Docker

Problema CGNAT y mitigación

Si el servidor está en una red sin IP fija o compartida (CGNAT), un atacante en la misma red puede provocar que tu IP legítima quede baneada por CrowdSec. La mitigación implementada:

  1. Bot de Telegram: /allow <ip> desbanea y allowlistea de inmediato en fail2ban + firewalld + CrowdSec.
  2. WireGuard VPN: Acceso por 10.8.0.0/24, en la allowlist vpn-local → nunca baneada.
  3. Cloudflare Tunnel (opcional, ver cloudflared/README.md): elimina el problema de raíz al ocultar la IP real del servidor.

Configuración del bot para CrowdSec

Variables de entorno relevantes en .env del bot:

CROWDSEC_ENABLED=true
CROWDSEC_ALLOWLIST_NAME=telegram-bot

Requiere que el bot se ejecute en el mismo host que el contenedor crowdsec (acceso a docker exec).


🔒 Seguridad

  • API local solo en loopback: La API de CrowdSec (cscli lapi) solo escucha en 127.0.0.1:8080
  • Bouncer integrado en Traefik: No expone puertos adicionales, todo el filtrado ocurre dentro de Traefik
  • Dashboard protegido por Authentik: Grafana requiere autenticación SSO previa
  • Motor con capacidades mínimas: Solo NET_BIND_SERVICE, sin CAP_SYS_ADMIN ni privilegios elevados
  • SELinux: Volúmenes con contexto :Z para entornos con SELinux habilitado
  • Key del bouncer: Generada aleatoriamente y almacenada solo en .env (gitignorado)

🛠️ Troubleshooting

El bouncer no bloquea

  1. Verifica que el plugin está cargado en Traefik:

    docker logs traefik | grep crowdsec
    
  2. Verifica que el middleware está configurado:

    docker exec traefik wget -qO- http://localhost:8080/api/http/middlewares | grep crowdsec
    
  3. Verifica que CrowdSec tiene decisiones activas:

    docker exec crowdsec cscli decisions list
    
  4. Comprueba conectividad entre Traefik y CrowdSec:

    docker exec traefik wget -qO- http://crowdsec:8080/v1/heartbeat
    

CrowdSec no detecta ataques

  1. Verifica que los logs de Traefik se están generando:

    ls -lh /opt/traefik/logs/access.log
    tail -f /opt/traefik/logs/access.log
    
  2. Verifica el acquis de CrowdSec:

    docker exec crowdsec cat /etc/crowdsec/acquis.yaml
    
  3. Revisa los logs del engine:

    docker logs -f crowdsec
    
  4. Simula un ataque de prueba:

    curl -H "User-Agent: Nikto" https://tu-dominio.com/
    docker exec crowdsec cscli decisions list
    

El dashboard pide login pero Authentik no redirige

  1. Verifica que el middleware está correctamente referenciado en las labels:

    docker inspect crowdsec-grafana | grep -A 20 Labels
    
  2. Revisa que la aplicación existe en Authentik y está asociada al Embedded Outpost

  3. Comprueba los logs de Authentik:

    docker logs ths-authentik-server
    

💾 Backups

Incluye en tus backups de Kopia (ya configurados en backups/kopia/):

# Datos de CrowdSec (decisiones, bouncers, config)
/opt/crowdsec/data/

# Configuración personalizada
/opt/crowdsec/config/

🔄 Actualizaciones

Para actualizar CrowdSec:

  1. Edita .env y actualiza la versión si es necesario:
    CROWDSEC_IMAGE=crowdsecurity/crowdsec:latest
    GRAFANA_IMAGE=grafana/grafana:latest
    
  2. Redespiega:
    cd crowdsec
    docker compose --env-file .env pull
    docker compose --env-file .env up -d
    

⚠️ Antes de actualizar versiones mayores de CrowdSec, revisa el changelog.

📚 Recursos