Hi, and thanks for CrowdSec Manager.
I run it in a split setup: CrowdSec and the manager on one Docker host, Traefik, Pangolin and Gerbil on another. While setting that up I found several bugs and fixed them on a fork.
Already opened: #138 builds with Go 1.27.1 and updates golang.org/x/crypto, x/net and x/text.
- It fixes CVE-2025-68121 (critical,
crypto/tls) and the rest of Trivy's findings for the image: 1 critical and 38 high become 0.
- It is small and does not depend on anything below.
Bugs that affect every installation
- Simulation mode does not work.
cscli simulation status -o json prints text, so the page always shows global simulation as disabled and lists no scenarios.
- The global switch sends the scenario name
*, which cscli does not know.
- Toggling a scenario does not reload CrowdSec, so CrowdSec keeps applying its decisions.
- An unknown scenario reports success.
- Changes that only take effect after a restart.
- Whitelist and captcha profile changes run
cscli parsers reload and cscli profiles reload. Neither command exists; they exit 1 and the error is ignored.
POST /api/hub/:category/install and /remove, POST /api/hub/upgrade and config snapshot restores don't reload CrowdSec at all.
- The fix reloads with SIGHUP and falls back to a restart.
- Whitelist entries are lost.
- Four of the five flows that add to the CrowdSec whitelist replace the whole file with the new entry.
- The CIDR flow puts ranges under
ip:, which makes CrowdSec exit on its next reload.
- The captcha and Discord apply pipelines keep going after a failed step. They then restart CrowdSec on a half-written configuration.
- Writes to read-only mounts fail halfway. Multi-file flows fail partway through when the Traefik config directory is read-only. Writes into a writable mount nested in a read-only one fail at random: moby's
checkWritablePath picks the first matching mount from a map.
- New databases ignore the configured paths. A new settings database stores the built-in default paths instead of
TRAEFIK_* and CROWDSEC_ACQUIS_FILE from the environment.
- Data race on the Docker client. 73 handler closures assign
dockerClient = resolveDockerClient(...) to the shared captured variable, so concurrent requests can run against another request's Docker host.
- Any origin can use the API. CORS and the WebSocket endpoints, including the terminal, accept any origin. A new
CORS_ALLOWED_ORIGINS restricts them.
Feature: per-service Docker hosts
CROWDSEC_DOCKER_HOST, TRAEFIK_DOCKER_HOST, PANGOLIN_DOCKER_HOST and GERBIL_DOCKER_HOST pin each service to a DOCKER_HOSTS entry.
- Flows that touch several services then reach each one on its own host: whitelists, captcha, health checks, config validation and history sync.
DOCKER_HOSTS_TLS adds mutual TLS per host.
- Nothing changes while the variables are unset.
- Smaller additions on the same fork:
- a simulation switch per scenario in the scenario list;
TRAEFIK_WHITELIST_MIDDLEWARE, to edit a named middleware (ipAllowList or the bouncer's clientTrustedIPs);
- reading the Traefik access log from a mounted file;
- a
.dockerignore.
Proposal
One PR per topic, each on top of dev with its tests:
- The data race fix and the fake Docker Engine API used by the tests. The other PRs build on this one.
- The CrowdSec reload fixes.
- The simulation fixes and the per-scenario switch.
- Whitelist, apply pipelines, read-only mounts, settings, CORS.
- Per-service Docker hosts and TLS.
Would that work for you? Should the PRs target dev or main? I'm happy to talk it through on Discord as well.
Hi, and thanks for CrowdSec Manager.
I run it in a split setup: CrowdSec and the manager on one Docker host, Traefik, Pangolin and Gerbil on another. While setting that up I found several bugs and fixed them on a fork.
Already opened: #138 builds with Go 1.27.1 and updates
golang.org/x/crypto,x/netandx/text.crypto/tls) and the rest of Trivy's findings for the image: 1 critical and 38 high become 0.Bugs that affect every installation
cscli simulation status -o jsonprints text, so the page always shows global simulation as disabled and lists no scenarios.*, which cscli does not know.cscli parsers reloadandcscli profiles reload. Neither command exists; they exit 1 and the error is ignored.POST /api/hub/:category/installand/remove,POST /api/hub/upgradeand config snapshot restores don't reload CrowdSec at all.ip:, which makes CrowdSec exit on its next reload.checkWritablePathpicks the first matching mount from a map.TRAEFIK_*andCROWDSEC_ACQUIS_FILEfrom the environment.dockerClient = resolveDockerClient(...)to the shared captured variable, so concurrent requests can run against another request's Docker host.CORS_ALLOWED_ORIGINSrestricts them.Feature: per-service Docker hosts
CROWDSEC_DOCKER_HOST,TRAEFIK_DOCKER_HOST,PANGOLIN_DOCKER_HOSTandGERBIL_DOCKER_HOSTpin each service to aDOCKER_HOSTSentry.DOCKER_HOSTS_TLSadds mutual TLS per host.TRAEFIK_WHITELIST_MIDDLEWARE, to edit a named middleware (ipAllowListor the bouncer'sclientTrustedIPs);.dockerignore.Proposal
One PR per topic, each on top of
devwith its tests:Would that work for you? Should the PRs target
devormain? I'm happy to talk it through on Discord as well.