Breaking Change: Complete Architecture Rewrite
v2.0 replaces the Python Docker-based bouncer (which used the UniFi controller API) with the official CrowdSec firewall bouncer Go binary running directly on UniFi OS devices using ipset/iptables.
Why the rewrite?
The v1.x Python bouncer worked by managing UniFi firewall groups through the controller API. While functional, it had significant limitations:
- Required Docker on a separate host
- Needed UniFi controller credentials
- Subject to API rate limits
- 60s minimum update interval
- 256MB+ RAM usage
- Firewall groups limited to ~10K IPs before controller instability
What's new in v2.0
- No Docker required — runs natively on UniFi OS devices (UDM SE, UDM Pro, UDR)
- No UniFi credentials — uses
ipset/iptablesdirectly, bypasses the controller API entirely - 10s update frequency (was 60s)
- ~15MB RAM (was 256MB+)
- 120K+ IP capacity on UDM SE/Pro (was ~10K via API)
- Firmware-update persistence —
ensure-rules.shcron job restores rules after reboots and firmware updates - UDR boot race fix —
ssd1.mountdependency prevents the bouncer from starting before storage is mounted
Installation
See the README for the new installation process using install.sh.
Migration from v1.x
- Stop and remove the v1.x Docker container
- Remove the old firewall groups from the UniFi controller (they are no longer used)
- Follow the v2.0 installation instructions in the README
- The native bouncer will automatically pick up all CrowdSec decisions
Files
| File | Purpose |
|---|---|
install.sh
| Downloads and installs the CrowdSec firewall bouncer binary |
setup.sh
| Configures ipset, iptables rules, and cron persistence |
ensure-rules.sh
| Cron job to restore rules after reboot/firmware update |
crowdsec-firewall-bouncer.yaml.example
| Example bouncer configuration |
crowdsec-firewall-bouncer.service
| systemd service file |
Companion tools
- crowdsec-blocklist-import — Import external IP blocklists as CrowdSec decisions
- crowdsec-unifi-parser — Parse UniFi syslogs for CrowdSec threat detection
Closed PRs
All 9 pending v1.x feature PRs (#18-#26) have been closed as obsolete — they modified bouncer.py which no longer exists. The features they provided are either handled natively by the Go bouncer, addressed by the new architecture, or available through companion tools.