From 53d259bd3f909a65a79612eb8e8f0b9a3172e06b Mon Sep 17 00:00:00 2001 From: Josh Knapp Date: Tue, 31 Mar 2026 13:39:41 -0700 Subject: [PATCH] Add trusted IP whitelist for rate limit bypass 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) --- Dockerfile | 2 ++ templates/hap_listener.tpl | 14 ++++++++------ trusted_ips.list | 4 ++++ trusted_ips.map | 4 ++++ 4 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 trusted_ips.list create mode 100644 trusted_ips.map diff --git a/Dockerfile b/Dockerfile index a36e94c..b1dc26d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 diff --git a/templates/hap_listener.tpl b/templates/hap_listener.tpl index 0bad0d3..b7b5595 100644 --- a/templates/hap_listener.tpl +++ b/templates/hap_listener.tpl @@ -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 " 1" per line diff --git a/trusted_ips.list b/trusted_ips.list new file mode 100644 index 0000000..a4b8273 --- /dev/null +++ b/trusted_ips.list @@ -0,0 +1,4 @@ +# Trusted IPs - one per line, supports CIDR +# These IPs bypass all rate limiting rules +# Phone system +172.116.197.166 diff --git a/trusted_ips.map b/trusted_ips.map new file mode 100644 index 0000000..2a54be0 --- /dev/null +++ b/trusted_ips.map @@ -0,0 +1,4 @@ +# Trusted IPs map - format: 1 +# Used for whitelisting IPs that arrive via proxy headers (real_ip) +# Phone system +172.116.197.166 1