Skip to content

CrowdSec Integration & Security Logging ​

Connect RouteWarden to CrowdSec to automatically turn blocked reconnaissance scans into immediate firewall bans across your entire infrastructure.

Attacker Probes /.env ──► RouteWarden Blocks & Emits JSON ──► CrowdSec Parses & Bans Attacker IP

Why Pair RouteWarden with CrowdSec? ​

CrowdSec typically detects attacks by tailing standard web access logs and waiting for multiple suspicious requests to cross a threshold. While effective for broad traffic, this means vulnerability scanners still get multiple chances to probe your services before getting blocked.

Pairing RouteWarden directly with CrowdSec changes this dynamic:

FeatureStandard Log AnalysisRouteWarden + CrowdSec
First-Request NeutralizationRequires multiple requests to cross thresholdIntercepted on the very first probe before reaching upstream backends
Ban SpeedTypically requires 5–10 requestsImmediate ban triggered on sensitive file reconnaissance
Attacker ExperienceStandard 403 ForbiddenChoice of deception: fake .env credentials, slow tarpits, or connection drops
Parsing OverheadCrowdSec must parse every web requestCrowdSec only processes discrete routewarden_block security events
Anti-Evasion NormalizationComplex URL-encoded paths can slip past naive regexEvaluates canonical paths cleaned of double encoding, matrix params, and backslashes

How It Works ​

  1. Interception: When a client requests a protected endpoint (such as /.env, /.git/config, or /dump.sql) or sends a blocked query string, RouteWarden intercepts the request according to your configured response mode (json, html, fakeSuccess, silentDrop, etc.).
  2. Structured Event Emission: Along with the client response, RouteWarden emits a single-line JSON audit event to stdout:
{  "type": "routewarden_block",  "timestamp": "2026-09-19T15:20:00Z",  "plugin": "routewarden",  "client_ip": "198.51.100.42",  "method": "GET",  "path": "/.env",  "request_uri": "/.env",  "pattern": "(?i)(^|/)(\.env.*)$",  "action": "fakeSuccess",  "reason": "path_blocked",  "user_agent": "Mozilla/5.0 (compatible; Nuclei/v3.1.0)"}
  1. CrowdSec Parsing: The custom RouteWarden parser ingests this structured event and extracts the client IP, probed path, HTTP method, and matched pattern.
  2. Instant Remediation: The scenario flags the probe as high-confidence reconnaissance and immediately instructs your CrowdSec bouncers (firewall, iptables, Cloudflare) to ban the offending IP.

Setup Walkthrough ​

Step 1: Install the RouteWarden CrowdSec Parser ​

Create /etc/crowdsec/parsers/s01-parse/routewarden-logs.yaml:

# /etc/crowdsec/parsers/s01-parse/routewarden-logs.yamlonsuccess: next_stagename: routewarden/parserdescription: "Parse RouteWarden security block events from Traefik & Caddy"filter: "evt.Line.Raw contains 'routewarden_block'"nodes:  - grok:      pattern: '.*(?P<json_raw>\{"type":"routewarden_block".*\})'      apply_on: Line.Rawstatics:  - meta: log_type    value: routewarden_block  - meta: source_ip    expression: 'JsonExtract(evt.Parsed.json_raw, "client_ip")'  - meta: http_path    expression: 'JsonExtract(evt.Parsed.json_raw, "path")'  - meta: http_method    expression: 'JsonExtract(evt.Parsed.json_raw, "method")'  - meta: http_user_agent    expression: 'JsonExtract(evt.Parsed.json_raw, "user_agent")'  - meta: routewarden_pattern    expression: 'JsonExtract(evt.Parsed.json_raw, "pattern")'  - meta: routewarden_action    expression: 'JsonExtract(evt.Parsed.json_raw, "action")'

Step 2: Install the RouteWarden Threat Scenario ​

Create /etc/crowdsec/scenarios/routewarden-threat.yaml:

# /etc/crowdsec/scenarios/routewarden-threat.yamltype: triggername: routewarden/sensitive-endpoint-scandescription: "Ban IPs probing sensitive paths intercepted by RouteWarden"filter: "evt.Meta.log_type == 'routewarden_block'"blackhole: 1hlabels:  type: scan  remediation: true  service: http  confidence: 3  spoofable: 0  behavior: "http:probing"scope:  type: ip  expression: evt.Meta.source_ip

Step 3: Configure CrowdSec Log Acquisition (acquis.yaml) ​

CrowdSec reads logs through an acquisition datasource configured in /etc/crowdsec/acquis.yaml. You can ingest RouteWarden logs via Docker container logs or directly from local log files on disk.

# /etc/crowdsec/acquis.yaml# Ingest directly from Traefik container stdout/stderrsource: dockercontainer_name:  - traefiklabels:  type: routewarden

How to direct Gateway output to a log file ​

If you choose file-based acquisition, configure your gateway to write logs to disk:

# Static Traefik Configuration (traefik.yml)log:  level: INFO  filePath: "/var/log/traefik/traefik.log"  format: common

TIP

Docker Volume Sharing for File-Based Acquisition: If CrowdSec runs inside a Docker container while reading a file from the host, ensure the log directory is mounted in both containers:

volumes:  - /var/log/traefik:/var/log/traefik:ro

Step 4: Configure the Gateway (Traefik, Caddy & NGINX) ​

Security logging is enabled by default (securityLog: true / security_log true).

http:  middlewares:    routewarden-shield:      plugin:        routewarden:          enabled: true          # Emits structured JSON events on stdout for CrowdSec          securityLog: true          enableDefaultPatterns: true          # Deceive attackers with convincing dummy credentials          response:            mode: fakeSuccess            statusCode: 200

Complete Docker Compose Example ​

Here is a practical Docker Compose setup running your preferred gateway with RouteWarden, CrowdSec, and a protected web container:

services:  traefik:    image: traefik:v3.1    container_name: traefik    command:      - "--api.insecure=true"      - "--providers.docker=true"      - "--providers.docker.exposedbydefault=false"      - "--entrypoints.web.address=:80"      - "--experimental.plugins.routewarden.modulename=github.com/routewarden/traefik-warden"      - "--experimental.plugins.routewarden.version=v1.2.1"    ports:      - "80:80"      - "8080:8080"    volumes:      - /var/run/docker.sock:/var/run/docker.sock:ro    restart: unless-stopped  crowdsec:    image: crowdsecurity/crowdsec:latest    container_name: crowdsec    environment:      COLLECTIONS: "crowdsecurity/traefik crowdsecurity/http-cve"    volumes:      - ./crowdsec/acquis.yaml:/etc/crowdsec/acquis.yaml:ro      - ./crowdsec/parsers:/etc/crowdsec/parsers/s01-parse:ro      - ./crowdsec/scenarios:/etc/crowdsec/scenarios:ro      - /var/run/docker.sock:/var/run/docker.sock:ro      - crowdsec-db:/var/lib/crowdsec/data/    restart: unless-stopped  web:    image: nginx:alpine    container_name: web    labels:      - "traefik.enable=true"      - "traefik.http.routers.web.rule=PathPrefix(`/`)"      - "traefik.http.routers.web.middlewares=sec-shield"      - "traefik.http.middlewares.sec-shield.plugin.routewarden.enabled=true"      - "traefik.http.middlewares.sec-shield.plugin.routewarden.securityLog=true"      - "traefik.http.middlewares.sec-shield.plugin.routewarden.response.mode=json"volumes:  crowdsec-db:

Testing the Integration ​

1. Send a Test Probe ​

Simulate a vulnerability scanner probing for exposed configuration files:

curl -i -H "User-Agent: Nuclei/v3.1.0" http://localhost/.env

2. Verify Structured Security Log Emission ​

Check Traefik or Caddy output for the security block record:

docker logs traefik | grep routewarden_block

Example JSON output:

{"action":"json","client_ip":"172.18.0.1","method":"GET","path":"/.env","pattern":"(?i)(^|/)(\.env.*|.*\.(txt|log|bak|backup|sql|conf|config|ini|yaml|yml))$","plugin":"routewarden","reason":"path_blocked","request_uri":"/.env","timestamp":"2026-09-19T15:30:12Z","type":"routewarden_block","user_agent":"Nuclei/v3.1.0"}

3. Check Active CrowdSec Decisions ​

Verify that CrowdSec parsed the event and issued a ban:

# View trigger alertsdocker exec -t crowdsec cscli alerts list# View active firewall remediation decisionsdocker exec -t crowdsec cscli decisions list

The client IP is now banned by CrowdSec across all attached bouncers.


SIEM and Log Shipper Ingestion ​

Because RouteWarden emits single-line JSON with type: "routewarden_block", you can easily pipe these logs into your existing observability stack without custom grok patterns:

  • Elasticsearch / Filebeat: Ingest with standard JSON processors and enrich client_ip with GeoIP data.
  • Grafana Loki / Promtail: Parse with {type="routewarden_block"} | json for instant dashboard metrics and alerts.
  • Datadog / Splunk: Automatic JSON facet extraction for pattern, action, reason, and user_agent.

Released under the MIT License.