fix(dashboards): WAF bans cache and DPI LAN flow display

WAF Dashboard:
- Use cached bans from cron (waf-stats-update) instead of slow cscli
- Fixes "Failed to load bans" timeout issue

DPI Dual-Stream:
- Add LAN Flow Analysis card showing active clients, destinations, protocols
- LAN passive flow analysis was working but not displayed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-03-15 17:15:13 +01:00
parent 58ba852564
commit e1ee84b3eb
3 changed files with 32 additions and 25 deletions

View File

@ -157,6 +157,7 @@ return view.extend({
var mitm = status.mitm_stream || {};
var tap = status.tap_stream || {};
var corr = status.correlation || {};
var lan = status.lan_passive || {};
var view = E('div', { 'class': 'cbi-map', 'style': 'background:#0a0a12;min-height:100vh;' }, [
// Header
@ -249,7 +250,19 @@ return view.extend({
})
}, 'Correlate')
])
]), corr.running ? '#00d4aa' : '#808090')
]), corr.running ? '#00d4aa' : '#808090'),
// LAN Passive Flow Card
lan.enabled ? createCard('LAN Flow Analysis', '🌐', E('div', {}, [
E('div', { 'style': 'margin-bottom:0.8rem;' }, createStatusLED(lan.running)),
E('div', { 'style': 'display:flex;flex-wrap:wrap;gap:8px;' }, [
createMetric('Clients', lan.active_clients || 0, '#00d4aa'),
createMetric('Destinations', lan.unique_destinations || 0, '#00a0ff'),
createMetric('Protocols', lan.detected_protocols || 0, '#ffa500')
]),
E('div', { 'style': 'margin-top:8px;color:#808090;font-size:0.8rem;' },
'Interface: ' + (lan.interface || 'br-lan'))
]), lan.running ? '#00d4aa' : '#808090') : E('div')
]),
// Threats Table

View File

@ -650,30 +650,13 @@ sync_routes() {
}
get_bans() {
# Get CrowdSec decisions as JSON - limit to avoid timeout
# CAPI blocklists can have thousands of entries, so we only show local decisions
local bans_json="[]"
local total=0
local autoban=0
local crowdsec_count=0
if command -v cscli >/dev/null 2>&1; then
# Get local decisions only (WAF auto-bans) - these are what users care about
# Using --limit to prevent huge output from CAPI blocklists
bans_json=$(cscli decisions list -o json --limit 100 2>/dev/null)
if [ -z "$bans_json" ] || [ "$bans_json" = "null" ]; then
bans_json="[]"
else
# Count using grep on the raw JSON
total=$(echo "$bans_json" | grep -c '"id":' 2>/dev/null) || total=0
autoban=$(echo "$bans_json" | grep -c '"origin":.*"cscli"' 2>/dev/null) || autoban=0
crowdsec_count=$(echo "$bans_json" | grep -c '"origin":.*"crowdsec"' 2>/dev/null) || crowdsec_count=0
fi
# Read cached bans (updated every minute by cron)
local cache_file="/tmp/secubox/waf-bans.json"
if [ -f "$cache_file" ]; then
cat "$cache_file"
else
echo '{"success":true,"total":0,"mitmproxy_autoban":0,"crowdsec":0,"bans":[]}'
fi
# Build response with embedded bans array
printf '{"success":true,"total":%d,"mitmproxy_autoban":%d,"crowdsec":%d,"bans":%s}\n' \
"$total" "$autoban" "$crowdsec_count" "$bans_json"
}
unban_ip() {

View File

@ -1,9 +1,10 @@
#!/bin/sh
# WAF Stats Updater - writes to /tmp/secubox/waf-stats.json
# WAF Stats Updater - writes to /tmp/secubox/waf-stats.json and waf-bans.json
# Run via cron every minute: * * * * * /usr/sbin/waf-stats-update
CACHE_DIR="/tmp/secubox"
CACHE_FILE="$CACHE_DIR/waf-stats.json"
BANS_CACHE="$CACHE_DIR/waf-bans.json"
WAF_DATA="/srv/mitmproxy-in"
mkdir -p "$CACHE_DIR"
@ -58,3 +59,13 @@ cat > "$CACHE_FILE" << EOF
"updated": "$(date -Iseconds)"
}
EOF
# Cache CrowdSec bans for fast dashboard loading
if command -v cscli >/dev/null 2>&1; then
bans_json=$(cscli decisions list -o json --limit 20 2>/dev/null)
[ -z "$bans_json" ] || [ "$bans_json" = "null" ] && bans_json="[]"
total=$(echo "$bans_json" | grep -c '"id":' 2>/dev/null) || total=0
printf '{"success":true,"total":%d,"bans":%s}\n' "$total" "$bans_json" > "$BANS_CACHE"
else
echo '{"success":true,"total":0,"bans":[]}' > "$BANS_CACHE"
fi