Reduce EWMA false positives with min_pps threshold
- Add min_pps (default 20) to skip anomaly detection for low-traffic IPs - Increase threshold_multiplier from 3.0 to 5.0 - Increase rate_limit_after from 1 to 3 violations - Support min_pps in SIGHUP config reload Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -79,7 +79,8 @@ DEFAULT_CONFIG = {
|
||||
'ewma': {
|
||||
'alpha': 0.3,
|
||||
'poll_interval': 1,
|
||||
'threshold_multiplier': 3.0,
|
||||
'threshold_multiplier': 5.0,
|
||||
'min_pps': 20,
|
||||
},
|
||||
'ai': {
|
||||
'enabled': True,
|
||||
@@ -170,9 +171,10 @@ class ViolationTracker:
|
||||
class EWMAAnalyzer:
|
||||
"""Per-IP EWMA calculation for rate anomaly detection."""
|
||||
|
||||
def __init__(self, alpha=0.3, threshold_multiplier=3.0):
|
||||
def __init__(self, alpha=0.3, threshold_multiplier=5.0, min_pps=20):
|
||||
self.alpha = alpha
|
||||
self.threshold_multiplier = threshold_multiplier
|
||||
self.min_pps = min_pps
|
||||
self.ewma = {}
|
||||
self.baseline = {}
|
||||
self.lock = threading.Lock()
|
||||
@@ -188,6 +190,9 @@ class EWMAAnalyzer:
|
||||
self.ewma[ip] = self.alpha * current_pps + (1 - self.alpha) * self.ewma[ip]
|
||||
self.baseline[ip] = 0.01 * current_pps + 0.99 * self.baseline[ip]
|
||||
|
||||
if current_pps < self.min_pps:
|
||||
return False
|
||||
|
||||
base = max(self.baseline[ip], 1)
|
||||
if self.ewma[ip] > base * self.threshold_multiplier:
|
||||
return True
|
||||
@@ -614,7 +619,8 @@ class DDoSDaemon:
|
||||
self.violation_tracker = ViolationTracker(self.cfg['escalation'])
|
||||
self.ewma_analyzer = EWMAAnalyzer(
|
||||
alpha=self.cfg['ewma'].get('alpha', 0.3),
|
||||
threshold_multiplier=self.cfg['ewma'].get('threshold_multiplier', 3.0),
|
||||
threshold_multiplier=self.cfg['ewma'].get('threshold_multiplier', 5.0),
|
||||
min_pps=self.cfg['ewma'].get('min_pps', 20),
|
||||
)
|
||||
self.ai_detector = AIDetector(self.cfg['ai'])
|
||||
self.profile_manager = ProfileManager(self.cfg['rate_limits'])
|
||||
@@ -673,7 +679,8 @@ class DDoSDaemon:
|
||||
# Build all new values before swapping anything
|
||||
new_escalation = new_cfg['escalation']
|
||||
new_alpha = new_cfg['ewma'].get('alpha', 0.3)
|
||||
new_threshold = new_cfg['ewma'].get('threshold_multiplier', 3.0)
|
||||
new_threshold = new_cfg['ewma'].get('threshold_multiplier', 5.0)
|
||||
new_min_pps = new_cfg['ewma'].get('min_pps', 20)
|
||||
new_ai_cfg = new_cfg['ai']
|
||||
new_rate_cfg = new_cfg['rate_limits']
|
||||
new_ewma_interval = new_cfg['ewma'].get('poll_interval', 1)
|
||||
@@ -684,6 +691,7 @@ class DDoSDaemon:
|
||||
self.violation_tracker.cfg = new_escalation
|
||||
self.ewma_analyzer.alpha = new_alpha
|
||||
self.ewma_analyzer.threshold_multiplier = new_threshold
|
||||
self.ewma_analyzer.min_pps = new_min_pps
|
||||
self.ai_detector.cfg = new_ai_cfg
|
||||
self.profile_manager.cfg = new_rate_cfg
|
||||
self._ewma_interval = new_ewma_interval
|
||||
|
||||
Reference in New Issue
Block a user