A CrowdSec bouncer compiled to WebAssembly, run as a Sōzune plugin.
On every request it reads the client IP and asks the CrowdSec Local API (LAPI)
whether that IP has an active decision. If it does, the request is blocked with
403; otherwise it continues to the backend.
This is the live bouncer mode — one LAPI call per request, no local cache
(kept simple for a first cut). It uses Sōzune's http_fetch extension to reach
the LAPI, which is not part of the http-wasm spec: this guest only runs on a
host that provides that extension.
cargo build --release --target wasm32-unknown-unknown
# -> target/wasm32-unknown-unknown/release/sozune_crowdsec.wasmDeclare the plugin in Sōzune's static config. allowed_hosts must include the
LAPI host — it both opts the plugin into the network extension and restricts
where it may connect (anti-SSRF).
# config.yaml
plugins:
crowdsec:
path: /plugins/sozune_crowdsec.wasm
allowed_hosts: ["crowdsec:8080"]
config:
lapi_host: "crowdsec:8080"
lapi_key: "<your-bouncer-api-key>"
scheme: "http"
path: "/"Then reference it on a service:
labels:
- "sozune.enable=true"
- "sozune.http.app.host=app.example.com"
- "sozune.http.app.plugins=crowdsec"| Key | Default | Description |
|---|---|---|
lapi_host |
— | CrowdSec LAPI host and port, e.g. crowdsec:8080. Required. |
lapi_key |
— | Bouncer API key (cscli bouncers add ...). |
scheme |
http |
http or https. |
path |
/ |
Base path of the LAPI. |
- Fail-open: if the LAPI is unreachable or misconfigured, the request is allowed. A bouncer outage should not take the site down.
- Live mode only: no caching yet, so each request makes one LAPI call.
- Client IP is taken from the leftmost
X-Forwarded-Forentry, falling back to the connection source address.
MIT.