Skip to content

CrowdSec Manager & Security Configuration

This page covers the CrowdSec Manager web UI on the Pangolin server, protected behind Tinyauth authentication, along with tuning of CrowdSec security rules and enabling Cloudflare Turnstile captcha for the CrowdSec bouncer.


Architecture

graph LR
    User -->|HTTPS| Traefik
    Traefik -->|forwardAuth| Tinyauth
    Tinyauth -->|authenticated| Traefik
    Traefik -->|proxy| CrowdSec-Manager
    CrowdSec-Manager -->|API| CrowdSec
    Traefik -->|bouncer plugin| CrowdSec
    CrowdSec -->|captcha decision| Turnstile[Cloudflare Turnstile]

All services run on the same Docker Compose stack and share the pangolin network. Traefik reaches them through Gerbil's network namespace.


Components Added

CrowdSec Manager

Image: hhftechnology/crowdsec-manager:1.1.0

A web UI for managing CrowdSec operations — viewing alerts, decisions, managing bouncers, and configuring scenarios. It has read-only access to Traefik and CrowdSec configs and read-write access to its own data and backups.

Accessible at: https://crowdsec.bnkserve.org

Tinyauth

Image: ghcr.io/steveiliop56/tinyauth:v4

A lightweight forward-auth middleware that protects the CrowdSec Manager dashboard with a login screen. Traefik's forwardAuth middleware checks every request to the manager against Tinyauth before allowing access.

Login page at: https://auth.bnkserve.org

User credentials are stored in a users file (/data/users) mounted from the host, using bcrypt-hashed passwords.

Special Characters in Passwords

Tinyauth v4 has a known issue where special characters (@, !, etc.) in passwords can cause login failures through the browser, even though the bcrypt hash verifies correctly via the CLI. Use alphanumeric passwords to avoid this.


Traefik Routing

Routers

Router Domain Middleware Purpose
crowdsec-manager-router crowdsec.bnkserve.org security-headers, tinyauth Dashboard (HTTPS)
crowdsec-manager-redirect crowdsec.bnkserve.org redirect-to-https HTTP → HTTPS redirect
tinyauth-router auth.bnkserve.org security-headers Auth login page (HTTPS)
tinyauth-redirect auth.bnkserve.org redirect-to-https HTTP → HTTPS redirect

No tinyauth middleware on the tinyauth router

The tinyauth-router must not have the tinyauth forwardAuth middleware applied — this would create an infinite redirect loop.

Middleware

The tinyauth forwardAuth middleware forwards every request to http://tinyauth:3000/api/auth/traefik. If the user has a valid session cookie (scoped to .bnkserve.org), the request passes through. Otherwise, the user is redirected to the Tinyauth login page.

tinyauth:
  forwardAuth:
    address: http://tinyauth:3000/api/auth/traefik
    trustForwardHeader: true
    authResponseHeaders:
      - X-Forwarded-User

CrowdSec Tuning

Relaxed Crawl Detection

The crowdsecurity/http-crawl-non_statics scenario was triggering on legitimate Canadian users browsing the site. The local override at /etc/crowdsec/scenarios/http-crawl-non_statics.yaml (replacing the hub symlink) has relaxed thresholds:

Parameter Before After Effect
capacity 40 80 Twice as many distinct pages before triggering
leakspeed 0.5s 0.25s Bucket drains twice as fast

Combined effect: 4x more lenient — a user must hit 80+ distinct non-static pages faster than 1 every 0.25 seconds to trigger a captcha.

Canadian ISP Whitelist

A whitelist expression in /etc/crowdsec/parsers/s02-enrich/mywhitelists.yaml exempts traffic from major Canadian ISPs from all CrowdSec scenarios:

expression:
  - evt.Meta.ASNNumber in ['812', '852', '6327', '5645', '20365', '25668', '577']
AS Number ISP
812 Rogers Communications
852 TELUS Communications
6327 Shaw Communications
5645 TekSavvy
20365 Freedom Mobile
25668 CipherKey
577 Bell Canada

Field name

The GeoIP enricher populates evt.Meta.ASNNumber (not ASNumber). This can be verified by inspecting /etc/crowdsec/parsers/s02-enrich/geoip-enrich.yaml.


Cloudflare Turnstile Captcha

Previously, CrowdSec captcha decisions resulted in a hard 403 block because no captcha provider was configured. Now, users with a captcha decision see a Cloudflare Turnstile challenge page and can proceed after solving it.

Configuration added to the CrowdSec bouncer plugin in dynamic_config.yml:

captchaProvider: turnstile
captchaSiteKey: <site-key>
captchaSecretKey: <secret-key>
captchaHTMLFilePath: /etc/traefik/captcha.html

Captcha HTML template path

The captcha.html template is copied from the plugin source to /etc/traefik/captcha.html (the mounted config volume). Do not reference the /plugins-storage/ path directly — the hash in that path changes on every Traefik restart.


DNS Records

Two A records pointing to 72.11.155.21:

Record Purpose
crowdsec.bnkserve.org CrowdSec Manager dashboard
auth.bnkserve.org Tinyauth login page

Verification

# Check containers are running and healthy
docker ps --filter name=crowdsec-manager --filter name=tinyauth

# Check both are on the pangolin network
docker network inspect pangolin --format '{{range .Containers}}{{.Name}} {{end}}'

# Verify no Canadian ISPs in active decisions
docker exec crowdsec cscli decisions list | grep "CA"

# Check CrowdSec whitelist is loaded
docker exec crowdsec cscli parsers inspect mywhitelists

# Check Traefik logs for captcha errors
docker logs traefik 2>&1 | grep -i captcha