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:
| 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