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:
parent
449d5bb96e
commit
98440c456a
@ -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)
|
||||
])
|
||||
]);
|
||||
}));
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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')),
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user