# 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 ```bash 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: ```bash cd crowdsec && ./setup.sh ``` ### Paso 1: Configurar variables de entorno Edita el `.env` local con las variables reales: ```bash nano crowdsec/.env ``` Variables críticas: ```env # 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 ```bash 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: ```bash cd Traefik docker compose --env-file .env up -d ``` ### Paso 4: Desplegar CrowdSec ```bash cd crowdsec docker compose --env-file .env up -d ``` ### Paso 5: Verificar el despliegue ```bash # 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 **Applications** → **Providers** → **Create** - 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 **Applications** → **Create** - 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 **Outposts** → `authentik Embedded Outpost` → **Edit** - 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: ```yaml 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): ```yaml 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 ```bash # 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 ```bash # 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. ```bash # Crear una allowlist nueva docker exec crowdsec cscli allowlists create -d "Descripción" # Añadir una IP o CIDR a una allowlist docker exec crowdsec cscli allowlists add # Quitar una IP de una allowlist docker exec crowdsec cscli allowlists remove # Listar todas las allowlists y su contenido docker exec crowdsec cscli allowlists list docker exec crowdsec cscli allowlists inspect ``` #### 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 ` | IPs gestionadas por el bot de Telegram | Para recrearlas desde cero: ```bash # 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 ```bash # 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: ```env 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`: ```bash 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: ```yaml --- # 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 ` 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 ` | Unban + añade a allowlist `telegram-bot` | | `/unallow ` | Quita de allowlist `telegram-bot` | | `/unban ` | 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 ` 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: ```env 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: ```bash docker logs traefik | grep crowdsec ``` 2. Verifica que el middleware está configurado: ```bash docker exec traefik wget -qO- http://localhost:8080/api/http/middlewares | grep crowdsec ``` 3. Verifica que CrowdSec tiene decisiones activas: ```bash docker exec crowdsec cscli decisions list ``` 4. Comprueba conectividad entre Traefik y CrowdSec: ```bash 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: ```bash ls -lh /opt/traefik/logs/access.log tail -f /opt/traefik/logs/access.log ``` 2. Verifica el acquis de CrowdSec: ```bash docker exec crowdsec cat /etc/crowdsec/acquis.yaml ``` 3. Revisa los logs del engine: ```bash docker logs -f crowdsec ``` 4. Simula un ataque de prueba: ```bash 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: ```bash 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: ```bash docker logs ths-authentik-server ``` ## 💾 Backups Incluye en tus backups de Kopia (ya configurados en `backups/kopia/`): ```bash # 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: ```env CROWDSEC_IMAGE=crowdsecurity/crowdsec:latest GRAFANA_IMAGE=grafana/grafana:latest ``` 2. Redespiega: ```bash 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](https://github.com/crowdsecurity/crowdsec/releases). ## 📚 Recursos - [Documentación oficial de CrowdSec](https://docs.crowdsec.net/) - [CrowdSec + Traefik Plugin](https://plugins.traefik.io/plugins/6335349fe93a526d1ec2aed6/crowdsec-bouncer) - [CrowdSec Hub (colecciones)](https://hub.crowdsec.net/) - [Grafana Docs](https://grafana.com/docs/grafana/latest/) - [CrowdSec Discord](https://discord.gg/crowdsec)