Add trusted IP whitelist for rate limit bypass
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 1m25s

Adds trusted_ips.list and trusted_ips.map files that exempt specific
IPs from all rate limiting rules. Supports both direct source IP
matching (is_trusted_ip) and proxy-header real IP matching
(is_whitelisted). Files are baked into the image and can be updated
by editing and rebuilding.

Adds phone system IP 172.116.197.166 to the whitelist.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-31 13:39:41 -07:00
parent 2ba8f87c2c
commit 53d259bd3f
4 changed files with 18 additions and 6 deletions

View File

@@ -5,6 +5,8 @@ COPY ./templates /haproxy/templates
COPY requirements.txt /haproxy/
COPY haproxy_manager.py /haproxy/
COPY scripts /haproxy/scripts
COPY trusted_ips.list /etc/haproxy/trusted_ips.list
COPY trusted_ips.map /etc/haproxy/trusted_ips.map
RUN chmod +x /haproxy/scripts/*
RUN pip install -r requirements.txt
# Create log directories

View File

@@ -23,21 +23,23 @@ frontend web
stick-table type ip size 200k expire 10m store conn_cur,conn_rate(10s),http_req_rate(10s),http_err_rate(30s)
http-request track-sc0 var(txn.real_ip)
# Whitelist: let health checks and local traffic bypass rate limits
# Whitelist: let health checks, local, and trusted traffic bypass rate limits
acl is_local src 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
acl is_trusted_ip src -f /etc/haproxy/trusted_ips.list
acl is_health_check path_beg /.well-known/acme-challenge
acl is_whitelisted var(txn.real_ip),map_ip(/etc/haproxy/trusted_ips.map,0) -m int gt 0
# --- Rate limit rules (applied in order, first match wins) ---
# Hard block: >500 req/10s per IP (sustained flood)
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 500 } !is_local !is_health_check
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 500 } !is_local !is_trusted_ip !is_whitelisted !is_health_check
# Tarpit: >200 req/10s per IP (aggressive scraping / light flood)
http-request tarpit deny_status 429 if { sc_http_req_rate(0) gt 200 } !is_local !is_health_check
http-request tarpit deny_status 429 if { sc_http_req_rate(0) gt 200 } !is_local !is_trusted_ip !is_whitelisted !is_health_check
# Connection rate limit: >150 new connections per 10s per IP
http-request deny deny_status 429 if { sc_conn_rate(0) gt 150 } !is_local !is_health_check
http-request deny deny_status 429 if { sc_conn_rate(0) gt 150 } !is_local !is_trusted_ip !is_whitelisted !is_health_check
# Concurrent connection limit: >100 simultaneous connections per IP
http-request deny deny_status 429 if { sc_conn_cur(0) gt 100 } !is_local !is_health_check
http-request deny deny_status 429 if { sc_conn_cur(0) gt 100 } !is_local !is_trusted_ip !is_whitelisted !is_health_check
# High error rate: >20 errors in 30s (scanner/fuzzer behavior)
http-request tarpit deny_status 403 if { sc_http_err_rate(0) gt 20 } !is_local !is_health_check
http-request tarpit deny_status 403 if { sc_http_err_rate(0) gt 20 } !is_local !is_trusted_ip !is_whitelisted !is_health_check
# IP blocking using map file (manual blocks only)
# Map file format: /etc/haproxy/blocked_ips.map contains "<ip_or_cidr> 1" per line

4
trusted_ips.list Normal file
View File

@@ -0,0 +1,4 @@
# Trusted IPs - one per line, supports CIDR
# These IPs bypass all rate limiting rules
# Phone system
172.116.197.166

4
trusted_ips.map Normal file
View File

@@ -0,0 +1,4 @@
# Trusted IPs map - format: <ip_or_cidr> 1
# Used for whitelisting IPs that arrive via proxy headers (real_ip)
# Phone system
172.116.197.166 1