From 0707c70c8be0a4b7f3ab0afe7716857035704737 Mon Sep 17 00:00:00 2001 From: cschantz Date: Fri, 14 Nov 2025 20:02:12 -0500 Subject: [PATCH] Fix auto-blocking: Use file-based IPC for background process CRITICAL FIX: Auto-mitigation engine was not blocking IPs Root Cause: - Auto-mitigation ran in subshell: ( ... ) & - Subshells cannot access parent's associative arrays (IP_DATA) - Engine was looping through empty array, blocking nothing - This is why IP with score 100 sat for minutes without blocking Solution: - Main loop writes IP_DATA to $TEMP_DIR/ip_data every 2 seconds - Auto-mitigation reads from file instead of array - Tracks BLOCKED_THIS_SESSION to prevent duplicates - Uses file-based counter for TOTAL_BLOCKS How It Works Now: 1. Main process: Updates IP_DATA array in memory 2. Main loop: Writes IP_DATA to temp file every refresh (2 sec) 3. Auto-mitigation (background): Reads file every 10 sec 4. Auto-mitigation: Blocks IPs with score >= 80 5. Auto-mitigation: Writes to total_blocks file 6. Main loop: Reads total_blocks to update display Performance: - File write every 2 sec (100-500 bytes, negligible) - File read every 10 sec by background process - No CSF reload needed (csf -td is instant) This finally enables automatic blocking at score >= 80 --- modules/security/live-attack-monitor.sh | 50 ++++++++++++++++++------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/modules/security/live-attack-monitor.sh b/modules/security/live-attack-monitor.sh index 69521ad..fb82f3f 100755 --- a/modules/security/live-attack-monitor.sh +++ b/modules/security/live-attack-monitor.sh @@ -53,6 +53,7 @@ mkdir -p "$TEMP_DIR" "$SNAPSHOT_DIR" 2>/dev/null touch "$TEMP_DIR/recent_events" touch "$TEMP_DIR/ip_data" echo "0" > "$TEMP_DIR/event_counter" +echo "0" > "$TEMP_DIR/total_blocks" # Save snapshot of IP data (for persistence across restarts) save_snapshot() { @@ -1887,17 +1888,27 @@ detect_distributed_attacks() { auto_mitigation_engine() { # Run in background, check every 10 seconds ( + # Track already blocked IPs in this session + declare -A BLOCKED_THIS_SESSION + while true; do sleep 10 - # Auto-block IPs that reach CRITICAL threshold - for ip in "${!IP_DATA[@]}"; do - IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "${IP_DATA[$ip]}" + # Read current IP data from snapshot file (updated by main process) + if [ -f "$TEMP_DIR/ip_data" ]; then + while IFS='=' read -r ip data; do + [ -z "$ip" ] && continue + + IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "$data" + + # Auto-block at score >= 80 (CRITICAL) + if [ "$score" -ge 80 ]; then + # Skip if already blocked in this session + [ -n "${BLOCKED_THIS_SESSION[$ip]}" ] && continue + + # Mark as blocked to prevent duplicate attempts + BLOCKED_THIS_SESSION[$ip]=1 - # Auto-block at score >= 80 (CRITICAL) - if [ "$score" -ge 80 ]; then - # Check if already blocked - if ! is_ip_blocked "$ip" 2>/dev/null; then # Auto-block local time_str=$(date +"%H:%M:%S") echo -e "${CRITICAL_COLOR}[${time_str}] AUTO_BLOCK | $ip | Score:$score | ${attacks}${NC}" >> "$TEMP_DIR/recent_events" @@ -1910,15 +1921,14 @@ auto_mitigation_engine() { fi # Block for 1 hour with detailed reason - block_ip_temporary "$ip" 1 "$block_reason" >/dev/null 2>&1 & + block_ip_temporary "$ip" 1 "$block_reason" & - # Update ban count and total blocks - ban_count=$((ban_count + 1)) - TOTAL_BLOCKS=$((TOTAL_BLOCKS + 1)) - IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score" + # Increment total blocks counter + local current_total=$(cat "$TEMP_DIR/total_blocks" 2>/dev/null || echo "0") + echo $((current_total + 1)) > "$TEMP_DIR/total_blocks" fi - fi - done + done < "$TEMP_DIR/ip_data" + fi done ) & } @@ -1962,6 +1972,18 @@ while true; do draw_live_feed draw_quick_actions + # Write IP data to temp file for auto-mitigation engine (every loop) + { + for ip in "${!IP_DATA[@]}"; do + echo "$ip=${IP_DATA[$ip]}" + done + } > "$TEMP_DIR/ip_data" 2>/dev/null + + # Update total blocks from file + if [ -f "$TEMP_DIR/total_blocks" ]; then + TOTAL_BLOCKS=$(cat "$TEMP_DIR/total_blocks") + fi + # Periodic cleanup (every 50 loops = ~100 seconds) ((LOOP_COUNT++)) if [ $((LOOP_COUNT % 50)) -eq 0 ]; then