CrowdSec con Bouncers de Traefik y Nginx

CrowdSec es un sistema de seguridad colaborativo de código abierto que analiza logs en tiempo real para detectar comportamientos maliciosos y comparte esa inteligencia con la comunidad, mientras los bouncers aplican las decisiones de bloqueo en el punto de entrada de la red. Integrarlo con Traefik y Nginx permite bloquear IPs maliciosas antes de que las peticiones lleguen a tus aplicaciones, con una base de datos de reputación alimentada por millones de servidores en todo el mundo. Esta guía cubre la instalación y configuración completa de CrowdSec con ambos proxies.

Requisitos Previos

  • Ubuntu 20.04/22.04 o Debian 11/12
  • Nginx o Traefik instalado y en funcionamiento
  • Acceso root
  • Cuenta en CrowdSec (para sincronización de inteligencia de amenazas)

Instalación de CrowdSec

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

# Instalar CrowdSec
sudo apt-get install -y crowdsec

# Verificar que el servicio está corriendo
sudo systemctl status crowdsec

# Ver el estado general de CrowdSec
sudo cscli version
sudo cscli machines list

# Registrar el servidor en CrowdSec (para acceder a la lista de IPs maliciosas)
sudo cscli capi register

# Ver las alertas activas
sudo cscli alerts list

Instalar la CLI de CrowdSec

# cscli ya viene incluido con CrowdSec
# Verificar que está disponible
cscli --version

# Actualizar las hub collections y los parsers
sudo cscli hub update
sudo cscli hub upgrade

Configuración de Colecciones y Escenarios

Las colecciones son paquetes de parsers y escenarios prediseñados para diferentes aplicaciones:

# Ver colecciones instaladas
sudo cscli collections list

# Instalar colecciones para los servicios más comunes
sudo cscli collections install \
    crowdsecurity/nginx \
    crowdsecurity/traefik \
    crowdsecurity/linux \
    crowdsecurity/sshd \
    crowdsecurity/wordpress \
    crowdsecurity/http-cve

# Instalar parsers adicionales
sudo cscli parsers install crowdsecurity/geoip-enrich

# Ver escenarios activos (qué comportamientos detecta)
sudo cscli scenarios list

# Ver parsers instalados (cómo lee los logs)
sudo cscli parsers list

Configurar las fuentes de logs

# Ver la configuración de adquisición de logs
cat /etc/crowdsec/acquis.yaml

# Configuración de ejemplo para Nginx y Traefik
cat > /etc/crowdsec/acquis.d/nginx.yaml << 'EOF'
---
filenames:
  - /var/log/nginx/access.log
  - /var/log/nginx/error.log
labels:
  type: nginx
EOF

cat > /etc/crowdsec/acquis.d/traefik.yaml << 'EOF'
---
filenames:
  - /var/log/traefik/access.log
labels:
  type: traefik
EOF

# Reiniciar CrowdSec para aplicar cambios
sudo systemctl restart crowdsec

# Verificar que los logs se están leyendo correctamente
sudo cscli metrics | grep -A 10 "Acquisition"

Bouncer para Nginx

El bouncer de Nginx bloquea las IPs maliciosas directamente en el nivel del servidor web:

# Instalar el bouncer de Nginx para CrowdSec
sudo apt-get install -y crowdsec-nginx-bouncer

# Verificar la instalación del bouncer
sudo cscli bouncers list

# La configuración del bouncer está en:
cat /etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf

Configuración del bouncer de Nginx

# /etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf
API_URL=http://localhost:8080
API_KEY=TU_API_KEY_AQUI  # Se genera automáticamente durante la instalación
MODE=live
# Agregar la configuración del bouncer al nginx.conf
# El bouncer crea automáticamente /etc/nginx/conf.d/crowdsec.conf
cat /etc/nginx/conf.d/crowdsec.conf

# Contenido típico generado:
# lua_package_path '/usr/lib/crowdsec/lua/plugins/?.lua;;';
# lua_shared_dict crowdsec_cache 50m;
# init_by_lua_block { ... }
# En tu virtualhost de Nginx, agregar la verificación de CrowdSec:
server {
    listen 443 ssl http2;
    server_name tudominio.com;

    # Incluir la verificación de CrowdSec
    include /etc/nginx/conf.d/crowdsec.conf;

    location / {
        # El bouncer intercepta la petición antes de este punto
        access_by_lua_block {
            local cs = require "crowdsec"
            cs.check()
        }
        
        proxy_pass http://localhost:3000;
    }
}
# Verificar la configuración de Nginx
sudo nginx -t

# Reiniciar Nginx
sudo systemctl restart nginx

# Probar que el bouncer funciona (añadir una IP manualmente y probar)
sudo cscli decisions add --ip 1.2.3.4 --duration 1m --reason "prueba de bloqueo"
curl -I http://1.2.3.4  # Si accedes desde esa IP, verás un 403
sudo cscli decisions delete --ip 1.2.3.4

Bouncer para Traefik

El bouncer de Traefik funciona como middleware, verificando cada petición antes de pasarla al servicio backend:

# Para usar CrowdSec con Traefik, necesitas el bouncer de Traefik
# que se instala como plugin o como contenedor separado

# Opción 1: Traefik Bouncer como servicio separado (recomendado)

Docker Compose para CrowdSec + Traefik

# docker-compose.yml con CrowdSec y Traefik integrados
version: '3'

services:
  traefik:
    image: traefik:v3
    command:
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --certificatesresolvers.letsencrypt.acme.email=admin@tudominio.com
      - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
      # Activar access log para que CrowdSec pueda leerlo
      - --accesslog=true
      - --accesslog.filepath=/var/log/traefik/access.log
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt
      - traefik_logs:/var/log/traefik
    labels:
      # Aplicar el middleware de CrowdSec globalmente
      - traefik.http.middlewares.crowdsec-bouncer.forwardauth.address=http://crowdsec-bouncer:8080/api/v1/forwardAuth
      - traefik.http.middlewares.crowdsec-bouncer.forwardauth.trustForwardHeader=true

  crowdsec:
    image: crowdsecurity/crowdsec:latest
    environment:
      GID: "1000"
      COLLECTIONS: "crowdsecurity/traefik crowdsecurity/http-cve"
    volumes:
      - ./crowdsec/acquis.yaml:/etc/crowdsec/acquis.yaml:ro
      - crowdsec_db:/var/lib/crowdsec/data
      - traefik_logs:/var/log/traefik:ro
    restart: unless-stopped

  crowdsec-bouncer:
    image: fbonalair/traefik-crowdsec-bouncer:latest
    environment:
      CROWDSEC_BOUNCER_API_KEY: TU_API_KEY
      CROWDSEC_AGENT_HOST: crowdsec:8080
      GIN_MODE: release
    depends_on:
      - crowdsec
    restart: unless-stopped

  # Tu aplicación web con el middleware de CrowdSec aplicado
  mi-aplicacion:
    image: mi-app:latest
    labels:
      - traefik.enable=true
      - traefik.http.routers.mi-app.rule=Host(`app.tudominio.com`)
      - traefik.http.routers.mi-app.entrypoints=websecure
      - traefik.http.routers.mi-app.tls.certresolver=letsencrypt
      # Aplicar el middleware de CrowdSec a esta aplicación
      - traefik.http.routers.mi-app.middlewares=crowdsec-bouncer@docker

volumes:
  crowdsec_db:
  traefik_logs:
# Configurar la adquisición de logs de Traefik para CrowdSec
cat > ./crowdsec/acquis.yaml << 'EOF'
---
filenames:
  - /var/log/traefik/access.log
labels:
  type: traefik
EOF

# Generar la API Key para el bouncer
docker exec crowdsec cscli bouncers add traefik-bouncer

# Copiar la API Key generada y configurarla en el docker-compose.yml
# como valor de CROWDSEC_BOUNCER_API_KEY

docker compose up -d

Dashboard y Monitorización

# Ver las decisiones activas (IPs bloqueadas)
sudo cscli decisions list

# Ver las alertas de las últimas 24 horas
sudo cscli alerts list --since 24h

# Ver estadísticas detalladas
sudo cscli metrics

# Ver las métricas de bouncers
sudo cscli bouncers list

# Instalar el dashboard de CrowdSec (Metabase)
sudo cscli dashboard setup

# Acceder al dashboard en: http://localhost:3000
# Credenciales por defecto: [email protected] / !!Cr0wdS3c_M3t4b4s3??

# Monitorizar en tiempo real las decisiones
sudo cscli decisions list -o json | watch -n 5

Integrar con Prometheus

# CrowdSec expone métricas en formato Prometheus
# Endpoint: http://localhost:6060/metrics

# Verificar que las métricas están disponibles
curl http://localhost:6060/metrics | grep crowdsec

# Configurar en prometheus.yml:
# prometheus.yml - Agregar scrape config de CrowdSec
scrape_configs:
  - job_name: 'crowdsec'
    static_configs:
      - targets: ['localhost:6060']
    metrics_path: /metrics

Escenarios Personalizados

Puedes crear escenarios personalizados para detectar comportamientos específicos de tu aplicación:

# /etc/crowdsec/scenarios/mi-aplicacion-brute-force.yaml
type: leaky
name: mi-empresa/mi-aplicacion-brute-force
description: "Detectar fuerza bruta en el endpoint de login de mi aplicación"
filter: "evt.Meta.log_type == 'http_access-log' AND evt.Meta.http_path startsWith '/api/auth/login' AND evt.Meta.http_status == '401'"
groupby: "evt.Meta.source_ip"
capacity: 5
leakspeed: "10s"
blackhole: 1m
labels:
  service: mi-aplicacion
  confidence: 3
  spoofable: 0
  classification:
    - attack.T1110
# Cargar el escenario personalizado
sudo cscli scenarios install mi-empresa/mi-aplicacion-brute-force

# O copiar el archivo directamente
cp mi-aplicacion-brute-force.yaml /etc/crowdsec/scenarios/
sudo systemctl reload crowdsec

# Verificar que el escenario se cargó
sudo cscli scenarios list | grep mi-aplicacion

Solución de Problemas

CrowdSec no detecta ataques

# Verificar que los logs se están leyendo
sudo cscli metrics | grep -A 10 "Acquisition"
# La columna "Lines read" debe incrementar

# Probar un parser manualmente
sudo cscli explain --log '1.2.3.4 - - [15/Jan/2024:10:20:30 +0000] "GET /wp-login.php HTTP/1.1" 404 162' \
    --type nginx

# Ver los logs de CrowdSec para errores
sudo journalctl -u crowdsec -f

El bouncer no bloquea IPs

# Verificar que el bouncer está registrado
sudo cscli bouncers list

# Verificar la conectividad entre el bouncer y CrowdSec
curl http://localhost:8080/v1/decisions?ip=1.2.3.4

# Ver los logs del bouncer de Nginx
sudo tail -f /var/log/nginx/error.log | grep crowdsec

# Añadir una decisión de prueba y verificar
sudo cscli decisions add --ip 8.8.8.8 --duration 5m --reason "test"
curl -I https://tudominio.com  # Desde 8.8.8.8 debería dar 403
sudo cscli decisions delete --ip 8.8.8.8

Demasiados falsos positivos

# Agregar IPs o rangos a la lista blanca
sudo cscli whitelist add 192.168.0.0/24 "Red interna de la oficina"

# Crear un whitelist permanente
cat > /etc/crowdsec/parsers/s02-enrich/mis-whitelist.yaml << 'EOF'
name: mi-empresa/whitelist-ips
description: "IPs internas que no deben bloquearse"
whitelist:
  reason: "Redes internas"
  ip:
    - "192.168.0.0/24"
    - "10.0.0.0/8"
  cidr:
    - "172.16.0.0/12"
EOF

sudo systemctl reload crowdsec

Conclusión

CrowdSec con bouncers para Traefik y Nginx proporciona una capa de seguridad en tiempo real que combina la inteligencia colectiva de la comunidad con la detección basada en comportamiento para tu tráfico específico. A diferencia de las soluciones tradicionales de firewall, CrowdSec puede detectar ataques sofisticados distribuidos en múltiples IPs y adaptarse a los patrones de tu aplicación mediante escenarios personalizados, todo ello sin impacto significativo en el rendimiento gracias a su arquitectura asíncrona.