feat(ui): Add WAF auto-ban statistics to dashboards

CrowdSec Dashboard:
- Added WAF Threats and WAF Auto-Bans stats cards
- Added WAF Auto-Ban status to health checks
- Shows sensitivity level (aggressive/moderate/permissive)

mitmproxy Status:
- Added WAF Auto-Ban section with statistics
- Shows threats today, bans today, total bans
- Displays sensitivity level with color coding
- Shows pending bans count when applicable

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-02-02 16:15:40 +01:00
parent 449d5bb96e
commit 98440c456a
4 changed files with 129 additions and 5 deletions

View File

@ -119,8 +119,8 @@ return view.extend({
var stats = [
{ label: 'Active Bans', value: s.active_bans || 0, type: (s.active_bans || 0) > 0 ? 'success' : '' },
{ label: 'Alerts (24h)', value: s.alerts_24h || 0, type: (s.alerts_24h || 0) > 10 ? 'warning' : '' },
{ label: 'Blocked Packets', value: this.fmt(s.dropped_packets || 0), type: (s.dropped_packets || 0) > 0 ? 'danger' : '' },
{ label: 'Bouncers', value: s.bouncer_count || 0, type: (s.bouncer_count || 0) > 0 ? 'success' : 'warning' }
{ label: 'WAF Threats', value: s.waf_threats_today || 0, type: (s.waf_threats_today || 0) > 0 ? 'warning' : '' },
{ label: 'WAF Auto-Bans', value: s.waf_bans_today || 0, type: (s.waf_bans_today || 0) > 0 ? 'danger' : '' }
];
return stats.map(function(st) {
return E('div', { 'class': 'cs-stat ' + st.type }, [
@ -158,14 +158,16 @@ return view.extend({
{ label: 'LAPI', ok: s.lapi_status === 'available' },
{ label: 'CAPI', ok: s.capi_enrolled },
{ label: 'Bouncer', ok: (s.bouncer_count || 0) > 0 },
{ label: 'GeoIP', ok: s.geoip_enabled }
{ label: 'GeoIP', ok: s.geoip_enabled },
{ label: 'WAF Auto-Ban', ok: s.waf_autoban_enabled, value: s.waf_sensitivity }
];
return E('div', { 'class': 'cs-health' }, checks.map(function(c) {
var valueText = c.value ? c.value : (c.ok ? 'OK' : 'Disabled');
return E('div', { 'class': 'cs-health-item' }, [
E('div', { 'class': 'cs-health-icon ' + (c.ok ? 'ok' : 'error') }, c.ok ? '\u2713' : '\u2717'),
E('div', {}, [
E('div', { 'class': 'cs-health-label' }, c.label),
E('div', { 'class': 'cs-health-value' }, c.ok ? 'OK' : 'Error')
E('div', { 'class': 'cs-health-value' }, valueText)
])
]);
}));

View File

@ -2373,6 +2373,43 @@ get_overview() {
[ -f /etc/crowdsec/online_api_credentials.yaml ] && capi_enrolled=1
json_add_boolean "capi_enrolled" "$capi_enrolled"
# WAF Autoban statistics (from mitmproxy)
local waf_autoban_enabled=0
local waf_bans_today=0
local waf_threats_today=0
local waf_sensitivity=""
# Check if mitmproxy autoban is enabled
waf_autoban_enabled=$(uci -q get mitmproxy.autoban.enabled 2>/dev/null || echo 0)
waf_sensitivity=$(uci -q get mitmproxy.autoban.sensitivity 2>/dev/null || echo "moderate")
# Count WAF-originated bans in CrowdSec (reason contains "mitmproxy-waf")
if [ "$cs_running" = "1" ] && [ -x "$CSCLI" ]; then
waf_bans_today=$(run_cscli decisions list -o json 2>/dev/null | \
grep -c "mitmproxy-waf" 2>/dev/null || echo 0)
fi
# Count threats from mitmproxy log today
local threats_log="/srv/mitmproxy/threats.log"
if [ -f "$threats_log" ]; then
local today
today=$(date -u +%Y-%m-%d)
waf_threats_today=$(grep -c "\"timestamp\": \"$today" "$threats_log" 2>/dev/null || echo 0)
fi
# Count processed autobans
local autoban_processed=0
local autoban_log="/srv/mitmproxy/autoban-processed.log"
if [ -f "$autoban_log" ]; then
autoban_processed=$(wc -l < "$autoban_log" 2>/dev/null || echo 0)
fi
json_add_boolean "waf_autoban_enabled" "$waf_autoban_enabled"
json_add_string "waf_sensitivity" "$waf_sensitivity"
json_add_int "waf_bans_today" "${waf_bans_today:-0}"
json_add_int "waf_threats_today" "${waf_threats_today:-0}"
json_add_int "waf_autoban_total" "${autoban_processed:-0}"
json_dump
}

View File

@ -162,6 +162,54 @@ return view.extend({
])
]),
// Auto-Ban Statistics Card
E('div', { 'class': 'cbi-section' }, [
E('h3', {}, _('WAF Auto-Ban')),
E('div', { 'class': 'cbi-section-node' }, [
E('table', { 'class': 'table' }, [
E('tr', { 'class': 'tr' }, [
E('td', { 'class': 'td', 'width': '33%' }, E('strong', {}, _('Auto-Ban'))),
E('td', { 'class': 'td' }, [
E('span', {
'style': 'display: inline-block; width: 12px; height: 12px; border-radius: 50%; margin-right: 8px; background: ' + (status.autoban_enabled ? '#27ae60' : '#95a5a6')
}),
status.autoban_enabled ? _('Enabled') : _('Disabled')
])
]),
E('tr', { 'class': 'tr' }, [
E('td', { 'class': 'td' }, E('strong', {}, _('Sensitivity'))),
E('td', { 'class': 'td' }, [
E('span', {
'style': 'background: ' + ({ aggressive: '#e74c3c', moderate: '#f39c12', permissive: '#27ae60' }[status.autoban_sensitivity] || '#666') + '; color: white; padding: 2px 8px; border-radius: 4px; font-size: 11px; text-transform: uppercase;'
}, status.autoban_sensitivity || 'moderate')
])
]),
E('tr', { 'class': 'tr' }, [
E('td', { 'class': 'td' }, E('strong', {}, _('Ban Duration'))),
E('td', { 'class': 'td' }, status.autoban_duration || '4h')
])
]),
E('div', { 'style': 'display: flex; gap: 24px; margin-top: 16px; padding: 12px; background: #f8f9fa; border-radius: 8px;' }, [
E('div', { 'style': 'text-align: center; flex: 1;' }, [
E('div', { 'style': 'font-size: 28px; font-weight: bold; color: #e67e22;' }, String(status.threats_today || 0)),
E('div', { 'style': 'font-size: 12px; color: #666;' }, _('Threats Today'))
]),
E('div', { 'style': 'text-align: center; flex: 1;' }, [
E('div', { 'style': 'font-size: 28px; font-weight: bold; color: #e74c3c;' }, String(status.autobans_today || 0)),
E('div', { 'style': 'font-size: 12px; color: #666;' }, _('Bans Today'))
]),
E('div', { 'style': 'text-align: center; flex: 1;' }, [
E('div', { 'style': 'font-size: 28px; font-weight: bold; color: #3498db;' }, String(status.autobans_total || 0)),
E('div', { 'style': 'font-size: 12px; color: #666;' }, _('Total Bans'))
]),
status.autobans_pending > 0 ? E('div', { 'style': 'text-align: center; flex: 1;' }, [
E('div', { 'style': 'font-size: 28px; font-weight: bold; color: #9b59b6;' }, String(status.autobans_pending)),
E('div', { 'style': 'font-size: 12px; color: #666;' }, _('Pending'))
]) : null
])
])
]),
// HAProxy Backend Inspection Card
E('div', { 'class': 'cbi-section' }, [
E('h3', {}, _('HAProxy Backend Inspection')),

View File

@ -57,6 +57,36 @@ get_status() {
local token_file="${data_path:-/srv/mitmproxy}/.mitmproxy_token"
[ -f "$token_file" ] && token=$(cat "$token_file" 2>/dev/null | tr -d '\n')
# Auto-ban stats
local autoban_enabled=$(uci_get autoban.enabled)
local autoban_sensitivity=$(uci_get autoban.sensitivity)
local autoban_duration=$(uci_get autoban.ban_duration)
# Count threats today
local threats_today=0
local threats_log="${data_path:-/srv/mitmproxy}/threats.log"
if [ -f "$threats_log" ]; then
local today=$(date -u +%Y-%m-%d)
threats_today=$(grep -c "\"timestamp\": \"$today" "$threats_log" 2>/dev/null || echo 0)
fi
# Count processed autobans
local autobans_total=0
local autobans_today=0
local autoban_log="${data_path:-/srv/mitmproxy}/autoban-processed.log"
if [ -f "$autoban_log" ]; then
autobans_total=$(wc -l < "$autoban_log" 2>/dev/null || echo 0)
local today=$(date +%Y-%m-%d)
autobans_today=$(grep -c "^$today" "$autoban_log" 2>/dev/null || echo 0)
fi
# Pending autoban requests
local autobans_pending=0
local autoban_requests="${data_path:-/srv/mitmproxy}/autoban-requests.log"
if [ -f "$autoban_requests" ] && [ -s "$autoban_requests" ]; then
autobans_pending=$(wc -l < "$autoban_requests" 2>/dev/null || echo 0)
fi
cat <<EOFJ
{
"enabled": $([ "$enabled" = "1" ] && echo "true" || echo "false"),
@ -76,7 +106,14 @@ get_status() {
"wan_protection_enabled": $([ "$wan_protection_enabled" = "1" ] && echo "true" || echo "false"),
"wan_interface": "${wan_interface:-wan}",
"crowdsec_feed": $([ "$crowdsec_feed" = "1" ] && echo "true" || echo "false"),
"block_bots": $([ "$block_bots" = "1" ] && echo "true" || echo "false")
"block_bots": $([ "$block_bots" = "1" ] && echo "true" || echo "false"),
"autoban_enabled": $([ "$autoban_enabled" = "1" ] && echo "true" || echo "false"),
"autoban_sensitivity": "${autoban_sensitivity:-moderate}",
"autoban_duration": "${autoban_duration:-4h}",
"threats_today": ${threats_today:-0},
"autobans_today": ${autobans_today:-0},
"autobans_total": ${autobans_total:-0},
"autobans_pending": ${autobans_pending:-0}
}
EOFJ
}