Corrected the tarpit logic flow to work as intended:
1. Backend tracks 400/401/403/404 error responses via http-response
2. Counter increments AFTER the backend responds with an error
3. Frontend checks counter on SUBSEQUENT requests
4. Tarpit/blocking only applies after error thresholds are reached:
- 5+ errors: Potential scanner (no action yet)
- 15+ errors: Likely scanner (tarpit if also burst traffic)
- 30+ errors: Confirmed scanner (always tarpit)
- 50+ errors: Aggressive scanner (block with 429)
This ensures:
- Normal traffic is never delayed
- First requests always go through normally
- Only clients that accumulate errors get progressively slowed/blocked
- The tarpit is a response to bad behavior, not a preemptive measure
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
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 <noreply@anthropic.com>
- Remove duplicate http_err_rate entries (only one period allowed)
- Simplify to single http_err_rate(10s) for burst detection
- Fix sc0_http_err_rate ACL syntax (remove period argument)
- Replace time-based sustained/persistent attack detection with counter-based thresholds
- Use gpc0 counter thresholds for sustained (>=15) and persistent (>=30) attack detection
This resolves the configuration errors in HAProxy 3.0.11 while maintaining
effective exploit scanning protection through counter-based detection.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove gpc2 from stick-table (not supported in HAProxy 3.0)
- Fix ACL syntax: Change sc_get_gpc0(0) to sc0_get_gpc0
- Fix ACL syntax: Change sc_http_err_rate(0,period) to sc0_http_err_rate(period)
- Fix ACL syntax: Change sc_get_gpc1(0) to sc0_get_gpc1
- Reorder rules to place http-request rules before use_backend rules
- Remove duplicate gpc2 increment rule
These changes ensure compatibility with HAProxy 3.0.11 while maintaining
the tarpit escalation functionality for exploit scanning protection.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement progressive tarpit delays and threat detection to slow down
attackers scanning for exploits. Features include:
- Stick table to track attacks with 2-hour expiry
- Escalating tarpit delays based on threat level and repeat offenses
- Threat level detection (low/medium/high/critical) based on scan attempts
- Rate-based attack detection for burst/sustained/persistent attacks
- Automatic scan attempt tracking via HTTP error responses (400/401/403/404)
- Detection of suspicious paths (admin panels, config files, etc.)
- Trusted network bypass for local/monitoring systems
- Progressive escalation levels that increase tarpit duration
- Critical threat blocking with 429 status
The system uses HAProxy's built-in tarpit mechanism to delay responses
up to 60 seconds for persistent attackers, effectively slowing down
vulnerability scanners while maintaining service for legitimate users.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Modified /blocked-ip route to return 403 Forbidden status with HTML page
- Added HAProxy reload after adding blocked IP to ensure consistency
- Added HAProxy reload after removing blocked IP to ensure consistency
- Includes error handling for reload failures without breaking the operation
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
**Template Changes:**
- Switch from direct denial to blocked page redirect with 403 status
- Blocked IPs now see /blocked-ip page instead of generic 403 denial
- Maintains proper 403 HTTP status code for blocked requests
**Blocked Page Updates:**
- Remove contact support button to prevent misuse
- Add clear instructions on how to request unblocking
- Provide structured guidance for contacting hosting provider
- Maintain professional appearance with helpful information
**Benefits:**
- Better user experience for legitimate blocks
- Clear instructions prevent support confusion
- Maintains security while being informative
- Professional appearance reflects well on hosting providers
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add blocked_ips database table to store blocked IP addresses
- Implement API endpoints for IP blocking management:
- GET /api/blocked-ips: List all blocked IPs
- POST /api/blocked-ips: Block an IP address
- DELETE /api/blocked-ips: Unblock an IP address
- Update HAProxy configuration generation to include blocked IP ACLs
- Create blocked IP page template for denied access
- Add comprehensive API documentation for WHP integration
- Include test script for IP blocking functionality
- Update .gitignore with Python patterns
- Add CLAUDE.md for codebase documentation
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add configuration regeneration before HAProxy startup
- Add configuration validation before starting HAProxy
- Add automatic configuration regeneration if invalid config detected
- Prevent container crashes when HAProxy fails to start
- Allow container to continue running even if HAProxy is not available
- Add better error handling and logging for startup issues
- Replace http-response set-body (HAProxy 2.8+) with local server approach
- Add separate Flask server on port 8080 to serve default page
- Update default backend template to use local server instead of inline HTML
- Maintain all customization features via environment variables
- Fix JavaScript error handling for domains API response