Add CDN filter and fix xdp-cdn-update bugs
- Add xdp_cdn_filter BPF program (priority 5) to allow only CDN/whitelist on port 80/443 - Fix \r carriage return bug preventing BunnyCDN IPv4 loading (594 IPs were silently failing) - Fix BPF map flush code to handle list-type keys from bpftool JSON output - Fix per-cpu stats parsing to use formatted values from bpftool - Replace in-loop counter with post-load BPF map verification for accurate counts - Remove xdp_cdn_load.py (consolidated into xdp-cdn-update) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -631,6 +631,9 @@ class DDoSDaemon:
|
||||
self._last_retrain_time = self._get_model_mtime()
|
||||
self._last_log_cleanup = time.time()
|
||||
|
||||
self._blocked_ips = set()
|
||||
self._blocked_ips_lock = threading.Lock()
|
||||
|
||||
self._init_traffic_db()
|
||||
|
||||
level = self.cfg['general'].get('log_level', 'info').upper()
|
||||
@@ -830,19 +833,33 @@ class DDoSDaemon:
|
||||
)
|
||||
|
||||
if level == 'temp_block':
|
||||
dur = self.cfg['escalation'].get('temp_block_duration', 300)
|
||||
try:
|
||||
block_ip(ip_str, dur)
|
||||
log.warning("TEMP BLOCK: %s for %ds", ip_str, dur)
|
||||
except Exception as e:
|
||||
log.error("Failed to temp-block %s: %s", ip_str, e)
|
||||
with self._blocked_ips_lock:
|
||||
already = ip_str in self._blocked_ips
|
||||
if already:
|
||||
log.debug("EWMA skip (already blocked): %s", ip_str)
|
||||
else:
|
||||
dur = self.cfg['escalation'].get('temp_block_duration', 300)
|
||||
try:
|
||||
block_ip(ip_str, dur)
|
||||
with self._blocked_ips_lock:
|
||||
self._blocked_ips.add(ip_str)
|
||||
log.warning("TEMP BLOCK: %s for %ds", ip_str, dur)
|
||||
except Exception as e:
|
||||
log.error("Failed to temp-block %s: %s", ip_str, e)
|
||||
|
||||
elif level == 'perm_block':
|
||||
try:
|
||||
block_ip(ip_str, 0)
|
||||
log.warning("PERM BLOCK: %s", ip_str)
|
||||
except Exception as e:
|
||||
log.error("Failed to perm-block %s: %s", ip_str, e)
|
||||
with self._blocked_ips_lock:
|
||||
already = ip_str in self._blocked_ips
|
||||
if already:
|
||||
log.debug("EWMA skip (already blocked): %s", ip_str)
|
||||
else:
|
||||
try:
|
||||
block_ip(ip_str, 0)
|
||||
with self._blocked_ips_lock:
|
||||
self._blocked_ips.add(ip_str)
|
||||
log.warning("PERM BLOCK: %s", ip_str)
|
||||
except Exception as e:
|
||||
log.error("Failed to perm-block %s: %s", ip_str, e)
|
||||
|
||||
self.ewma_analyzer.cleanup_stale(active_ips)
|
||||
|
||||
@@ -970,19 +987,33 @@ class DDoSDaemon:
|
||||
log.warning("AI escalation: %s ewma=%.1f baseline=%.1f -> %s", ip_str, ewma, baseline, level)
|
||||
|
||||
if level == 'temp_block':
|
||||
dur = self.cfg['escalation'].get('temp_block_duration', 300)
|
||||
try:
|
||||
block_ip(ip_str, dur)
|
||||
log.warning("AI TEMP BLOCK: %s for %ds", ip_str, dur)
|
||||
except Exception as e:
|
||||
log.error("Failed to AI temp-block %s: %s", ip_str, e)
|
||||
with self._blocked_ips_lock:
|
||||
already = ip_str in self._blocked_ips
|
||||
if already:
|
||||
log.debug("AI skip (already blocked): %s", ip_str)
|
||||
else:
|
||||
dur = self.cfg['escalation'].get('temp_block_duration', 300)
|
||||
try:
|
||||
block_ip(ip_str, dur)
|
||||
with self._blocked_ips_lock:
|
||||
self._blocked_ips.add(ip_str)
|
||||
log.warning("AI TEMP BLOCK: %s for %ds", ip_str, dur)
|
||||
except Exception as e:
|
||||
log.error("Failed to AI temp-block %s: %s", ip_str, e)
|
||||
|
||||
elif level == 'perm_block':
|
||||
try:
|
||||
block_ip(ip_str, 0)
|
||||
log.warning("AI PERM BLOCK: %s", ip_str)
|
||||
except Exception as e:
|
||||
log.error("Failed to AI perm-block %s: %s", ip_str, e)
|
||||
with self._blocked_ips_lock:
|
||||
already = ip_str in self._blocked_ips
|
||||
if already:
|
||||
log.debug("AI skip (already blocked): %s", ip_str)
|
||||
else:
|
||||
try:
|
||||
block_ip(ip_str, 0)
|
||||
with self._blocked_ips_lock:
|
||||
self._blocked_ips.add(ip_str)
|
||||
log.warning("AI PERM BLOCK: %s", ip_str)
|
||||
except Exception as e:
|
||||
log.error("Failed to AI perm-block %s: %s", ip_str, e)
|
||||
|
||||
prev_features = features
|
||||
|
||||
@@ -1014,6 +1045,8 @@ class DDoSDaemon:
|
||||
try:
|
||||
unblock_ip(ip_str)
|
||||
self.violation_tracker.clear(ip_str)
|
||||
with self._blocked_ips_lock:
|
||||
self._blocked_ips.discard(ip_str)
|
||||
log.info("Expired block removed: %s (dropped %d pkts)", ip_str, drop_count)
|
||||
except Exception as e:
|
||||
log.error("Failed to remove expired block %s: %s", ip_str, e)
|
||||
|
||||
Reference in New Issue
Block a user