feat(haproxy): Add CrowdSec HAProxy bouncer for dual-layer WAF
- Add lua-load directive for CrowdSec bouncer script - Add http-request lua.crowdsec_check to HTTP/HTTPS frontends - Block requests where txn.blocked=1 with 403 status - Skip CrowdSec check for ACME challenges (HTTP frontend) - Dual-layer WAF: CrowdSec IP blocking + mitmproxy inspection Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
14e965d5fa
commit
33bc1e1732
@ -3797,3 +3797,22 @@ git checkout HEAD -- index.html
|
||||
- **Root Cause:** RPCD handler only checked Docker, not LXC containers
|
||||
- **Fix:** Added `webmail.type` UCI option check, use `lxc-info` for LXC type
|
||||
- Webmail status now correctly shows "Running" for LXC containers
|
||||
|
||||
46. **CrowdSec HAProxy Bouncer - Dual Layer WAF (2026-02-26)**
|
||||
- **Purpose:** IP-level blocking at HAProxy before mitmproxy WAF inspection
|
||||
- **Implementation:**
|
||||
- Created `/srv/haproxy/lua/crowdsec.lua` - Lua bouncer script
|
||||
- Queries CrowdSec LAPI on port 8190 for IP decisions
|
||||
- In-memory cache with 60s TTL (30s negative cache)
|
||||
- Fail-open design: allows traffic if API unreachable
|
||||
- Skips internal IPs (127.x, 192.168.x, 10.x)
|
||||
- **HAProxy Integration:**
|
||||
- `lua-load /opt/haproxy/lua/crowdsec.lua` in global section
|
||||
- `http-request lua.crowdsec_check` in HTTP/HTTPS frontends
|
||||
- `http-request deny deny_status 403 if { var(txn.blocked) -m str 1 }`
|
||||
- **Registered Bouncer:** `haproxy-bouncer` in CrowdSec with API key
|
||||
- **Result:** Dual-layer WAF protection
|
||||
- Layer 1: CrowdSec HAProxy bouncer (IP reputation, 60s cache)
|
||||
- Layer 2: mitmproxy WAF (request inspection, CVE detection)
|
||||
- All 13 MetaBlogizer sites verified working with dual WAF
|
||||
- **CrowdSec MCP:** Added crowdsec-local-mcp for AI-generated WAF rules
|
||||
|
||||
@ -571,6 +571,7 @@ global
|
||||
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384
|
||||
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
|
||||
tune.ssl.default-dh-param 2048
|
||||
lua-load /opt/haproxy/lua/crowdsec.lua
|
||||
|
||||
EOF
|
||||
|
||||
@ -643,6 +644,10 @@ frontend http-in
|
||||
acl is_acme_challenge path_beg /.well-known/acme-challenge/
|
||||
use_backend acme_challenge if is_acme_challenge
|
||||
|
||||
# CrowdSec IP blocking (dual-layer WAF with mitmproxy)
|
||||
http-request lua.crowdsec_check if !is_acme_challenge
|
||||
http-request deny deny_status 403 if { var(txn.blocked) -m str 1 }
|
||||
|
||||
EOF
|
||||
|
||||
# Add HTTPS redirect rules for vhosts with ssl_redirect
|
||||
@ -684,6 +689,10 @@ frontend https-in
|
||||
acl is_sensitive_path path_beg /.htaccess
|
||||
acl is_sensitive_path path_beg /.htpasswd
|
||||
http-request deny if is_sensitive_path
|
||||
|
||||
# CrowdSec IP blocking (dual-layer WAF with mitmproxy)
|
||||
http-request lua.crowdsec_check
|
||||
http-request deny deny_status 403 if { var(txn.blocked) -m str 1 }
|
||||
EOF
|
||||
else
|
||||
# Fallback to directory mode if no certs.list
|
||||
@ -701,6 +710,10 @@ frontend https-in
|
||||
acl is_sensitive_path path_beg /.htaccess
|
||||
acl is_sensitive_path path_beg /.htpasswd
|
||||
http-request deny if is_sensitive_path
|
||||
|
||||
# CrowdSec IP blocking (dual-layer WAF with mitmproxy)
|
||||
http-request lua.crowdsec_check
|
||||
http-request deny deny_status 403 if { var(txn.blocked) -m str 1 }
|
||||
EOF
|
||||
fi
|
||||
# Add path-based ACLs BEFORE vhost ACLs (path rules take precedence)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user