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:
@@ -53,6 +53,7 @@ mkdir -p "$TEMP_DIR" "$SNAPSHOT_DIR" 2>/dev/null
|
|||||||
touch "$TEMP_DIR/recent_events"
|
touch "$TEMP_DIR/recent_events"
|
||||||
touch "$TEMP_DIR/ip_data"
|
touch "$TEMP_DIR/ip_data"
|
||||||
echo "0" > "$TEMP_DIR/event_counter"
|
echo "0" > "$TEMP_DIR/event_counter"
|
||||||
|
echo "0" > "$TEMP_DIR/total_blocks"
|
||||||
|
|
||||||
# Save snapshot of IP data (for persistence across restarts)
|
# Save snapshot of IP data (for persistence across restarts)
|
||||||
save_snapshot() {
|
save_snapshot() {
|
||||||
@@ -1887,17 +1888,27 @@ detect_distributed_attacks() {
|
|||||||
auto_mitigation_engine() {
|
auto_mitigation_engine() {
|
||||||
# Run in background, check every 10 seconds
|
# Run in background, check every 10 seconds
|
||||||
(
|
(
|
||||||
|
# Track already blocked IPs in this session
|
||||||
|
declare -A BLOCKED_THIS_SESSION
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
sleep 10
|
sleep 10
|
||||||
|
|
||||||
# Auto-block IPs that reach CRITICAL threshold
|
# Read current IP data from snapshot file (updated by main process)
|
||||||
for ip in "${!IP_DATA[@]}"; do
|
if [ -f "$TEMP_DIR/ip_data" ]; then
|
||||||
IFS='|' read -r score hits bot_type attacks ban_count rep_score <<< "${IP_DATA[$ip]}"
|
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
|
# Auto-block
|
||||||
local time_str=$(date +"%H:%M:%S")
|
local time_str=$(date +"%H:%M:%S")
|
||||||
echo -e "${CRITICAL_COLOR}[${time_str}] AUTO_BLOCK | $ip | Score:$score | ${attacks}${NC}" >> "$TEMP_DIR/recent_events"
|
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
|
fi
|
||||||
|
|
||||||
# Block for 1 hour with detailed reason
|
# 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
|
# Increment total blocks counter
|
||||||
ban_count=$((ban_count + 1))
|
local current_total=$(cat "$TEMP_DIR/total_blocks" 2>/dev/null || echo "0")
|
||||||
TOTAL_BLOCKS=$((TOTAL_BLOCKS + 1))
|
echo $((current_total + 1)) > "$TEMP_DIR/total_blocks"
|
||||||
IP_DATA[$ip]="$score|$hits|$bot_type|$attacks|$ban_count|$rep_score"
|
|
||||||
fi
|
fi
|
||||||
fi
|
done < "$TEMP_DIR/ip_data"
|
||||||
done
|
fi
|
||||||
done
|
done
|
||||||
) &
|
) &
|
||||||
}
|
}
|
||||||
@@ -1962,6 +1972,18 @@ while true; do
|
|||||||
draw_live_feed
|
draw_live_feed
|
||||||
draw_quick_actions
|
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)
|
# Periodic cleanup (every 50 loops = ~100 seconds)
|
||||||
((LOOP_COUNT++))
|
((LOOP_COUNT++))
|
||||||
if [ $((LOOP_COUNT % 50)) -eq 0 ]; then
|
if [ $((LOOP_COUNT % 50)) -eq 0 ]; then
|
||||||
|
|||||||
Reference in New Issue
Block a user