Helps agents install, configure, operate, and debug CrowdSec security engine, bouncers, and WAF components across various environments.
- GitHub stars
- 30
- Files
- 34
- Last commit
- Oct 28, 2026
- License
- MIT
- Allowed tools
- —
What does the crowdsec skill do?
crowdsec helps agents install, configure, operate, and debug CrowdSec security engine, bouncers, and WAF components across various environments.
Summary generated from the skill's SKILL.md.
About the crowdsec skill
Managing the deployment and maintenance of CrowdSec security infrastructure is what this skill enables for DevOps engineers and security administrators. It provides the necessary operational support to install, configure, and debug the CrowdSec engine, bouncers, and Web Application Firewall components across diverse environments including bare-metal systemd, Docker, and Kubernetes.
An agent should load this skill when a user needs to perform tasks such as configuring log acquisition, managing hub collections, setting up notifications, or deploying bouncers for Nginx, Traefik, Caddy, or HAProxy. It is specifically designed for operational tasks like upgrading versions, migrating from fail2ban, or troubleshooting why logs are not parsing or why a bouncer is not blocking traffic. While it handles the deployment of the AppSec component and bot detection challenge modes, it does not author new WAF rules, scenarios, or parsers. For those specific creative tasks, a different skill is required.
What an agent can do with it
- 1Troubleshoot security blocking issuesHelp me figure out why my CrowdSec bouncer is not blocking traffic even though a decision exists.
- 2Deploy security components in KubernetesI need to set up CrowdSec using Helm in my Kubernetes cluster.
- 3Configure web server protectionShow me how to install and wire a Nginx bouncer to my existing setup.
Written from the skill's SKILL.md. Every use case is checked against a quote from it.
How to install the crowdsec skill
Each command copies the skill folder into the client's skills directory. Restart the client or start a new session to load it.Install the crowdsec skill in Plugin
/plugin marketplace add crowdsecurity/crowdsec-skill /plugin install crowdsec@crowdsecurity
Install the crowdsec skill in Claude Code
~/.claude/skills/crowdsec/SKILL.md
$ npx degit crowdsecurity/crowdsec-skill/skills/crowdsec ~/.claude/skills/crowdsecInstall the crowdsec skill in Claude Code (project)
.claude/skills/crowdsec/SKILL.md
$ npx degit crowdsecurity/crowdsec-skill/skills/crowdsec .claude/skills/crowdsecInstall the crowdsec skill in Codex
~/.agents/skills/crowdsec/SKILL.md
$ npx degit crowdsecurity/crowdsec-skill/skills/crowdsec ~/.agents/skills/crowdsecInstall the crowdsec skill in Gemini CLI
~/.gemini/skills/crowdsec/SKILL.md
$ npx degit crowdsecurity/crowdsec-skill/skills/crowdsec ~/.gemini/skills/crowdsecInstall the crowdsec skill in Claude.ai
npx degit crowdsecurity/crowdsec-skill/skills/crowdsec crowdsec && zip -r crowdsec.zip crowdsec # claude.ai → Customize → Skills → + → Create skill → Upload a skill → crowdsec.zip
Automated checks
Ran Nov 14, 2026Full report →Passed our automated checks. That is not a security audit: read the scripts before you let an agent run them. How checks work
- Source repository linked and reachablecrowdsecurity/crowdsec-skill/skills/crowdsec is public and reachablegithub.com/crowdsecurity/crowdsec-skill/tree/HEAD/skills/cro ↗Pass
- Open source license (OSI)MITspdx.org/licenses/MIT.html ↗Pass
- Commit or release in the last yearLast commit 2026-10-28github.com/crowdsecurity/crowdsec-skill/commits ↗Pass
- No download-and-run or credential theft in scripts2 scripts read; no download-and-run, remote eval, base64 execution or credential uploadPass
- No hidden instructions in SKILL.mdNo override phrases, safeguard switches, credential requests or hidden charactersgithub.com/crowdsecurity/crowdsec-skill/blob/HEAD/skills/cro ↗Pass
- Pre-approved tools are scopedNo pre-approved tools; the agent asks before using onegithub.com/crowdsecurity/crowdsec-skill/blob/HEAD/skills/cro ↗Pass
- SKILL.md follows the Agent Skills formatValid name and description; says when to use it; 213 linesgithub.com/crowdsecurity/crowdsec-skill/blob/HEAD/skills/cro ↗Pass
SKILL.md
View on GitHubCrowdSec — operations, deployment, configuration, and debugging
Glossary: AppSec is the engine component name (in configs, hub paths,
cscli appsec-*, Helm workload); WAF is the user-facing term for the same
thing. This skill uses both interchangeably.
Boundary — what this skill does and does not do
| You want to… | Use |
|---|---|
| Install / upgrade / uninstall CrowdSec | this skill |
| Configure acquisition, hub, profiles, notifications | this skill |
| Install and wire a bouncer (firewall, nginx, traefik, caddy) | this skill |
| Deploy the WAF (AppSec component) | this skill |
| Deploy and tune bot detection (AppSec challenge mode) | this skill |
| Debug "logs not parsing" / "no alerts" / "bouncer not blocking" | this skill |
| Migrate from fail2ban | this skill |
| Write a parser, scenario, or WAF (AppSec) rule | the crowdsec-local-mcp mcp |
| Drive the cloud Service API (manage blocklists / allowlists / firewall integrations / metrics / decisions programmatically) | the crowdsec-service-api skill |
Step 1 — Detect the environment
Run probes in this order. Stop at the first match.
# systemd / bare-metal
systemctl list-unit-files crowdsec.service >/dev/null 2>&1 && systemctl is-enabled crowdsec >/dev/null 2>&1
# docker
docker ps --format '{{.Names}} {{.Image}}' 2>/dev/null | grep -E '(^|/)(crowdsec)([: ]|$)'
# kubernetes
kubectl get pods -A 2>/dev/null | grep -i crowdsec
If nothing matches and the user reports CrowdSec is installed, ask where: a vendor appliance, a custom image, a binary in /opt/, or a remote host. Otherwise pivot to install: see references/install/.
pfSense detection:
uname -i # → pfSense (pfSense CE or Plus)
If confirmed pfSense, go directly to references/install/pfsense.md — paths, service names, and activation flow are entirely different from Linux/systemd.
Privileges — bare-metal / systemd prerequisite
On bare-metal/systemd, cscli and crowdsec need root (they read
/etc/crowdsec/, the DB under /var/lib/crowdsec/, and control the systemd
unit). Before running anything that touches config or state, confirm the user
is root or has sudo:
id -u # 0 = root; otherwise the user needs sudo
If they are neither root nor a sudoer, stop and ask them to grant it — don't
guess. Once confirmed, run bare-metal commands as root or prefixed with sudo.
Docker/k8s commands run inside the container/pod and do not need this.
Step 1.5 — Version & install-source sanity check (Linux)
Do this first on any install task and on any "weird behavior" report (missing
cscli commands/flags, hub items that won't install, behavior ≠ docs). An engine
installed from the wrong source can be years behind — a Linux-distro-only trap.
Compare the running engine to the latest published release:
curl -s https://version.crowdsec.net/latest # → {"tag_name":"v1.7.8",...}; parse tag_name
cscli version # bare-metal: prefix sudo
Then check where the package came from:
# Debian/Ubuntu
apt-cache policy crowdsec # read the *** installed line's origin
ls /etc/apt/sources.list.d/ | grep -i crowdsec
# RHEL-family
dnf info crowdsec ; dnf repolist | grep -i crowdsec
The official source is the packagecloud repo (packagecloud.io/crowdsec/crowdsec, repo id
crowdsec_crowdsec). A distro origin (archive.ubuntu.com, deb.debian.org,
ports.ubuntu.com) — or no crowdsec repo file at all — means it was installed from the
distro's own ancient package.
Rule: if the source isn't the official repo or the version is well behind
tag_name, treat it as a likely-outdated install — stop debugging config and migrate
onto the official repo first: references/operate/upgrades.md
§ Detect & fix an outdated / distro-packaged install.
Docker/Kubernetes: no repo-source trap — the version is the image tag pulled from Docker
Hub. If it's far behind version.crowdsec.net/latest, pull a newer tag
(references/operate/upgrades.md happy path).
Step 1.6 — Feature compatibility
Some features only exist past a given engine version, and a few also need a capable bouncer. Check here before debugging "the config is right but nothing happens" — on an older engine the answer is an upgrade, not a config change.
| Feature | Min engine | Also needs | Docs |
|---|---|---|---|
| Bot detection (AppSec challenge mode) — alpha | 1.8.0 | A bot-detection-capable bouncer (nginx, OpenResty, HAProxy SPOA, Traefik, Envoy) and a host that can run WASM in compiler mode | references/appsec/bot-detection/ |
Glob patterns in appsec_configs |
1.8.0 | — | references/appsec/bot-detection/deploy.md § 2 |
Version-gated behaviour is recorded here rather than repeated in each reference doc — when a feature is added, give it a row instead of sprinkling "x.y+" through the prose.
Step 2 — Detect the intent
| Cue from user | Go to |
|---|---|
| "install", "set up", "fresh box", "how do I start" | references/install/ (pick file by env) |
| "pfsense", "pfSense", "netgate" | references/install/pfsense.md |
| "configure logs / acquisition", "read journald / syslog / docker logs" | references/configure/acquisition.md |
| "install a collection / parser / scenario", "hub", "tainted" | references/configure/hub.md |
| "ban duration", "captcha", "decisions", "simulation", "alerts but no bans" | references/configure/profiles.md |
| "allowlist my office / CDN / monitoring IP", "I'm getting blocked by CAPI", "exclude IP from any ban" | references/configure/allowlists.md |
| "whitelist vs allowlist vs postoverflow", "which suppression layer should I use" | references/configure/allowlists.md § Suppression mechanisms |
| "test my whitelist works", "is my postoverflow / dynamic-IP whitelist actually firing" | references/configure/allowlists.md § Verification — does a whitelist actually work? |
| "notifications", "alert me on slack/email/webhook", "notification not firing" | references/configure/notifications.md |
| "block at the firewall", "iptables", "nftables", "ipset" | references/configure/bouncers/firewall.md |
| "nginx bouncer", "lua / openresty module" | references/configure/bouncers/web-servers.md § nginx |
| "haproxy bouncer", "SPOA / SPOE" | references/configure/bouncers/web-servers.md § haproxy |
| "apache bouncer", "mod_crowdsec" | references/configure/bouncers/web-servers.md § apache |
| "traefik bouncer", "traefik plugin / middleware" | references/configure/bouncers/web-servers.md § Traefik |
| "caddy bouncer", "caddy module / xcaddy" | references/configure/bouncers/web-servers.md § Caddy |
| "wrong source IP", "real client IP", "behind Cloudflare / reverse proxy / NPM", "X-Forwarded-For", "everyone shows as the proxy IP" | references/configure/bouncers/web-servers.md — per-bouncer real-IP/trusted-proxy sections |
| "AppSec", "WAF", "virtual patching", "block by request shape" | references/appsec/ — overview, deploy, configure, troubleshoot |
| "bot detection", "challenge mode", "JS challenge", "proof of work", "block headless browsers / puppeteer / selenium / scrapers", "let Googlebot through" | references/appsec/bot-detection/ — overview, deploy, configure, customize, troubleshoot |
| "Console", "enroll", "share signals" | references/install/console.md |
| "upgrade", "back up", "roll back", "new version", "tainted items after upgrade" | references/operate/upgrades.md |
"old/outdated version", "cscli command or flag missing", "hub item won't install", "behavior doesn't match the docs", "installed from the distro package" |
references/operate/upgrades.md § Detect & fix an outdated / distro-packaged install (see Step 1.5 above) |
| "multiple agents", "remote LAPI", "mTLS", "postgres backend" | references/operate/multi-server.md (partial — machine cleanup done, rest stub) |
"stale machines / log processors in cscli machines list", "prune dead agents", "ephemeral k8s pods piling up" |
references/operate/multi-server.md § Decommissioning stale machines |
| "is it working?", "smoke test", "validate install", "verify setup", "did detection / WAF / blocking actually wire up?" | references/operate/health-check.md |
| Debug — common · "it's broken" / "not working" / general diagnosis | references/debug/common/triage.md → run bash ${CLAUDE_SKILL_DIR}/scripts/diagnose.sh |
| Debug — common · specific error string | references/debug/common/errors.md |
| Debug — common · "container can't see logs", "mount", "SELinux/AppArmor denied", "k8s RBAC / DaemonSet" | references/debug/common/platform-gotchas.md |
| Debug — by symptom · "logs not parsed", "0 parsed" | references/debug/symptoms/parsing.md |
| Debug — by symptom · "no alerts firing" | references/debug/symptoms/no-alerts.md |
| Debug — by symptom · "decision exists but not blocked" | references/debug/symptoms/not-blocked.md |
| Debug — by symptom · "bouncer blocks everything", "locked out of all services", "every request 403 after adding the bouncer" | references/debug/symptoms/not-blocked.md § 7 — Inverse symptom |
| Debug — by feature · AppSec/WAF not blocking, false positives, captcha | references/appsec/troubleshoot.md |
| Debug — by feature · challenge never served, endless challenge loop, real crawlers being challenged, everything blocked after enabling bot detection | references/appsec/bot-detection/troubleshoot.md |
| "switch from fail2ban" | references/migrate/from-fail2ban.md (TODO — stub) |
For anything debug-shaped, the first move is almost always:
bash ${CLAUDE_SKILL_DIR}/scripts/diagnose.sh
(or --env docker --container <name> / --env k8s --namespace ... --pod ...).
Step 3 — Universal cscli cheat sheet
These work in every environment. On bare-metal/systemd, prefix with sudo (unless you are root) — see Privileges above. In docker/k8s prefix with docker exec <name> / kubectl exec -n <ns> <pod> -- (which run as root inside the container/pod).
| Purpose | Command |
|---|---|
| Engine version | cscli version |
| Effective config (paths, LAPI URL, DB type) | cscli config show |
| One-shot triage table | cscli metrics |
| Recent alerts | cscli alerts list -l 50 |
| Active bans | cscli decisions list |
| Delete one ban | cscli decisions delete -i <ip> |
| Hub state (installed + tainted/missing flags) | cscli hub list |
| Refresh hub index, then upgrade items | cscli hub update && cscli hub upgrade |
| Allowlists — list / check one IP / add | cscli allowlists list, cscli allowlists check <ip>, cscli allowlists add <name> <ip> |
| List bouncers and their last pull time | cscli bouncers list |
| List agents registered to this LAPI | cscli machines list |
| LAPI reachable (agent→LAPI) | cscli lapi status |
| CAPI/Console connectivity (enrolled, pulling/sharing) | cscli capi status |
| Console feature toggles (custom/manual/tainted/context/console_management) | cscli console status |
| Enroll this engine in the Console | cscli console enroll <key> then reload (see references/install/console.md) |
| Replay a log file through parsers (read-only) | cscli explain --file <path> --type <syslog|nginx|...> |
| Replay a single log line | cscli explain --log '<line>' --type <type> |
| Validate config after editing any yaml (acquisition/profiles/config) | crowdsec -t (bare-metal; also auto-runs on systemctl reload) — then confirm the source reads with cscli metrics show acquisition |
| See simulation state (alerts but no decisions) | cscli simulation status |
| Inspect decision profiles (filters / ban duration) | cat /etc/crowdsec/profiles.yaml — there is no cscli profiles command (through v1.7.8); see references/configure/profiles.md |
Where things live on a default bare-metal install:
- Binaries:
/usr/bin/crowdsec,/usr/bin/cscli - Config root:
/etc/crowdsec/ - Acquisition:
/etc/crowdsec/acquis.yamland/or/etc/crowdsec/acquis.d/*.yaml - Hub items:
/etc/crowdsec/hub/, enabled symlinks under/etc/crowdsec/{parsers,scenarios,collections,postoverflows,contexts}/ - Local overrides:
*/parsers/*/_custom/,*/scenarios/*/_custom/, etc. - Data (sqlite DB, geoip):
/var/lib/crowdsec/data/ - Logs:
/var/log/crowdsec.log(agent) and/var/log/crowdsec_api.log(LAPI) - LAPI default listen:
127.0.0.1:8080 - Systemd unit:
crowdsec.service
Step 4 — Hard don'ts
Confirm with the user before any of these:
cscli decisions delete --all— wipes every active ban including CAPI-pulled blocklists. Use targeteddelete -i,delete -r,delete --id,delete --origin lists --scenario <name>.- Editing hub-managed files under
/etc/crowdsec/{parsers,scenarios,collections,postoverflows,contexts}/instead of the sibling_custom/directory — see references/debug/common/triage.md § Hard don'ts. - Disabling a signature collection wholesale to silence a false positive — pick the right suppression layer (allowlist / whitelist parser / postoverflow) per references/configure/allowlists.md § Suppression mechanisms.
- Mutating host firewall state (firewall bouncer install,
ipsetflush, iptables↔nftables switch) without confirming — the firewall bouncer can wipe rule chains other tools depend on. - Skipping
--reset-then-reuse-valuesonhelm upgrade crowdsec— silently drops values.
Docs
Canonical reference: https://docs.crowdsec.net/. Each file in references/ cites the specific page it relies on — follow the link rather than paraphrasing from memory.
Files in this skill
34crowdsec skill questions
How do I install the crowdsec skill in Claude Code?
Run npx degit crowdsecurity/crowdsec-skill/skills/crowdsec ~/.claude/skills/crowdsec. Claude Code loads skills from ~/.claude/skills (all projects) or .claude/skills (one project) and uses a skill when its description matches the task.
Which clients can use the crowdsec skill?
Any client that reads the Agent Skills format: Claude Code, Codex, Gemini CLI and claude.ai (upload as a ZIP). Scripts in the skill run only where the client allows code execution.
What is the scope of this skill?
This skill covers installation, configuration, and debugging of CrowdSec, including bouncers and WAF, but it does not include authoring new rules, parsers, or scenarios.
What are the requirements for using bot detection (AppSec challenge mode)?
Bot detection requires engine version 1.8.0 or higher, a compatible bouncer (such as nginx, Traefik, or Envoy), and a host capable of running WASM in compiler mode.