User : 'plan for later a waf with dropping result of attackants...
threats accumulate looks very high'. Phase 7.A delivers the foundation :
WAF detections become real nft drops within seconds.
## E2E live-verified on gk2
login : 200 JWT 160 chars
alert : 201 ← decision id 13244
cscli : Ip:192.0.2.99 ban origin=secubox-waf 1h
nft : 192.0.2.99 in table ip crowdsec (kernel-level drop)
Full chain (mitm LXC → host LAPI → bouncer → nft) round-trip in ~12s.
## Architecture
[secubox_waf.py in mitm LXC]
│ detects threat via pattern match
│ if count >= BAN_THRESHOLD
│ ↓
│ ban_ip() → _ban_via_crowdsec()
│ ↓
│ HTTP POST /v1/alerts (urllib stdlib, no httpx dep)
│ ↓
[socat 10.100.0.1:8080 → 127.0.0.1:8080] ← Phase 7.A.1 bridge
│ ↓
[CrowdSec LAPI on host 127.0.0.1:8080]
│ ↓
[crowdsec-firewall-bouncer (existing)]
│ ↓
[nft add element ip crowdsec ...]
│ ↓
[attacker IP dropped at netdev/forward chain]
## Files
### addons/secubox_waf.py
New constants CROWDSEC_CFG_FILE, _CS_JWT, _CS_JWT_TTL.
New _load_crowdsec_cfg() reads TOML, validates 4 required fields.
New _cs_jwt(cfg) caches JWT for 25 min (LAPI default 30 min expiry).
New _ban_via_crowdsec() POSTs Alert+Decision to /v1/alerts with
Bearer JWT. urllib stdlib only (mitm venv lacks httpx). On 401,
forces JWT refresh next call. Stats : bans_pushed, bans_failed.
Modified ban_ip() : tries HTTP bridge first, falls back to cscli
subprocess if bridge disabled. Old subprocess path kept for hosts
where WAF runs natively (cscli available).
### bin/secubox-waf-cs-bridge-setup
Installs socat forwarder unit secubox-cs-bridge.service so the mitm
LXC can reach the host loopback LAPI without changing CrowdSec config.
Registers secubox-waf as a MACHINE (watcher) via cscli machines add
with -f - so the local agent's credentials file stays untouched.
Writes /tmp/crowdsec.toml with machine_id + machine_password.
Operator copies into LXC at /etc/secubox/waf/crowdsec.toml.
### crowdsec/crowdsec.toml.example
Updated to document machine_id / machine_password (not the old
bouncer api_key — bouncers can only PULL decisions, not push them).
## Why machine auth (not bouncer)
CrowdSec LAPI splits routes by auth type :
- X-Api-Key (bouncer) → GET /v1/decisions/stream (read-only)
- JWT (watcher) → POST /v1/alerts (write)
- JWT (watcher) → DELETE /v1/decisions
To PUSH a ban, the WAF must auth as a watcher. We register a dedicated
machine 'secubox-waf' so its decisions show up in the dashboard tagged
with origin=secubox-waf (vs origin=crowdsec for scenario-driven bans
and origin=cscli for manual ones).
## Socat bridge rationale
Default CrowdSec install binds LAPI to 127.0.0.1:8080. Direct patching
of listen_uri to 10.100.0.1 breaks the local agent + bouncer (they hard-
code 127.0.0.1 in their credential files). A 30-line socat forwarder
service exposes the same LAPI on the LXC bridge gateway, gated by the
host firewall (only LXCs can reach 10.100.0.1). Zero CrowdSec config
change.
## Acceptance criteria (issue #498 Phase 7.A target)
1. Attacker dropped at nft within 30s of crossing BAN_THRESHOLD ✓
2. cscli decisions list shows origin=secubox-waf entries ✓
3. nft list table ip crowdsec shows the dropped IPs ✓
4. threat_counts dict growth bounded ✓ (still
local memory, but attacker IPs now drop before refilling it)
## Phase 7.A.2+ (followups in TODO.md)
- Backport into packages/secubox-waf/mitmproxy/secubox_waf.py
- debian/postinst : invoke setup script + bind-mount config into LXC
- WAF dashboard tab in admin webui showing bans_pushed counter
- Tune BAN_THRESHOLD per category (XSS=2, SQLi=1, scanner pattern=5)
- Phase 7.B : nft rate-limit pre-mitm to catch TCP-only scanners
|
||
|---|---|---|
| .. | ||
| addons | ||
| api | ||
| bin | ||
| crowdsec | ||
| data | ||
| debian | ||
| menu.d | ||
| nginx | ||
| tests | ||
| www/mitmproxy | ||
| README.md | ||
🔍 MITM Proxy
Traffic inspection and WAF proxy with auto-ban
Category: Security
Screenshot
Features
- Traffic inspection
- Request logging
- Auto-ban
- SSL interception
Installation
# Add SecuBox repository
curl -fsSL https://apt.secubox.in/install.sh | sudo bash
# Install package
sudo apt install secubox-mitmproxy
Configuration
Configuration file: /etc/secubox/mitmproxy.toml
API Endpoints
GET /api/v1/mitmproxy/status- Module statusGET /api/v1/mitmproxy/health- Health check
Addons
secubox_waf.py
Inspects every HTTP response in transit, applies the SecuBox WAF ruleset
and injects the health-banner + cookie-inventory bootstrap script before
</body> on text/html responses. Domain allow/exclude lists configurable
via [cdn].
cookie_audit.py (issue #156)
Companion to the WAF addon. Captures every Set-Cookie header observed in
transit and appends a structured JSONL record to
/var/log/secubox/cookie-audit/server.jsonl. Cookie values are
sha256-hashed at the addon — the raw value never leaves the process.
Register both addons together:
mitmdump -s /usr/share/secubox/addons/secubox_waf.py \
-s /usr/share/secubox/addons/cookie_audit.py
The companion browser script shared/cookie-inventory.js (loaded via the
WAF banner injection) snapshots document.cookie and posts to
/api/v1/cookie-audit/ingest. The secubox-metrics
CookieAuditAggregator reconciles both streams and flags RGPD/ePrivacy
violations (JS-set, non-strictly-necessary cookies).
Enable via [cookie_audit] enabled = true in /etc/secubox/secubox.conf.
License
MIT License - CyberMind © 2024-2026
