Add distributed DDoS detection with dynamic thresholds
CRITICAL FIX for botnet-style attacks USER REPORT: "512 SYN_RECV connections but live monitor only shows 2 IPs" ROOT CAUSE: Threshold was hardcoded at >20 connections per IP. This works for focused attacks (one IP, many connections) but FAILS for distributed DDoS where 50+ IPs each send 5-15 connections. Example from user's attack: - 512 total SYN_RECV connections - Spread across 40+ attacker IPs - Top attacker: 107 packets (likely <20 active connections) - Result: NONE detected, server getting hammered SOLUTION - Dynamic Threshold: 1. Total SYN_RECV Detection (line 2226) Count total SYN_RECV across all IPs If > 100 total → distributed_attack mode activated 2. Adaptive Thresholds (lines 2247-2253) NORMAL MODE: threshold = 20 connections - Focused attack (1-2 IPs) - High bar to avoid false positives DISTRIBUTED MODE: threshold = 5 connections - Botnet attack (many IPs) - Catches participants in coordinated attack - Triggers when total > 100 DETECTION EXAMPLES: Focused Attack (unchanged behavior): - 1 IP with 150 SYN_RECV - Total: 150, threshold: 20 - Result: 1 IP detected, blocked Distributed Botnet (NEW): - 50 IPs each with 10 SYN_RECV - Total: 500, threshold: 5 (distributed mode) - Result: ALL 50 IPs detected, reputation tracked - Progressive blocking as scores accumulate User's Attack (512 total): - distributed_attack = 1 (512 > 100) - threshold = 5 - All IPs with >5 connections now tracked - Likely catches 30-40 of the attackers This allows catching both attack patterns without flooding the system with false positives during normal traffic.
This commit is contained in:
@@ -2222,6 +2222,15 @@ monitor_network_attacks() {
|
||||
while true; do
|
||||
# Use ss if available (faster), otherwise netstat
|
||||
if command -v ss &>/dev/null; then
|
||||
# Get total SYN_RECV count for distributed attack detection
|
||||
local total_syn=$(ss -tn state syn-recv 2>/dev/null | wc -l)
|
||||
local distributed_attack=0
|
||||
|
||||
# Distributed DDoS detection: Many IPs with small counts
|
||||
if [ "$total_syn" -gt 100 ]; then
|
||||
distributed_attack=1
|
||||
fi
|
||||
|
||||
# Count SYN_RECV connections per IP (sign of SYN flood)
|
||||
while read -r ip count; do
|
||||
# Skip local/private IPs first
|
||||
@@ -2235,7 +2244,15 @@ monitor_network_attacks() {
|
||||
# Track connection count for this IP
|
||||
CONNECTION_COUNT[$ip]=$count
|
||||
|
||||
if [ "$count" -gt 20 ]; then # More than 20 SYN_RECV connections = DDoS
|
||||
# Dynamic threshold based on attack type:
|
||||
# - Normal: >20 connections (focused attack)
|
||||
# - Distributed DDoS: >5 connections (botnet)
|
||||
local threshold=20
|
||||
if [ "$distributed_attack" -eq 1 ]; then
|
||||
threshold=5 # Lower threshold during distributed attacks
|
||||
fi
|
||||
|
||||
if [ "$count" -gt "$threshold" ]; then
|
||||
# Only process once per detection window
|
||||
if [ -z "${ALERT_SENT[$ip]}" ]; then
|
||||
ALERT_SENT[$ip]=1
|
||||
|
||||
@@ -2222,6 +2222,15 @@ monitor_network_attacks() {
|
||||
while true; do
|
||||
# Use ss if available (faster), otherwise netstat
|
||||
if command -v ss &>/dev/null; then
|
||||
# Get total SYN_RECV count for distributed attack detection
|
||||
local total_syn=$(ss -tn state syn-recv 2>/dev/null | wc -l)
|
||||
local distributed_attack=0
|
||||
|
||||
# Distributed DDoS detection: Many IPs with small counts
|
||||
if [ "$total_syn" -gt 100 ]; then
|
||||
distributed_attack=1
|
||||
fi
|
||||
|
||||
# Count SYN_RECV connections per IP (sign of SYN flood)
|
||||
while read -r ip count; do
|
||||
# Skip local/private IPs first
|
||||
@@ -2235,7 +2244,15 @@ monitor_network_attacks() {
|
||||
# Track connection count for this IP
|
||||
CONNECTION_COUNT[$ip]=$count
|
||||
|
||||
if [ "$count" -gt 20 ]; then # More than 20 SYN_RECV connections = DDoS
|
||||
# Dynamic threshold based on attack type:
|
||||
# - Normal: >20 connections (focused attack)
|
||||
# - Distributed DDoS: >5 connections (botnet)
|
||||
local threshold=20
|
||||
if [ "$distributed_attack" -eq 1 ]; then
|
||||
threshold=5 # Lower threshold during distributed attacks
|
||||
fi
|
||||
|
||||
if [ "$count" -gt "$threshold" ]; then
|
||||
# Only process once per detection window
|
||||
if [ -z "${ALERT_SENT[$ip]}" ]; then
|
||||
ALERT_SENT[$ip]=1
|
||||
|
||||
Reference in New Issue
Block a user