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
This commit is contained in:
cschantz
2025-11-14 20:02:12 -05:00
parent 29628fe1ca
commit 0707c70c8b
+36 -14
View File
@@ -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