diff --git a/Dockerfile b/Dockerfile index 14a8d2f..a36e94c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,6 +18,6 @@ RUN mkdir -p /var/spool/cron/crontabs && \ chown root:crontab /var/spool/cron/crontabs/root EXPOSE 80 443 8000 # Add health check -HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD curl -f http://localhost:8000/health || exit 1 +HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ + CMD curl -sf --max-time 5 http://localhost:8000/health && curl -s --max-time 5 -o /dev/null http://localhost/ || exit 1 CMD ["/haproxy/scripts/start-up.sh"] \ No newline at end of file diff --git a/templates/hap_header.tpl b/templates/hap_header.tpl index 084d8c2..bfe0333 100644 --- a/templates/hap_header.tpl +++ b/templates/hap_header.tpl @@ -27,6 +27,10 @@ global # SSL and Performance tune.ssl.default-dh-param 2048 + # HTTP/2 protection against Rapid Reset (CVE-2023-44487) and stream abuse + tune.h2.fe.max-total-streams 2000 + tune.h2.fe.glitches-threshold 50 + # Stats persistence for zero-downtime reloads stats-file /var/lib/haproxy/stats.dat #--------------------------------------------------------------------- @@ -42,12 +46,12 @@ defaults option forwardfor #except 127.0.0.0/8 option redispatch retries 3 - timeout http-request 300s + timeout http-request 30s timeout queue 2m - timeout connect 120s - timeout client 10m + timeout connect 10s + timeout client 5m timeout server 10m - timeout http-keep-alive 120s + timeout http-keep-alive 30s timeout check 10s timeout tarpit 10s # Tarpit delay for low-level scanners (before silent-drop) maxconn 3000 diff --git a/templates/hap_listener.tpl b/templates/hap_listener.tpl index d5b39b0..56b2d08 100644 --- a/templates/hap_listener.tpl +++ b/templates/hap_listener.tpl @@ -19,6 +19,26 @@ frontend web 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 + # --- Connection & rate tracking --- + 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 + 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_health_check path_beg /.well-known/acme-challenge + + # --- 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 + # 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 + # Connection rate limit: >60 new connections per 10s per IP + http-request deny deny_status 429 if { sc_conn_rate(0) gt 60 } !is_local !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 + # 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 + # IP blocking using map file (manual blocks only) # Map file format: /etc/haproxy/blocked_ips.map contains " 1" per line # Runtime updates: echo "add map #0 IP_ADDRESS 1" | socat stdio /var/run/haproxy.sock diff --git a/templates/hap_security_tables.tpl b/templates/hap_security_tables.tpl index b9dd256..414e4c4 100644 --- a/templates/hap_security_tables.tpl +++ b/templates/hap_security_tables.tpl @@ -1,7 +1,8 @@ -# HAProxy 3.0.11 eliminates need for separate security tables -# All threat intelligence is now consolidated in the main frontend table -# using array-based GPC system with 15 threat indicators - -# Placeholder for future security extensions -# The main table in hap_listener.tpl now provides comprehensive -# multi-dimensional threat tracking with weighted scoring \ No newline at end of file +# HAProxy Stats & Monitoring +frontend stats + bind 127.0.0.1:8404 + stats enable + stats uri /stats + stats refresh 30s + stats show-legends + stats show-node \ No newline at end of file