- Make refresh_cache async to prevent rpcd watchdog kills
- Fix JSON escaping for top_scenarios/countries arrays
- Show decisions as "Active Bans" when alerts_raw is empty
- Display ban expiry time instead of creation time
- Update cron to run cache refresh in background
Fixes LuCI crashes caused by 16s blocking refresh calls.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- alerts_24h now uses local_decisions count instead of empty file
- top_scenarios_raw now extracts from decisions JSON (was parsing CAPI metrics)
- top_countries_raw now correctly parses IsoCode from alerts GeoIP metadata
- Double-buffer caching via cron job already in place
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Problem: get_overview RPC was timing out (30s+) due to 12+ sequential
cscli calls with CAPI data, causing "TypeError: can't assign to property
'countries' on 5" in LuCI.
Solution:
- Pre-cached architecture with /tmp/secubox/crowdsec-overview.json
- get_overview() returns cached data instantly (0.08s)
- refresh_overview_cache() runs via cron every minute
- Reduced cscli calls from 12 to 4 (metrics, decisions, alerts, bouncers)
- Extract flat decisions array using jsonfilter
- Manual JSON building to avoid jshn argument size limits
- Add /etc/cron.d/crowdsec-dashboard for periodic refresh
Also includes:
- Streamlit Control: Deploy functionality like metablogizer
- Streamlit Control: Enhanced Security page with WAF/CrowdSec data
- mitmproxy LuCI: Add timeout race to prevent page hang
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The CrowdSec dashboard was reading from /srv/mitmproxy/threats.log
but the WAF input instance writes to /srv/mitmproxy-in/threats.log.
Fixed paths:
- threats.log: /srv/mitmproxy -> /srv/mitmproxy-in
- autoban-processed.log: /srv/mitmproxy -> /srv/mitmproxy-in
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add batch IP lookup via ip-api.com for org/ISP info
- Display organization column between Source and Country
- Cache org lookups to avoid repeated requests
- Include organization in search filter
- Skip private IP ranges (192.168.x, 10.x, 127.x)
fix(mitmproxy): Fix null text appearing in status table
- Use concat([]) pattern instead of ternary null returns
- Prevents "null" text from rendering in DOM
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace --no-api + jsonfilter with jq length for counting
- jsonfilter cannot properly count JSON arrays
- --no-api flag returns empty results
- Applied fix to both get_overview() and stats functions
- Active Bans now shows correct count (was showing 0)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove --no-api flag which returned empty results
- Use jq length instead of jsonfilter for counting arrays
- Add grep fallback when jq is not available
- Count all decisions, alerts, and bouncers correctly
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
parseCountries() now correctly handles countries as array of objects
[{country: "US", count: 67}, ...] instead of only plain {US: 67} format.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SecuNav.renderTabs() now automatically initializes theme and loads CSS,
eliminating boilerplate from views. Added renderCompactTabs() for nested
modules and renderBreadcrumb() for back-navigation.
Updated module navs: cdn-cache, client-guardian, crowdsec-dashboard,
media-flow, mqtt-bridge, system-hub. Removed ~1000 lines of duplicate CSS.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The callDecisions RPC declaration used expect: { alerts: [] } but the
backend returns { decisions: [...] }, causing the unwrapped result to
always be empty. Also removed leftover console.log debug statements.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WAF Auto-ban Features:
- Three sensitivity levels: aggressive, moderate, permissive
- Aggressive: Immediate ban on first critical threat
- Moderate: Ban after 3 attempts in 5 minutes (default)
- Permissive: Ban after 5 attempts in 1 hour
- Attempt tracking with configurable thresholds
Critical threats (immediate in aggressive/moderate):
- CVE exploits, SQL injection, Command injection
- XXE, Log4Shell, SSTI attacks
CrowdSec Integration:
- Auto-ban requests written to /srv/mitmproxy/autoban-requests.log
- Cron job processes bans every minute via mitmproxyctl
- Bans sent to CrowdSec for network-wide enforcement
New Commands:
- mitmproxyctl process-autoban: Process pending bans
- mitmproxyctl reload-autoban: Reload config after UCI changes
CrowdSec Dashboard:
- Added ban button to alerts page
- Modal confirmation with 24h ban duration
- Real-time banned IP tracking
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Restored the original settings.js functionality as setup.js with
updated nav references. The simplified version was broken.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The settings page was showing "CAPI: Error" because the status
method didn't return the capi_enrolled field. Added CAPI status
check to get_status() so the health display shows correct status.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change nav paths from services/crowdsec to security/crowdsec in alerts,
bouncers, decisions, and settings views to match the new menu location.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change RPCD to return alerts_raw and decisions_raw as JSON strings
- Add parseAlerts() to parse alerts_raw in JavaScript
- Fix countries and alerts now display correctly in overview
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix nav links to use correct path (security instead of services)
- Add parseCountries() to convert top_countries_raw JSON to object
- Fix geo data display in overview
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The bouncer creates multiple sets: crowdsec-blacklists (empty base),
crowdsec-blacklists-CAPI (community blocklists ~19k IPs), and
crowdsec-blacklists-crowdsec (local decisions). Now counts IPs from
all sets in the table instead of just the base set.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move CrowdSec from Services to Security & Access menu
- Fix get_decisions() to return {"decisions":[]} not {"alerts":[]}
- Fix active_bans to use local_decisions count instead of parsing
unreliable metrics output
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rewrite all views with KISS CSS (1200+ lines removed)
- Use unified cs-* CSS prefix with SecuBox theme variables
- Move CrowdSec from Security to Services menu
- Update navigation paths in all views and nav.js
- Add CSS loading in each view's load() function
- Fix Services menu as proper firstchild submenu
- Simplify dashboard.css from 950+ to 112 lines
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add get_settings to read permissions and save_settings to write permissions
to fix RPC access denied error (-32002) on the settings page.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Console Enrollment section to settings with persistent key storage
- Integrate CrowdSec CSS with SecuBox global theme variables (--cyber-*)
- Fix modules.js install button and add installModule function
- Map cs-*, soc-*, sh-* CSS variables to SecuBox theme for consistency
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CAPI status now shows "Connected" when either enrolled or LAPI is available,
fixing misleading "Disconnected" display when CAPI is actually working.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove theme.js and themes/ directory (classic, cards, cyberpunk)
- Remove theme selector from settings page
- Use fixed 'cs-theme-classic' class in overview and settings views
- Simplify load() functions by removing theme.init() calls
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace hardcoded port 8180 with dynamic detection from credentials file
- Extract LAPI port from local_api_credentials.yaml URL
- Convert port to hex for /proc/net/tcp lookup
- Fix GeoIP database path detection (check /srv/crowdsec/data and /var/lib)
- Update default API URL fallback to 8090 (actual CrowdSec default)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix "not a constructor" error by using baseclass.singleton()
pattern instead of baseclass.extend() with manual instantiation.
Theme module now exports a singleton directly.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Make Setup Wizard the first menu item in SecuBox (order 5)
- Add P2P Hub collaborative catalog API methods:
- Peer discovery and management
- Catalog sharing between SecuBox instances
- Settings for P2P sharing preferences
- Fix crowdsec-dashboard theme.js to return class instead of instance
- Update views to properly instantiate theme class
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add theme manager with selectable themes and profiles:
- classic: Professional SOC-style dark theme (default)
- cards: Modern card-based UI with gradients
- cyberpunk: Neon glow effects with terminal aesthetics
Profiles extend themes with custom options:
- default, soc, modern, hacker
Theme selection available in Settings > Appearance with live preview.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move CrowdSec dashboard from admin/services/crowdsec to
admin/secubox/security/crowdsec to integrate with SecuBox menu structure.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix LAPI status check to dynamically read port from config
- Previously hardcoded wrong port (8080 vs 8180)
- Add comprehensive SecuBox feed documentation to README
- Document opkg configuration, HAProxy publishing, troubleshooting
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- CrowdSec Dashboard: Add bouncer_count, geoip_enabled, acquisition_count,
scenario_count fields to get_overview and get_health_check RPCD functions
- MetaBlogizer: Fix menu path to admin/secubox/services/metablogizer
- Portal: Add MetaBlogizer and Gitea to apps registry for services section
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The dashboard was showing 0 decisions because `cscli decisions list`
only returns local decisions, not CAPI blocklist entries.
Fixed by:
- Parsing CAPI decision counts from `cscli metrics` output
- Added separate local_decisions and capi_decisions fields
- Updated overview to show "CAPI Blocklist" and "Local Bans" separately
- Fixed get_capi_metrics to use metrics parsing instead of decisions list
This correctly shows ~15,000 CAPI blocklist IPs instead of 0.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CrowdSec:
- Change LAPI default port from 8080 to 8180 (avoid Docker conflict)
- Update bouncer config, init script, and RPCD dashboard
- Fix port detection hex value (1FF4 for 8180)
Streamlit:
- Complete rewrite with folder-based app structure
- Multi-instance support (multiple apps on different ports)
- Gitea integration (clone, pull, setup commands)
- Auto-install requirements.txt with hash-based caching
HexoJS:
- Multi-instance support with folder structure
- Multiple blog instances on different ports
HAProxy:
- Auto-generate fallback backends (luci, apps, default_luci)
- Add --server letsencrypt to ACME commands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Consider sync OK when CAPI blocklists are active (capi_elements > 0)
even if local decisions = 0
- Add capi_elements_count to health response
- Fixes false "Out of sync" warning when using community blocklists
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move UCI defaults script for auto-registration to cs-firewall-bouncer
- Remove redundant secubox-app-crowdsec-bouncer wrapper package
- Update luci-app-crowdsec-dashboard reference to new package name
- Increment PKG_RELEASE to 3
The defaults script handles:
- Automatic bouncer registration with CrowdSec LAPI
- Interface detection for LAN/WAN
- API key generation and UCI config update
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename crowdsec-firewall-bouncer to secubox-app-cs-firewall-bouncer
- Rename secubox-auth-logger to secubox-app-auth-logger
- Delete secubox-crowdsec-setup (merged into other packages)
- Fix circular dependencies in luci-app-secubox-crowdsec
- Fix dependency chain in secubox-app-crowdsec-bouncer
- Add consolidated get_overview API to crowdsec-dashboard
- Improve crowdsec-dashboard overview performance
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The new get_overview RPC method was missing from the ACL file,
causing "Access denied" errors in the frontend.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>