From de3a68b59c87a435552a01063c4892da49c85861 Mon Sep 17 00:00:00 2001 From: jknapp Date: Sat, 23 Aug 2025 18:44:19 -0700 Subject: [PATCH] Fix tarpit applying to all connections - use proper threat ranges MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous configuration was tarpiting all connections because the ACLs were overlapping (e.g., low_threat >= 3 would match everything above 3). Changes: - Add proper range checks for threat levels (e.g., >= 3 AND < 10 for low) - Simplify tarpit logic to only apply when scan attempts are detected - Remove complex escalation levels (not working properly in HAProxy 3.0) - Only tarpit connections with 3+ scan attempts or burst attacks - Critical threats (50+ attempts) get immediate 429 block This ensures normal traffic flows through without delay while actual scanners and attackers get tarpited based on their behavior. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- templates/hap_listener.tpl | 47 +++++++++++--------------------------- 1 file changed, 13 insertions(+), 34 deletions(-) diff --git a/templates/hap_listener.tpl b/templates/hap_listener.tpl index 66a8f17..48bc941 100644 --- a/templates/hap_listener.tpl +++ b/templates/hap_listener.tpl @@ -26,45 +26,24 @@ frontend web use_backend default-backend if { src -f /etc/haproxy/blocked_ips.map } # Define threat levels based on scan attempts and rates - acl low_threat sc0_get_gpc0 ge 3 - acl medium_threat sc0_get_gpc0 ge 10 - acl high_threat sc0_get_gpc0 ge 25 + acl has_scan_attempts sc0_get_gpc0 gt 0 + acl low_threat sc0_get_gpc0 ge 3 sc0_get_gpc0 lt 10 + acl medium_threat sc0_get_gpc0 ge 10 sc0_get_gpc0 lt 25 + acl high_threat sc0_get_gpc0 ge 25 sc0_get_gpc0 lt 50 acl critical_threat sc0_get_gpc0 ge 50 # Rate-based detection (burst attacks) - acl burst_attack sc0_http_err_rate gt 8 # >8 errors in 10 seconds - acl sustained_attack sc0_get_gpc0 ge 15 # Multiple sustained errors - acl persistent_attack sc0_get_gpc0 ge 30 # Persistent scanning + acl burst_attack sc0_http_err_rate gt 5 # >5 errors in 10 seconds - # Escalation levels (tracks how many times we've escalated this IP) - acl escalation_level_0 sc0_get_gpc1 eq 0 - acl escalation_level_1 sc0_get_gpc1 eq 1 - acl escalation_level_2 sc0_get_gpc1 eq 2 - acl escalation_level_3 sc0_get_gpc1 ge 3 + # Combined threat detection + acl is_threat has_scan_attempts + acl needs_tarpit low_threat or medium_threat or high_threat or burst_attack - # ESCALATING TARPIT RULES - # Level 1: Short tarpit (2-5 seconds) for first offense - http-request tarpit if low_threat escalation_level_0 - http-request tarpit if medium_threat escalation_level_0 - http-request tarpit if burst_attack escalation_level_0 + # TARPIT RULES - Only apply to actual threats + # Apply tarpit only if there are scan attempts + http-request tarpit if needs_tarpit - # Level 2: Medium tarpit (8-15 seconds) for second offense - http-request tarpit if low_threat escalation_level_1 - http-request tarpit if medium_threat escalation_level_1 - http-request tarpit if high_threat escalation_level_1 - http-request tarpit if sustained_attack escalation_level_1 - - # Level 3: Long tarpit (20-45 seconds) for repeat offenders - http-request tarpit if low_threat escalation_level_2 - http-request tarpit if medium_threat escalation_level_2 - http-request tarpit if high_threat escalation_level_2 - http-request tarpit if persistent_attack escalation_level_2 - - # Level 4: Maximum tarpit (60 seconds) for persistent attackers - http-request tarpit if escalation_level_3 - - # Complete block for critical threats regardless of escalation level + # Complete block for critical threats http-request deny deny_status 429 if critical_threat - # Increment escalation level when we apply tarpit/block - http-request sc-inc-gpc1(0) if low_threat or medium_threat or high_threat or burst_attack or sustained_attack or persistent_attack + # Increment scan counter when tarpit is applied (this happens after response in backend)