Add comprehensive anti-scan and brute force protection
All checks were successful
HAProxy Manager Build and Push / Build-and-Push (push) Successful in 54s

Implement multi-layered security system to protect against exploit
scanning and brute force attacks while maintaining legitimate traffic flow.

Security Features:
- Attack detection for common exploit paths (WordPress, phpMyAdmin, shells)
- Malicious user agent filtering (sqlmap, nikto, metasploit, etc.)
- SQL injection and directory traversal pattern detection
- Progressive rate limiting (50 req/10s, 20 conn/10s, 10 err/10s)
- Three-tier response: tarpit → deny → repeat offender blocking
- Strict authentication endpoint protection (5 req/10s limit)
- Real IP detection through proxy headers (Cloudflare, X-Real-IP)

Management Tools:
- manage-blocked-ips.sh: Dynamic IP blocking/unblocking
- monitor-attacks.sh: Real-time threat monitoring
- API endpoints for security stats and temporary blocking
- Auto-expiring temporary blocks with cleanup endpoint

HAProxy 2.6 Compatibility:
- Removed silent-drop (not available in 2.6)
- Fixed stick table counter syntax
- Using standard tarpit and deny actions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-22 16:50:35 -07:00
parent 002e79b565
commit e2f350ce95
4 changed files with 388 additions and 12 deletions

68
scripts/manage-blocked-ips.sh Executable file
View File

@@ -0,0 +1,68 @@
#!/bin/bash
# HAProxy IP blocking management script
# Usage: ./manage-blocked-ips.sh [block|unblock|list|clear] [IP_ADDRESS]
SOCKET="/tmp/haproxy-cli"
MAP_FILE="/etc/haproxy/blocked_ips.map"
# Ensure map file exists
if [ ! -f "$MAP_FILE" ]; then
touch "$MAP_FILE"
echo "# Blocked IPs - Format: IP_ADDRESS" > "$MAP_FILE"
fi
case "$1" in
block)
if [ -z "$2" ]; then
echo "Usage: $0 block IP_ADDRESS"
exit 1
fi
# Add IP to map file
grep -q "^$2" "$MAP_FILE" || echo "$2" >> "$MAP_FILE"
# Add to runtime map
echo "add map /etc/haproxy/blocked_ips.map $2 1" | socat stdio "$SOCKET"
echo "Blocked IP: $2"
;;
unblock)
if [ -z "$2" ]; then
echo "Usage: $0 unblock IP_ADDRESS"
exit 1
fi
# Remove from map file
sed -i "/^$2$/d" "$MAP_FILE"
# Remove from runtime map
echo "del map /etc/haproxy/blocked_ips.map $2" | socat stdio "$SOCKET"
echo "Unblocked IP: $2"
;;
list)
echo "Currently blocked IPs:"
echo "show map /etc/haproxy/blocked_ips.map" | socat stdio "$SOCKET" | awk '{print $1}'
;;
clear)
echo "Clearing all blocked IPs..."
echo "clear map /etc/haproxy/blocked_ips.map" | socat stdio "$SOCKET"
echo "# Blocked IPs - Format: IP_ADDRESS" > "$MAP_FILE"
echo "All IPs unblocked"
;;
stats)
echo "Stick table statistics (showing potential bad actors):"
echo "show table web" | socat stdio "$SOCKET" | head -50
;;
*)
echo "Usage: $0 {block|unblock|list|clear|stats} [IP_ADDRESS]"
echo ""
echo "Commands:"
echo " block IP - Block an IP address"
echo " unblock IP - Unblock an IP address"
echo " list - List all blocked IPs"
echo " clear - Clear all blocked IPs"
echo " stats - Show current stick table stats"
exit 1
;;
esac

73
scripts/monitor-attacks.sh Executable file
View File

@@ -0,0 +1,73 @@
#!/bin/bash
# Real-time attack monitoring for HAProxy
# Shows blocked requests and suspicious activity
LOG_FILE="/var/log/haproxy.log"
SOCKET="/tmp/haproxy-cli"
echo "==================================================="
echo "HAProxy Security Monitor - Real-time Attack Detection"
echo "==================================================="
echo ""
# Function to show current threats
show_threats() {
echo "Current Threat IPs (from stick table):"
echo "show table web" | socat stdio "$SOCKET" 2>/dev/null | \
awk '$4 > 0 || $5 > 0 || $6 > 30 || $7 > 5 || $8 > 10 {
printf "%-15s req_rate:%-3s err_rate:%-3s conn_rate:%-3s blocked:%s repeat:%s\n",
$1, $6, $7, $8, $4, $5
}' | head -20
echo "---------------------------------------------------"
}
# Function to show recent blocks
show_recent_blocks() {
echo "Recent Blocked Requests:"
tail -100 "$LOG_FILE" 2>/dev/null | \
grep -E "(scanner|exploit|ratelimit|repeat|tarpit|denied|dropped)" | \
tail -10 | \
awk '{
if (match($0, /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+/)) {
ip = substr($0, RSTART, RLENGTH)
gsub(/:.*/, "", ip)
reason = ""
if ($0 ~ /scanner/) reason = "SCANNER"
else if ($0 ~ /exploit/) reason = "EXPLOIT"
else if ($0 ~ /ratelimit/) reason = "RATE_LIMIT"
else if ($0 ~ /repeat/) reason = "REPEAT_OFFENDER"
else if ($0 ~ /tarpit/) reason = "TARPIT"
else if ($0 ~ /denied/) reason = "DENIED"
else if ($0 ~ /dropped/) reason = "DROPPED"
printf "[%s] %-15s %s\n", strftime("%H:%M:%S"), ip, reason
}
}'
echo ""
}
# Monitor mode selection
if [ "$1" == "live" ]; then
echo "Live monitoring mode - Press Ctrl+C to exit"
echo ""
while true; do
clear
echo "==================================================="
echo "HAProxy Security Monitor - $(date '+%Y-%m-%d %H:%M:%S')"
echo "==================================================="
echo ""
show_threats
echo ""
show_recent_blocks
sleep 5
done
else
# Single run mode
show_threats
echo ""
show_recent_blocks
echo ""
echo "Tip: Run with 'live' parameter for continuous monitoring"
echo "Usage: $0 [live]"
fi