Add real client IP detection for proxy/CDN environments
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 52s

Implements smart client IP detection to handle Cloudflare and other reverse
proxies correctly, preventing legitimate traffic from being tarpited when
behind a shared proxy IP.

Changes:
- Detect real client IP from proxy headers with priority order:
  1. CF-Connecting-IP (Cloudflare)
  2. X-Real-IP (common proxy header)
  3. X-Forwarded-For (standard proxy header)
  4. src (fallback to source IP if no headers)
- Track real client IP in stick-table instead of proxy IP
- Check real client IP for blocking rules
- No need to maintain proxy IP lists - works automatically

This ensures that:
- Cloudflare and other CDN traffic is tracked per real client
- Each actual user gets their own tarpit counter
- Legitimate users aren't affected by attackers on the same proxy
- Works automatically with any proxy that sets standard headers

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-08-24 06:51:00 -07:00
parent 5ce4f910c2
commit 2b31fb9f4f

View File

@@ -16,14 +16,27 @@ frontend web
# Allow trusted traffic to bypass all protection
http-request allow if trusted_networks or health_check
# Track client in stick table
http-request track-sc0 src
# Detect real client IP from proxy headers if they exist
# Priority: CF-Connecting-IP (Cloudflare) > X-Real-IP > X-Forwarded-For > src
acl has_cf_connecting_ip req.hdr(CF-Connecting-IP) -m found
acl has_x_real_ip req.hdr(X-Real-IP) -m found
acl has_x_forwarded_for req.hdr(X-Forwarded-For) -m found
# Set the real IP based on available headers
http-request set-var(txn.real_ip) req.hdr(CF-Connecting-IP) if has_cf_connecting_ip
http-request set-var(txn.real_ip) req.hdr(X-Real-IP) if !has_cf_connecting_ip has_x_real_ip
http-request set-var(txn.real_ip) req.hdr(X-Forwarded-For) if !has_cf_connecting_ip !has_x_real_ip has_x_forwarded_for
http-request set-var(txn.real_ip) src if !has_cf_connecting_ip !has_x_real_ip !has_x_forwarded_for
# Track the real client IP in stick table (not the proxy IP)
http-request track-sc0 var(txn.real_ip)
# IP blocking using map file (no word limit, runtime updates supported)
# Map file: /etc/haproxy/blocked_ips.map
# Runtime updates: echo "add map #0 IP_ADDRESS" | socat stdio /var/run/haproxy.sock
http-request set-path /blocked-ip if { src -f /etc/haproxy/blocked_ips.map }
use_backend default-backend if { src -f /etc/haproxy/blocked_ips.map }
# Now checks the real client IP (from headers if present, otherwise src)
http-request set-path /blocked-ip if { var(txn.real_ip) -m ip -f /etc/haproxy/blocked_ips.map }
use_backend default-backend if { var(txn.real_ip) -m ip -f /etc/haproxy/blocked_ips.map }
# Define threat levels based on accumulated error responses from backends
# These will be checked on subsequent requests after errors are tracked