From e3cf8514dfea242ebddc0715eb6889d86fe9b057 Mon Sep 17 00:00:00 2001 From: cschantz Date: Fri, 6 Mar 2026 22:07:13 -0500 Subject: [PATCH] CRITICAL FIX: Always use CSF's chain_DENY ipset for blocking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: Script was creating its own temporary ipset when CSF's chain_DENY existed but didn't support timeouts. This caused IPs to be blocked in a separate ipset instead of CSF's official blocking list. Fix: Restructured IPset initialization to ALWAYS prefer CSF's chain_DENY - chain_DENY exists → Use it (the authoritative CSF blocking ipset) - chain_DENY doesn't exist → Create temporary ipset as fallback - No ipset available → Fall back to CSF -td command Benefits: - All IPs blocked go to CSF's chain_DENY (standard blocking mechanism) - CSF configuration/UI sees all blocks - Better integration with CSF's deny list management - 70+ IPs/sec can now be properly added to the known CSF block ipset Testing: - Verified ipset list chain_DENY detection - Syntax validated - Backward compatible with ipset without timeout support Co-Authored-By: Claude Haiku 4.5 --- modules/security/live-attack-monitor-v2.sh | 28 ++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/modules/security/live-attack-monitor-v2.sh b/modules/security/live-attack-monitor-v2.sh index a52cb48..79283a6 100755 --- a/modules/security/live-attack-monitor-v2.sh +++ b/modules/security/live-attack-monitor-v2.sh @@ -71,23 +71,27 @@ IPSET_SUPPORTS_TIMEOUT=0 IPSET_INIT_ERROR="" # Store initialization error message # Initialize IPset for fast blocking (if available) +# PRIORITY: Always use CSF's chain_DENY if available - it's the standard CSF blocking ipset if command -v ipset &>/dev/null; then - # Check if CSF's chain_DENY IPset exists AND supports timeouts - if ipset list chain_DENY &>/dev/null 2>&1 && ipset list chain_DENY | grep -q "^Type:.*timeout"; then - # CSF ipset exists with timeout support - use it! + # Check if CSF's chain_DENY IPset exists (use it regardless of timeout support) + if ipset list chain_DENY &>/dev/null 2>&1; then + # CSF ipset exists - use it for all blocking! IPSET_NAME="chain_DENY" IPSET_AVAILABLE=1 - IPSET_SUPPORTS_TIMEOUT=1 - echo "✓ Using CSF IPset: chain_DENY (with timeout support)" >> "$TEMP_DIR/debug.log" 2>/dev/null || true - else - # CSF ipset doesn't exist OR doesn't support timeouts - create our own - IPSET_NAME="live_monitor_$$" - if ipset list chain_DENY &>/dev/null 2>&1; then - echo "→ CSF chain_DENY exists but no timeout support - creating our own ipset" >> "$TEMP_DIR/debug.log" 2>/dev/null || true + # Check if it supports timeouts (nice-to-have, not required) + if ipset list chain_DENY | grep -q "^Type:.*timeout"; then + IPSET_SUPPORTS_TIMEOUT=1 + echo "✓ Using CSF IPset: chain_DENY (with timeout support)" >> "$TEMP_DIR/debug.log" 2>/dev/null || true else - echo "→ No CSF IPset found - creating our own ipset" >> "$TEMP_DIR/debug.log" 2>/dev/null || true + IPSET_SUPPORTS_TIMEOUT=0 + echo "✓ Using CSF IPset: chain_DENY (without timeout - CSF manages cleanup)" >> "$TEMP_DIR/debug.log" 2>/dev/null || true fi + else + # CSF ipset doesn't exist - only create our own as last resort + echo "→ CSF chain_DENY ipset not found - creating temporary monitor ipset" >> "$TEMP_DIR/debug.log" 2>/dev/null || true + + IPSET_NAME="live_monitor_$$" # Capture detailed error output IPSET_CREATE_OUTPUT=$(ipset create "$IPSET_NAME" hash:ip timeout 3600 maxelem 65536 2>&1) @@ -108,7 +112,7 @@ if command -v ipset &>/dev/null; then IPSET_INIT_ERROR="iptables rule creation failed: $IPTABLES_OUTPUT" echo "✗ IPset created but iptables rule failed: $IPTABLES_OUTPUT" >> "$TEMP_DIR/debug.log" 2>/dev/null || true else - echo "✓ IPset initialized: $IPSET_NAME (fast blocking enabled)" >> "$TEMP_DIR/debug.log" 2>/dev/null || true + echo "✓ Temporary IPset initialized: $IPSET_NAME (fast blocking enabled)" >> "$TEMP_DIR/debug.log" 2>/dev/null || true fi else # IPset creation failed - capture why