Production-grade CrowdSec bouncer for UniFi network controllers
10K+

cs-unifi-bouncer-pro is a CrowdSec bouncer for UniFi network controllers: UniFi OS consoles, UniFi OS Server and the self-hosted Network Application. It turns CrowdSec ban decisions into UniFi firewall objects, so malicious addresses are blocked at the gateway.
It uses zone-based policies or legacy WAN_IN rules, chosen per site at startup, applies bans across multiple sites, and packs addresses into sharded groups or traffic matching lists that are created and merged as the ban list changes. Bans are persisted in a bbolt database, a configurable circuit breaker handles controller outages, and startup and periodic reconciles correct drift. The image is distroless, about an 8 MB download (about 31 MB unpacked), runs as nonroot (UID 65532), and is Cosign-signed with a CycloneDX SBOM attached to every release.
Upgrading from 1.x? 2.0 changes several defaults and rejects settings 1.x accepted. Read the upgrade guide before you pull the new image.
services:
bouncer:
image: developingchet/cs-unifi-bouncer-pro:latest
restart: unless-stopped
environment:
UNIFI_URL: https://192.168.1.1
UNIFI_API_KEY: your-api-key
CROWDSEC_LAPI_URL: http://crowdsec:8080
CROWDSEC_LAPI_ALLOW_HTTP: "true"
CROWDSEC_LAPI_KEY: your-bouncer-key
ZONE_PAIRS: External->Dmz
volumes:
- bouncer-data:/data
volumes:
bouncer-data:
For full setup including CrowdSec registration, TLS, multi-site, and Docker Secrets support, see the Setup Guide.
WAN_IN rules, chosen per site at startup. UniFi Network 11 is zone-based only: legacy sites switch to zone mode after the controller upgradeSHARD_MERGE_THRESHOLD)/v1/usage-metrics (default: 30 min; configurable)EGRESS_ZONE_PAIRS stops hosts in zones such as a DMZ or IoT network from connecting out to banned addresses, using the same ban listsstatus bans, status ip, status history, also against the running bouncer via docker execABUSEIPDB_LIST and optionally ABUSEIPDB_COUNTRY_INCLUDE, ABUSEIPDB_COUNTRY_EXCLUDE, and ABUSEIPDB_REFRESH_INTERVALBLOCK_SCENARIO_DURATION_MAP, including durations longer than BAN_TTL@ip1,ip2,... suffix on zone pairsDECISION_RATE_LIMIT)--lapi-auth also checks the LAPI key)| Variable | Example | Description |
|---|---|---|
UNIFI_URL | https://192.168.1.1 | UniFi controller base URL |
UNIFI_API_KEY | your-api-key | API key (Settings → Control Plane → Integrations); or use UNIFI_USERNAME + UNIFI_PASSWORD, which manage legacy firewall rules only |
CROWDSEC_LAPI_KEY | your-bouncer-key | Bouncer key from cscli bouncers add unifi-bouncer |
Commonly set as well:
| Variable | Default | Description |
|---|---|---|
CROWDSEC_LAPI_URL | https://crowdsec:8080 | CrowdSec LAPI URL; an http:// URL also needs CROWDSEC_LAPI_ALLOW_HTTP=true, for a trusted local network only |
ZONE_PAIRS | External->Dmz | Zone pairs whose inbound traffic is blocked on zone-based sites; src[:sport,...]->dst[:dport,...][@dstIP,...] — port and destination IP filters are optional |
UNIFI_SITES | default | Comma-separated sites to manage |
Sensitive variables (UNIFI_API_KEY, UNIFI_USERNAME, UNIFI_PASSWORD, CROWDSEC_LAPI_KEY) accept a _FILE suffix for Docker secrets and Kubernetes secret mounts. For the full variable reference see the Configuration Reference.
| Tag | When to use |
|---|---|
latest | stable, always points to the newest release |
2.4.0 (also v2.4.0) | exact version, recommended for production |
2.4 | minor-pinned |
2 | major-pinned |
This image is signed with Cosign (keyless OIDC). Verify with:
cosign verify developingchet/cs-unifi-bouncer-pro:2.4.0 \
--certificate-identity-regexp="https://github.com/developingchet/cs-unifi-bouncer-pro/.github/workflows/release.yml@refs/tags/.*" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com"
A CycloneDX SBOM is attached to each release and embedded as a Cosign attestation on the image.
Content type
Image
Digest
sha256:17286608e…
Size
7.5 MB
Last updated
1 day ago
docker pull developingchet/cs-unifi-bouncer-pro