- New Streamlit category with external app links
- France TV, Yijing Oracle, Fabricator, Bazi Complete, SecuBox Control
- External links open in new tab with ↗ indicator
- Support for both internal paths and external URLs in nav items
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- KISS Theme v2.1: Collapsible nav sections with icons, auto-expand active
- Add comprehensive navigation with all SecuBox apps organized by category
- Fix Client Guardian path to admin/secubox/security/guardian
- Fix Cookie Tracker path to admin/secubox/interceptor/cookies
- Ollama: Add system resources card (RAM/disk usage with progress bars)
- Ollama: Add API endpoints card with copy-to-clipboard
- Ollama: Add container logs viewer with refresh
- Ollama: Add system_info, logs, model_info RPCD methods
- Ollama: Update stats to show RAM/disk usage
- Fix Vortex Firewall menu path to admin/secubox/security
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add two toggle buttons in bottom-right corner
- 📐/📏 button: Toggle sidebar & top bar on/off
- 👁️ button: Switch between KISS and LuCI mode
- Three viewing modes: Full KISS, Content Only, LuCI
- Add .kiss-chrome-hidden class for minimized mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add fixed top bar with hamburger menu, logo, breadcrumb, logout
- Collapsible sidebar with scrolling for long menus
- Expanded navigation: Dashboard, Security, Services, Apps, System
- Preserve #tabmenu for internal view tab navigation
- Mobile overlay backdrop for sidebar
- Responsive breakpoints: 1024px, 768px, 480px
- Toggle button moved to bottom-right corner
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Emergency banner stacks vertically on mobile
- Quick actions use CSS grid (3-col → 2-col)
- Tables get horizontal scroll on narrow screens
- Health grid adapts to 3-col → 2-col on mobile
- Stats grid compact layout on small screens
- Reduced padding and font sizes for mobile
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>
- Update RPCD get_public_ips to return 4 IP fields:
- lan_ipv4: br-lan interface IP
- wan_ipv4: br-wan interface IP
- public_ipv4: Real public IP (cached from ipify.org)
- public_ipv6: Global IPv6 from br-wan
- Update dashboard to display 4-column IP grid with icons
- Add responsive CSS for 2x2 layout on small screens
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Whitelist trusted crawlers to prevent false positive SSRF alerts:
- Facebook/Meta: 69.171.x, 173.252.x, 31.13.x, 157.240.x, etc.
- Ahrefs SEO: 54.39.210.x, 167.114.139.x, 54.36.x
Changed from ip/cidr format to expression format for CrowdSec
compatibility on OpenWrt.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add setKissMode(), toggleKissMode(), isKissMode() methods to theme.js
- Add initKissMode() for automatic initialization from localStorage
- Add _injectKissCSS() for dark theme styling
- Add _injectKissSidebar() for C3BOX navigation
- Add _hideChrome()/_showChrome() for toggling LuCI UI elements
- Add kiss-loader.js for standalone auto-initialization
- KISS mode persists via localStorage across all pages
Usage:
1. Click the eye toggle (👁️) on any SecuBox page
2. Or call Theme.setKissMode(true) from JS console
3. Mode persists across page navigation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- InterceptoR: Refactor to use shared KissTheme.wrap() module
- Remove duplicate inline CSS (~200 lines)
- Use shared theme for sidebar navigation
- IoT Guard: Update to KISS dark theme styling
- Use KissTheme.wrap() with sidebar
- Update stat cards to use KISS classes
- Update device chips and anomaly table styling
- mitmproxy: Add KISS theme wrapper
- Add KissTheme.wrap() for sidebar navigation
- Update info card styling to match theme
- System Hub: Update to KISS theme
- Add KissTheme.wrap() for sidebar navigation
- Update quick actions to use kiss-btn class
- Inject KISS-compatible extra styles for cards
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add shared navigation config in kiss-theme.js
- Add renderSidebar() method for reusable sidebar
- Add wrap() helper for full page with sidebar
- Update InterceptoR to use sidebar layout
- Responsive: collapses on mobile, icons-only on tablet
Other views can use: KissTheme.wrap([content], 'active/path')
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add shared kiss-theme.js module for consistent dark theme across views
- Add eye toggle button (👁️) to switch between KISS and LuCI modes
- Add git repo status methods to luci.gitea RPCD:
- get_repo_status: branch, ahead/behind, staged/modified files
- get_commit_history: recent commits with stats
- get_commit_stats: daily commit counts for graphs
- Update InterceptoR overview with KISS styling and responsive grid
- Fix quick links paths (network-tweaks → admin/network/)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove 'local' keyword from case statement block where it's not
allowed in POSIX shell. Replace && block conditions with proper
if/then/fi statements for health score calculation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add login/logout button in topbar (detects session state)
- Add collapsible LuCI Quick Nav tree in left sidebar
- Add LuCI Tree screen with grid view of all module links
- 7 categories: Core, Security, Network, Services, Monitoring, System, P2P
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add /etc/config/iot-guard with default settings so the Settings
page loads without RPC errors. Includes main config, zone policy,
allowlist, and blocklist sections.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rewrite using standard LuCI view pattern matching other portal views
- Use simple data array structure instead of nested objects
- Add proper event listener for search filter
- Organize 90+ links into 17 categories
- Fix JavaScript errors on public endpoint
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Async progressive cache: instant render from localStorage, async RPC updates
- Public ACL: unauthenticated access for secubox-public/portal route
- Progressive DOM updates via updateText() helpers
- No blocking Promise.all - each fetch updates its section on completion
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Auto-detects DNS server (BIND vs dnsmasq) and generates appropriate
blocklist format:
- BIND: Response Policy Zone (RPZ) with NXDOMAIN responses
- dnsmasq: addn-hosts sinkhole file (existing)
Tested with 46,067 blocked domains on BIND named server.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The handler was looking for dns-guard.detector_${det}.enabled but
UCI config uses dns-guard.${det}.enabled (without detector_ prefix).
This caused all detectors to show as Disabled in the dashboard.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace defunct malwaredomains feed with ThreatFox (abuse.ch)
- Add is_valid_domain() function to validate domain format
- Optimize intel_merge() with batch SQL transactions
- Previous: 765 domains with invalid entries (HTML parsing artifacts)
- Now: 46,056 valid domains from 3 feeds (URLhaus, OpenPhish, ThreatFox)
Performance: Batch import completes in seconds vs minutes for 45K+ domains.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
KISS-style dashboard for Vortex DNS Firewall with:
- Status cards: Active state, Blocked Domains, Total Blocks, x47 Impact
- Quick actions: Update Feeds, Block Domain, Search Domain
- Threat intelligence feeds table with domain counts and update times
- Top blocked domains table with threat badges
- Threat distribution visualization
- Live polling (10s) for real-time stats updates
- Dark mode support
Menu: Services > Vortex DNS Firewall
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1 implementation of Vortex DNS Firewall - SecuBox's first line
of defense blocking threats at DNS level BEFORE any connection is
established.
Features:
- Threat intel aggregator (URLhaus, OpenPhish, Malware Domains)
- SQLite-based blocklist database with domain deduplication
- dnsmasq integration via sinkhole hosts file
- x47 vitality multiplier concept (each DNS block prevents ~47 connections)
- RPCD handler for LuCI integration with 8 methods
- CLI tool: vortex-firewall intel/stats/start/stop
Tested with 765 blocked domains across 3 threat feeds.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Support building images for: mochabin, espressobin-v7, espressobin-ultra, x86-64
- New CLI: secubox-cloner build --device espressobin-v7
- New CLI: secubox-cloner devices (list supported devices)
- RPCD: list_devices method, build_image accepts device_type param
- LuCI: Device selection dropdown in build modal
- LuCI: Device column in images table with badges
- Each device type has its own TFTP image file
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Dashboard with status cards: device, TFTP, tokens, clones
- Quick actions: Build Image, Start/Stop TFTP, Token generation
- Clone images table with size and TFTP-ready status
- Token management with auto-approve option
- U-Boot flash commands display when TFTP is running
- RPCD handler with 10 methods for full cloner management
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Pipe | while runs in subshell, json_add calls don't affect parent
- Use temp files to avoid subshell: write data to file, then read
- Fixed https_visitors, top_endpoints, recent_visitors arrays
- All arrays now properly populated with visitor data
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>
- Add poll.add() for continuous 3-second updates
- Use data-attributes for efficient DOM targeting
- Add CSS pulse animation on value changes
- Add live indicator with timestamp
- Implement updateValue, updateBar, updateList methods
- No page rebuilds - direct element text updates
- KISS and fast real-time metrics
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add get_active_sessions RPCD method to dashboard module
- Display session counts: Tor circuits, HTTPS, Streamlit, Mitmproxy, SSH
- Add ACTIVE SESSIONS panel with yellow/gold theme
- Add RECENT VISITORS panel showing visitor IPs and countries
- Add TOP ENDPOINTS panel showing accessed paths
- Add ACL permissions for get_active_sessions
- Auto-refresh with other metrics every 10 seconds
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>
- Add callGetVisitStats RPC from security-threats API
- Add WEB TRAFFIC section with total requests, bots/humans counts
- Display country flags and visit counts for top 8 countries
- Add TOP HOSTS section showing top 5 visited hosts
- Green color theme for traffic sections
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add get_visit_stats RPCD method parsing mitmproxy threats.log
- Returns total requests, by_country, by_host, by_type, by_severity,
bots_vs_humans breakdown, and top_urls (all top 10)
- Add callGetVisitStats RPC declaration to api.js
- Add renderVisitStats function to dashboard with traffic analytics grid
- Shows traffic breakdown by country, host, and URL patterns
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed default visibility from public to private for new Gitea
repositories created by metablogizerctl and streamlitctl.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
MetaBlogizer uses per-site uhttpd instances, not LXC containers.
The watchdog was incorrectly treating it as an LXC service and
constantly trying to restart a non-existent container.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add automatic Gitea push after upload_finalize in Streamlit RPCD
- Add automatic Gitea push after upload_finalize in MetaBlogizer RPCD
- Fix MetaBlogizer to use site name instead of UCI section ID for push
- Fix metablogizerctl to read Gitea config from dedicated gitea section
Uploaded files via LuCI are now automatically synced to Gitea repos.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Streamlit:
- App create/deploy now auto-pushes to Gitea when enabled
- Add 'gitea init-all' command to initialize repos for all existing apps
- Scans all app directories and creates Gitea repos
MetaBlogizer:
- Site create now auto-pushes to Gitea when token configured
- Add 'gitea init-all' command to initialize repos for all existing sites
- Iterates over UCI site configs and syncs to Gitea
Usage:
# Configure Gitea once
uci set streamlit.gitea.enabled=1
uci set streamlit.gitea.url='http://192.168.255.1:3000'
uci set streamlit.gitea.user='admin'
uci set streamlit.gitea.token='<token>'
uci commit streamlit
# Initialize all existing apps/sites
streamlitctl gitea init-all
metablogizerctl gitea init-all
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Streamlit/MetaBlogizer:
- Add 'gitea push <name>' command to both streamlitctl and metablogizerctl
- Auto-creates Gitea repo via API if it doesn't exist
- Initializes git, commits all files, and pushes to Gitea
- Stores repo reference in UCI for future syncs
Tor Shield:
- Add 'wan_input_allow' option for server preset
- Server mode now properly allows WAN inbound (ports 80, 443, 8443)
- Uses nftables rules to integrate with OpenWrt firewall4
- Outbound traffic still routed through Tor (kill_switch)
- Cleanup nftables rules on stop/disable
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace failing awk-based JSON parsing with jsonfilter per-alert extraction.
Alerts now correctly populate in CrowdSec dashboard.
Changes:
- Use jsonfilter to extract created_at, scenario, source_ip per alert
- Loop through up to 8 alerts with index-based access
- Remove Python dependency (not available on OpenWrt)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend uses timestamp/source_ip but JS was looking for time/ip.
Fixed field mappings:
- timestamp -> time display
- source_ip -> ip display
- request -> details fallback
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Alerts data was loaded but not displayed. Added new section showing:
- Time, IP, country, type, severity, details
- Limited to 25 most recent alerts
- Clear alerts button
- Proper severity colors and icons
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add HAProxy multi-domain SSL certificate matching issue
- Document crt-list solution for SNI issues
- Minor updates to settings and streamlit readme
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TRUSTED_PATH_PREFIXES for LuCI, ubus, and CGI paths
- Fix moderate mode to always require threshold (3 attempts in 5 min)
instead of immediate ban on critical threats
- Add WireGuard endpoint whitelist support to prevent VPN peer bans
- New script: mitmproxy-sync-wg-endpoints extracts peer IPs from UCI
- Bump version to v2.4
Prevents accidental bans from legitimate external LuCI login attempts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Shows all CrowdSec bans with:
- IP address, reason, source (WAF/CrowdSec), country, expiration
- Summary counts: total, WAF autobans, CrowdSec detections
- Unban button for each entry with confirmation dialog
- Empty state when no bans active
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New methods for threats monitor dashboard:
- bans: Get CrowdSec decisions with counts by source
Returns total, mitmproxy_autoban, crowdsec counts + full bans array
- unban: Remove ban by IP address
Updates ACL to include new methods for LuCI access.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New haproxyctl path commands:
- path list: Show all path ACLs with patterns and backends
- path sync <prefix> <host>: Auto-generate ACLs from all backends
Extracts short name from backend (metablog_X -> X, streamlit_Y -> Y)
Skips existing ACLs, only adds new ones
- path add: Manually add single path ACL
- path remove: Remove specific path ACL
- path clear: Remove all ACLs matching prefix
This enables dynamic route updates when backends change.
Example: haproxyctl path sync /gk2 secubox.in
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Path-based ACLs are now sorted by pattern length (longest first) before
being emitted to haproxy.cfg. This ensures specific paths like /gk2/evolution
match before general paths like /gk2.
Two-phase approach:
- _collect_path_acl() stores ACL data with pattern length prefix
- _emit_sorted_path_acls() sorts by length descending and emits rules
Enables apex domain path routing: secubox.in/gk2/** instead of *.gk2.secubox.in
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add _add_path_acl() function to process UCI 'acl' sections
- Support path_beg, path_end, path, path_reg, path_dir match types
- Path ACLs are processed before vhost ACLs (higher priority)
- Fix http_request list handling to avoid duplicate output
- Enables gk2.secubox.in/evolution routing to streamlit_evolution
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Support suffix matching for wildcard domains (*.domain.tld)
- Add match_type option: exact, suffix, regex
- Enable subdomain-to-path mapping for mesh publishing
- Prepare infrastructure for distributed Vortex DNS nodes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Display per-subdomain request/threat counts
- Show protocol distribution (HTTP/HTTPS)
- Show top URIs and countries per domain
- Sort by request count, limit to top 25
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Track requests, threats, protocols per subdomain
- Record HTTP methods, status codes, top URIs, countries
- New RPCD method: subdomain_metrics
- Metrics auto-saved to /tmp/secubox-subdomain-metrics.json
- Add wan_setup/wan_clear to ACL write permissions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add vhost for presse.cybermood.eu
- Add backend cybermood_presse on port 4001
- Add ACME certificate entry
- Add ACL routing rules
- Fix backends to use LAN IP (192.168.255.1) instead of localhost
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add vhost entries for cybermood.eu and www.cybermood.eu
- Add backend configuration (cybermood_web on port 4000)
- Add ACME certificate entries for SSL
- Add ACL routing rules in template
- Switch to crt-list for multi-certificate SNI support
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changed fetch_file() TTL from 300s to 60s
- All tabs now refresh every minute like Devel tab
- Updated footer to reflect unified refresh interval
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- New "🚀 Devel" tab with live GitHub commit activity (1-min cache)
- Metrics: Commits Today, This Week, Contributors, Stars
- Commit type distribution (feat/fix/docs/refactor/chore)
- Recent commits list with hash, message, author, relative time
- Repository stats: forks, watchers, open issues
- Cyberpunk-themed commit cards with color-coding
- Pulsing live indicator animation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The HAProxy LXC container was missing lxc.mount.auto = proc:mixed sys:ro
which caused lxc-attach to fail with "mount -t proc proc /proc" error.
This prevented the LED watchdog from checking HAProxy status via
lxc-attach -n haproxy -- pgrep haproxy, triggering false SPUNK alerts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add secubox-landing script to generate landing pages from HAProxy vhosts
- Integrate landing command into secubox CLI
- Add boot hook to regenerate landing pages on startup
- Fix HAProxy multi-cert SNI using crt-list instead of directory mode
- Fix backend IPs from 127.0.0.1 to 192.168.255.1 for LXC compatibility
- Auto-convert localhost IPs in RPCD handler and CLI tools
Landing page features:
- Groups all services by zone with stats header
- Shows SSL certificate status per domain
- Categorizes by type: Streamlit, Blog, Admin, Media, Dev, etc.
- Regenerates at boot (30s after startup)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SecuBox Fabricator - Universal Constructor for SecuBox Components:
- Main dashboard with live stats from UCI and JSON cache
- Collectors page: manage stats scripts, view/run collectors, JSON cache
- Apps page: Streamlit instance management with test/restart/deploy
- Blogs page: MetaBlogizer site management from UCI config
- Services page: HAProxy vhosts/backends, Peek/Poke/Emancipate
- Widgets page: dashboard widget designer with live stats preview
All pages now use actual live data from UCI configs and /tmp/secubox/*.json
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add DNS resolution test to heartbeat status
- Include BIND, CrowdSec, HAProxy, mitmproxy service checks
- Add security metrics (crowdsec_bans, dns_response)
- Improve health score calculation with all services
Router changes (not in repo):
- Enabled BIND recursion with forwarders (9.9.9.9, 1.1.1.1)
- Added BIND query/security logging
- Added CrowdSec acquisition for BIND logs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add extract_zip_flatten() to Streamlit RPCD for nested ZIP handling
- Add bot whitelist to mitmproxy WAF (Facebook, Google, Bing crawlers)
- Skip threat detection for whitelisted legitimate crawlers
- Track Fabricator app and stats evolution in HISTORY.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Creates double-buffered JSON caches with last N entries
- Caches: threats, kernel, syslog, crowdsec details
- Writes to /tmp/secubox and /www for LuCI access
- Cron runs every minute for real-time updates
- Usage: secubox-detail-collector [count] [type]
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>
- Create cyberpunk-style End of Internet page for unknown domains
- Add http-request UCI option support in haproxyctl generator
- Support path rewriting backends with http-request set-path
- Configure end_of_internet as default backend for both frontends
- Update docs with HAProxy enhancements (entry #59)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add validation in _add_vhost_acl() to detect when vhost backend
is set to IP:port format instead of a proper backend name.
This prevents haproxy config generation errors like:
[ALERT] unable to find required use_backend: '127.0.0.1:8081'
When detected, logs a warning and skips the vhost instead of
generating invalid config that crashes HAProxy.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Stats Collection:
- Add unified secubox-stats-collector for crowdsec/mitmproxy/firewall
- Add secubox-status-json and metablogizer-json for landing page
- JSON cache files in /tmp/secubox/ for double-buffer status
LED Pulse Daemon:
- Tri-color status sync matching control panel (Health/CPU/Memory)
- SPUNK ALERT mode for critical service failures (HAProxy/CrowdSec down)
- Integrated into secubox-core init.d for auto-start on boot
Landing Page:
- Add Blogaliser section with MetaBlogizer sites
- Add health indicators (green/yellow/red status dots)
- Add security stats (dropped, bans, connections)
Streamlit Enhancements:
- Add test_upload RPCD method for upload validation
- Add reupload button for replacing existing apps
- Add secubox_control.py reading from cache (LXC-compatible)
- Update ACL and API for new methods
HAProxy Fixes:
- Fix invalid use_backend entries (IP:port -> backend names)
- Add streamlit_hello backend
- Save routing to UCI config for persistence
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed LED heartbeat tick interval from 0.15s to 0.33s for more
visible pulse pattern. Adjusted cycle pause from 8 to 6 ticks.
Triple-pulse cycle now spans ~4 seconds total:
- 3 beats + 2 gaps + 6 rest = 11 ticks × 0.33s = ~3.6s
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds full exposure workflow for Streamlit apps:
- DNS A record registration (Gandi/OVH via dnsctl)
- Vortex DNS mesh publication
- HAProxy vhost with SSL and backend creation
- ACME certificate request
- Zero-downtime HAProxy reload
Usage: streamlitctl emancipate <app> [domain]
Domain auto-generated from vortex wildcard if not specified.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Track avahi-publish PID in /tmp/secubox-avahi-mesh.pid and check if process
is still running before spawning a new one. Prevents process accumulation
when discover_peers() is called repeatedly.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change mount point from var/mail to home/vmail for proper Dovecot integration
- Update virtual_mailbox_base from /var/mail to /home/vmail
- Create Maildir/{cur,new,tmp} structure matching Dovecot's mail_location
- Fix vmailbox entries to include Maildir/ suffix
- Update vmail user home directory to /home/vmail
This resolves the issue where emails delivered by Postfix were not visible
in Roundcube because Dovecot was looking in ~/Maildir/ subdirectory.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
LED assignment for MochaBin:
- led1: Global health status (green/yellow/red with pulse variations)
- led2: Security threat meter (CrowdSec + mitmproxy activity)
- led3: Global capacity (CPU + Network combined, color gradient)
- mmc0: Classic heartbeat when stable, rapid blink on state changes
Features:
- Fast 1.5s heartbeat loop for reactive visual feedback
- Health score from services (HAProxy, CrowdSec) + memory/disk
- Threat level from CrowdSec alerts and mitmproxy stats
- Combined CPU load + network throughput capacity meter
- Event pulse system for config/task/alert notifications
- State change detection for mmc0 stability indicator
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Interactive Streamlit landing page showing project evolution:
- Real-time sync with GitHub master (HISTORY.md, WIP.md, TODO.md, README.md)
- Milestone tracking with dates and timeline view
- Full-text search across all project files
- Feature distribution charts
- Dark cyberpunk theme matching SecuBox design
Deployed on port 8510, added to GK2 landing page.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add LED heartbeat to secubox-core daemon using MochaBin's RGB LEDs (led1)
- Green flash: system healthy
- Double red flash: warning state
- Long red flash: error state
- Blue flash: boot/startup
- LED pulses once per watchdog cycle (default 60s)
- New UCI options: led_heartbeat (default 1), watchdog_interval (default 60)
- Add "Node Services" section to Vortex DNS LuCI dashboard showing published sites
- Bump secubox-core version to 0.10.0-r12
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add -z/--zone option to dnsctl for zone override
- Detect correct DNS zone from domain suffix (secubox.in, maegia.tv, cybermind.fr)
- Register on both published domain zone AND vortex node subdomain
- Fix hyphenated site names (e.g., bazi-weekly) in UCI lookups
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Emancipate button to dashboard sites table
- Implement async RPC with job polling to avoid XHR timeout
- Add emancipate + emancipate_status RPCD methods
- Add ACL permissions for new RPC methods
- Change HAProxy reload to restart for clean state
- Document RPCD ACL requirements in CLAUDE.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add `metablogizerctl emancipate <name>` command for one-command full
exposure workflow:
1. DNS A record via dnsctl (Gandi/OVH based on availability)
2. Vortex DNS mesh publication
3. HAProxy vhost with SSL/ACME enabled
4. SSL certificate request (webroot mode)
5. Zero-downtime HAProxy reload
Usage:
metablogizerctl create myblog blog.example.com
metablogizerctl emancipate myblog
Bump version to 1.1.0.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- user_passwd now updates /etc/dovecot/users inside container
- user_add also syncs new users to Dovecot
- Fixes password reset not working (was only updating host file)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Reset Password button to user table
- Add showResetPasswordModal with password confirmation
- Add callUserPasswd RPC declaration
- Fix RPCD handler to read JSON from stdin or $3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace bash arrays with POSIX loops in scoring.sh
- Replace bc with shell arithmetic (bc not available on OpenWrt)
- Wrap RPCD handlers in functions for local keyword compatibility
- Fix process substitution < <() to use pipe instead
Tested on router: CLI and RPCD working, score calculation correct.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Network Anomaly Agent (secubox-network-anomaly):
- 5 detection modules: bandwidth, connection flood, port scan, DNS, protocol
- EMA-based baseline comparison
- LocalAI integration for threat assessment
- network-anomalyctl CLI
LocalRecall Memory System (secubox-localrecall):
- Persistent memory for AI agents
- Categories: threats, decisions, patterns, configs, conversations
- EMA-based importance scoring
- LocalAI integration for summarization
- localrecallctl CLI with 13 commands
AI Insights Dashboard (luci-app-ai-insights):
- Unified view across all AI agents
- Security posture scoring (0-100)
- Agent status grid with alert counts
- Aggregated alerts from all agents
- Run All Agents and AI Analysis actions
LuCI Dashboards:
- luci-app-network-anomaly with real-time stats
- luci-app-localrecall with memory management
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- LocalAI inference takes 30-60s on ARM64 hardware
- Changed RPCD chat handler to async pattern:
- Returns poll_id immediately
- Background process runs AI query (120s timeout)
- Saves result to /var/lib/threat-analyst/chat_*.json
- Client polls with poll_id to get result
- Updated api.js with chatAsync() that polls automatically
- Changed default LocalAI port from 8081 to 8091
- Frontend shows "Thinking..." message with spinner during inference
- Uses curl instead of wget (BusyBox wget doesn't support --post-data=-)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add init.d script for daemon mode with procd integration
- Update Makefile to install init script
- Add packages to bonus feed (secubox-vortex-dns, luci-app-vortex-dns)
- Update tracking files with completion status
Features:
- Master/slave hierarchical DNS delegation
- Wildcard domain management (*.domain)
- First Peek auto-registration of services
- Gossip-based exposure config sync via secubox-p2p
- Submastering for nested hierarchies
- LuCI dashboard with mode detection and action buttons
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New RPCD method: reset_password
- Resets Domoticz admin password via SQLite
- Accessible from LuCI dashboard
- MD5 hashes the password before storing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
mydestination included $mydomain which caused "User unknown in local
recipient table" errors because Postfix treated the domain as local
instead of virtual.
Changes:
- Remove $mydomain from mydestination in setup.sh
- Update fix-postfix command to also fix this issue
- Ensure vdomains file is properly created
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Alpine Linux's Postfix is compiled with LMDB support, not BerkeleyDB
hash support. This caused "Temporary lookup failure" errors on send.
Changes:
- Changed virtual_alias_maps and virtual_mailbox_maps to lmdb: prefix
- Copy resolv.conf to Postfix chroot for DNS resolution
- Added `mailctl fix-postfix` command to repair existing installations
Root cause: virtual_alias_maps was configured as hash:/etc/postfix/virtual
but the hash map type is not supported on Alpine, only lmdb.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Port status now checks inside container (not localhost)
- Added report command: generate, send, enable, disable
- Daily report includes server status, mail queue, logs, storage
- Cron job setup for automated daily reports at 7 AM
- Report sent to admin_email configured in UCI
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All-in-one LuCI interface for:
- Mail server status and control
- User/alias management with modals
- Port status monitoring
- DNS/SSL setup actions
- Webmail configuration
- Mesh backup integration
RPCD handler with 17 methods for full mail management.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New packages:
- secubox-app-backup: Unified backup for LXC containers, UCI config, services
- luci-app-backup: KISS dashboard with container list and backup history
- secubox-app-mailserver: Custom Postfix+Dovecot in LXC with mesh backup
Enhanced dnsctl with:
- generate: Auto-create subdomain A records
- suggest: Name suggestions by category
- mail-setup: MX, SPF, DMARC record creation
- dkim-add: DKIM TXT record management
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New packages:
- secubox-threat-analyst: AI-powered threat analysis with CrowdSec integration
- luci-app-threat-analyst: LuCI dashboard for threat intelligence
- secubox-dns-guard: DNS security monitoring and blocking
- secubox-mcp-server: Model Context Protocol server for AI assistant integration
Enhancements:
- dns-provider: Add DynDNS support (dyndns, get, update, domains commands)
- gandi.sh: Full DynDNS with WAN IP detection and record updates
- luci-app-dnsguard: Upgrade to v1.1.0 with improved dashboard
Infrastructure:
- BIND9 DNS setup for secubox.in with CAA records
- Wildcard SSL certificates via DNS-01 challenge
- HAProxy config fixes for secubox.in subdomains
- Mail server setup with Roundcube webmail
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Upgrade LocalAI from v2.25.0 to v3.9.0 with new features:
- **Agent Jobs Panel**: Schedule and manage background agentic tasks
- **Memory Reclaimer**: LRU eviction for loaded models, automatic VRAM cleanup
- **VibeVoice backend**: New voice synthesis support
Update README with:
- v3.9 feature highlights
- Complete CLI command reference
- Model presets table (tinyllama, phi2, mistral, gte-small)
- API endpoints documentation
- SecuBox Couche 2 integration notes
This is part of the v0.18 AI Gateway roadmap.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Build and add secubox-app-mac-guardian_0.5.0-r1_all.ipk
- Build and add luci-app-mac-guardian_0.5.0-r1_all.ipk
- Sync luci-app-mac-guardian to local-feed for SDK building
- Update apps-local.json catalog with proper metadata:
- Category: security, Icon: wifi
- Descriptions for frontend and backend packages
- Rebuild all bonus feed packages
Package features:
- WiFi MAC address spoofing detection
- OUI anomaly detection for device fingerprinting
- MAC flood protection via hotplug.d integration
- CrowdSec scenarios for automated threat response
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 4-step modal wizard for first-time configuration
- Step 1: Welcome with Docker/container status checks
- Step 2: Add/remove media library paths with type presets
- Step 3: Network configuration (domain, HAProxy, ACME)
- Step 4: Complete with link to Jellyfin Web UI
- Add RPCD methods: get_wizard_status, set_wizard_complete,
add_media_path, remove_media_path, get_media_paths
- Auto-trigger wizard when installed but not configured
- Add wizard.css with step indicators and form styling
- Update Makefile to install CSS resources
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add emancipate/revoke/get_emancipated RPCD methods
- Add Mesh toggle column with blue theme styling
- Add Emancipate button in header with multi-channel modal
- Modal allows selecting Tor/DNS/Mesh channels
- Add mesh badge to header stats
- Update ACL and API wrapper for new methods
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add animated "Collecting data..." overlay with pulsing dots during
5-second chart warmup period
- Chart legend transitions from "Waiting" to "Live" when data arrives
- Add formatBits() helper for network rate display (Kbps/Mbps/Gbps)
- Network rates now use SI units (bits) instead of bytes
- Cyberpunk theme support for empty state styling
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>
- Switch from Docker to LXC with Debian bookworm rootfs and native
Domoticz binary from GitHub releases (latest/download pattern)
- Fix LXC cgroup2 terminal allocation: add lxc.tty.max, lxc.pty.max,
cgroup2 device permissions for standard char devices, disable seccomp
- Fix PID 1 issue: run domoticz as child process with signal forwarding
- Use quoted heredoc with sed placeholders for start script generation
- Update LuCI view: Docker → LXC references, add memory usage display
- Remove Docker image UCI option, update catalog runtime to "lxc"
- Fix streamlit LXC config: same cgroup2/terminal/seccomp fixes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New luci-app-domoticz package with RPCD handler (12 methods), LuCI overview
(status, IoT integration, MQTT, HAProxy, mesh, logs), and full service lifecycle.
Enhanced domoticzctl with configure-mqtt (auto Mosquitto+Z2M bridge), configure-haproxy,
backup/restore, mesh-register, and uninstall commands. UCI extended with mqtt/network/mesh
sections. Catalog updated with LuCI package and IoT tags. MirrorNetworking strategic
document noted in planning files.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The z2m 2.x breaking changes required three fixes discovered during
live deployment testing on the router:
- Adapter renamed from `ezsp` to `ember` in zigbee-herdsman 4.0.0
- Config format needs `version: 4` and nested `homeassistant.enabled`
- Start script needs `ZIGBEE2MQTT_DATA` env var for correct config path
- Add `mosquitto-nossl` as package dependency (MQTT broker required)
- Direct `/dev/ttyUSB0` passthrough works; socat TCP bridge does not
Also updates project planning files (HISTORY.md, TODO.md, WIP.md,
CLAUDE.md) and rebuilds bonus feed with latest IPKs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace Docker-based zigbee2mqtt with a KISS LXC approach using Alpine
Linux container with Node.js + zigbee2mqtt, matching the HAProxy LXC
pattern. Adds USB serial passthrough for Sonoff Dongle Lite MG21.
- zigbee2mqttctl: Full LXC lifecycle (install, update, check, shell)
- RPCD: LXC diagnostics (lxc, cp210x, serial, container, service)
- api.js: Fix callApply missing params (payload was silently dropped)
- overview.js: Match new LXC diagnostics, fix applyConfig call
- Makefiles: Replace +dockerd +docker +containerd with +lxc +kmod-usb-serial-cp210x
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Includes rebuilt packages with RPCD function wrapper fix, crowdsec
decisions fix, and new secubox-app-jellyfin package.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Services with HAProxy DNS domains are now displayed at the top of the
table sorted alphabetically by domain, followed by remaining services
sorted by port number.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Includes device-intel, dns-provider, crowdsec-dashboard, and jellyfin
packages plus updated Packages index.
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>
BusyBox ash rejects `local` outside a function. Both RPCD handlers used
`local` directly in the case block, causing "not in a function" errors
and silent RPC failures (empty responses).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change menu action type from "firstchildview" to "firstchild" to fix runtime exception
- Remove null handleSaveApply/handleSave/handleReset so form.Map default save works
- Update Gandi API link from defunct account.gandi.net to admin.gandi.net PAT page
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace bash-only $((16#hex)) with printf "%d" 0x for ash
- Fix client-guardian collector to use actual UCI fields (name, zone,
status, first_seen, last_seen)
- Add ARP table collector for IP resolution and online detection
- Fix di_get_summary jsonfilter counting (use per-field extraction)
- Rename uci_get to di_ctl_get to avoid collision with OpenWrt's
/lib/functions.sh which overwrites it
- Replace rx_bytes/tx_bytes/risk_score with first_seen/last_seen
timeline in show command
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add PKG_ARCH:=all, empty Build/Compile, conffiles section, and
consistent SECTION/CATEGORY/SUBMENU to match other secubox-app packages.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add 4 new packages implementing unified device intelligence and
DNS provider API management:
- secubox-app-dns-provider: dnsctl CLI with OVH, Gandi, Cloudflare
adapters for DNS record CRUD, HAProxy vhost sync, propagation
verification, and ACME DNS-01 wildcard certificate issuance
- luci-app-dns-provider: RPCD handler + LuCI views for provider
settings and DNS record management
- secubox-app-device-intel: Aggregation layer merging mac-guardian,
client-guardian, DHCP, P2P mesh, and exposure data with heuristic
classification engine and USB/MQTT/Zigbee emulator modules
- luci-app-device-intel: RPCD handler + 5 LuCI views (dashboard,
devices, emulators, mesh, settings) with shared API and CSS
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Docker-based Jellyfin media server with UCI config (port, image, media
paths, GPU transcoding), procd init, jellyfinctl CLI, and LuCI frontend
with status/config/logs view.
Also adds Punk Exposure Engine architectural README documenting the
Peek/Poke/Emancipate service exposure model and DNS provider API
roadmap. CLAUDE.md updated with architectural directive.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use DOM property assignment (cb.checked = value) instead of HTML
attribute ('checked': false) which browsers treat as checked since
any attribute presence means ON for boolean HTML attributes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Collapse 4-tab UI into single-table view. Enrich scan with real names
from uhttpd UCI, streamlit UCI, docker containers, glances and Lyrion.
Add vhost_list RPCD method to show HAProxy domains and uhttpd instances.
Fix RPC expect unwrapping, trim CSS from 870 to 178 lines.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The install_requirements() function only matched requirements.txt exactly,
missing files like requirements_bazi.txt shipped in user ZIP uploads. Now
falls back to any requirements*.txt file. RPCD upload handlers (upload_zip,
upload_finalize) also trigger pip install inside the container at deploy time.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
uhttpd-mod-ubus silently rejects JSON-RPC requests >64KB with "Parse error",
causing uploads of .py files >48KB to fail with "No related RPC reply".
- Add chunked upload (upload_chunk + upload_finalize) that splits base64
content into 40KB pieces sent sequentially, then reassembles server-side
- Frontend auto-selects chunked upload when content exceeds 40KB
- Stop polling during upload to prevent RPC batch conflicts
- RPCD handlers use cat-to-tempfile instead of shell variables for stdin
to avoid BusyBox argument size limits
- Container startup script handles top-level .py files (not just subdirs)
- streamlitctl cmd_instance_start also handles top-level .py files
- Add upload_chunk and upload_finalize to ACL
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Read all files as ArrayBuffer and use Uint8Array chunked encoding
for base64, replacing btoa(text) which throws DOMException on
non-ASCII characters (accents, CJK, etc).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix ZIP upload: install unzip dependency, fix empty array check
(jsonfilter returns "[ ]" not "[]"), redirect unzip stdout to
prevent JSON corruption, use readAsArrayBuffer instead of
deprecated readAsBinaryString, add .catch() error handler
- Fix list_apps to scan subdirectories for ZIP-uploaded apps,
skip Streamlit pages/ convention dir, prefer app.py as entry point
- Fix set_active_app: replace broken streamlitctl call with direct
UCI update
- Fix remove_app: replace broken streamlitctl call with direct
file removal and UCI cleanup
- Fix add_app: replace broken streamlitctl call with direct UCI
- Add rename_app and rename_instance RPCD methods with ACL entries
- Activate now auto-creates an instance with next available port
- Apps list shows UCI display name separate from filesystem ID
- Sanitize uploaded filenames for UCI compatibility
- Add rename buttons and modals for apps and instances
- Add error notifications for failed deletes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds get_gitea_config, gitea_list_repos to read permissions and
save_gitea_config, gitea_clone, gitea_pull, preview_zip, upload_zip
to write permissions, fixing "Access denied" (-32002) errors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add gte-small embedding model preset to localaictl with proper YAML
config (embeddings: true, context_size: 512)
- Fix RPC expect declarations across api.js, dashboard.js, models.js to
use empty expect objects, preserving full response including error fields
- Replace fragile sed/awk JSON escaping in RPCD chat and completion
handlers with file I/O streaming through awk for robust handling of
special characters in LLM responses
- Switch RPCD chat handler from curl to wget to avoid missing output
file on timeout (curl doesn't create -o file on exit code 28)
- Bypass RPCD 30s script timeout for chat by calling LocalAI API
directly from the browser via fetch()
- Add embeddings flag to models RPC and filter embedding models from
chat view model selector
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Health check grep was case-sensitive ("ok") but LocalAI returns "OK".
Uptime detection fell into the lxc-info branch (command exists on router)
even though no localai container runs, causing uptime to always be 0.
Simplified to always use /proc/PID which works for both native and
containerized processes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Server endpoints were stored only in browser sessionStorage, lost on tab
close/refresh. Now endpoints are saved in a dedicated UCI config file
(wireguard_dashboard) with RPCD methods to manage them. The wizard
auto-saves the endpoint after tunnel creation, and peers/QR views use a
dropdown of saved endpoints instead of requiring manual re-entry.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change generateConfig/generateQR RPC declarations to use empty expect
so error responses are not silently discarded by LuCI's RPC unwrapper
- Simplify handleShowQR to always check backend for stored key first
- Auto-detect next available interface name in wizard (wg1 if wg0 exists)
- Pass private key to addPeer in wizard's createPeers for QR persistence
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The base64-encoded SVG QR code exceeded jshn's argument list limit,
causing "Argument list too long" errors. Build the JSON response
manually via file I/O so the large string is never passed as a
command argument.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Store the client private key in UCI config (_client_private_key) when a
peer is created, so QR codes and config files can be generated after
page refresh without prompting the user to manually re-enter the key.
Old peers without stored keys still get the manual entry fallback.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Prevent odhcpd crashes from MAC randomization causing hostname conflicts,
stale lease pile-up, and lease flooding. Adds hostname dedup, stale lease
cleanup, flood detection, CLI commands, RPC methods, and LuCI dashboard card.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rename package folder to follow secubox-app-* convention and add
luci-app-mac-guardian with KISS dashboard: status cards, client table
with trust/block actions, recent alerts, and configuration form.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pure-shell WiFi MAC address security monitor detecting randomized MACs,
OUI anomalies, MAC floods, and spoofing. Integrates with CrowdSec via
JSON log parsing and provides real-time hostapd hotplug detection.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Server mode routes all outbound traffic through Tor while preserving
inbound connections (HAProxy, etc) on the public IP. Fixes kill switch
blocking response packets by adding ESTABLISHED,RELATED conntrack rule,
and adds PREROUTING chain for LAN client Tor routing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
LuCI's E() renders null array children as literal "null" text.
Use concat with empty arrays instead of ternary-to-null for
conditional peer/IOC table sections and top-level sections.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The process name is mitmweb (not mitmdump) when running inside the
mitmproxy LXC container. Use pgrep -f mitmweb for correct detection.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Share CrowdSec bans and mitmproxy detections between mesh nodes using
the existing blockchain chain + gossip sync. Received IOCs from trusted
peers are auto-applied as CrowdSec decisions based on a three-tier trust
model (direct/transitive/unknown).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Generate a minimal IPK on-the-fly when a client visits the master-link
landing page, so the "Download Package" step always works even without
a pre-built IPK bundle. The IPK configures the peer via postinst uci
commands (avoiding file conflicts with secubox-master-link), and can be
installed directly via opkg install URL from SSH.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add wan_access UCI option and LuCI checkbox to optionally open Lyrion
ports (9000, 9090, 3483 TCP+UDP) on the WAN interface. WAN rules are
automatically removed when the option is disabled.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Open LAN firewall ports (TCP 9000/9090/3483, UDP 3483) on install and
service start so Squeezebox devices can discover and connect to Lyrion.
Fix LXC config to use host networking properly and add missing Docker
TCP 9090 CLI port mapping.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Read timestamp, approved_at, and other fields into variables before
`cat > "$request_file"` truncates the file. Fixes invalid JSON output
(`"timestamp": ,`) in ml_join_approve, ml_join_reject, and
ml_promote_to_submaster.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Hyphens in RPCD filenames break ubus CLI argument parsing. Rename
luci.master-link to luci.master_link and update all references in
the JS view, ACL, and Makefile. Also pipe RPCD method output through
tr -d '\n\t' so ubus receives single-line JSON it can parse.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use >/dev/null 2>&1 instead of just 2>/dev/null when sourcing
master-link.sh and calling chain_add_block, mesh_init, peer_add,
factory_trust_peer, and gossip_sync to prevent p2p-mesh.sh usage
text and block hashes from corrupting CGI JSON responses.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement secubox-master-link (backend) and luci-app-master-link (LuCI
frontend) for secure node onboarding into the SecuBox mesh via
HMAC-SHA256 join tokens, blockchain-backed peer trust, and gigogne
(nested) hierarchy with depth limiting.
Backend provides: token management, join/approve/reject protocol, IPK
bundle serving, CGI API endpoints, and a dark-themed landing page for
new nodes. Frontend provides a 3-tab LuCI view (overview, join requests,
mesh tree) with RPCD integration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
grep -c returns exit code 1 when no matches found (even though it
outputs 0), causing `|| echo 0` to append an extra 0 and corrupt
the JSON response. This broke ubus calls and LuCI status display.
Use `: ${var:=0}` pattern instead to provide defaults.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Read LXC path from /etc/lxc/lxc.conf instead of hardcoding /var/lib/lxc
(OpenWrt uses /srv/lxc by default)
- Skip Alpine rootfs download if file already exists in /tmp
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The factory_audit_log function's ubus call was only redirecting stderr,
allowing stdout JSON output to leak into CGI responses when Gitea backup
is enabled. This caused JSON parse errors in the Factory dashboard when
creating snapshots.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- secubox-app-mitmproxy: Sensitivity-based auto-ban system
- luci-app-mitmproxy: Updated frontend
- luci-app-crowdsec-dashboard: Ban button on alerts page
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>
Integrate SimpleX Chat SMP and XFTP servers for privacy-focused messaging:
- secubox-app-simplex: Backend with LXC container management
- SMP server for message relay (port 5223)
- XFTP server for encrypted file sharing (port 443)
- Auto-download of SimpleX binaries for aarch64/x86_64
- TLS certificate generation (self-signed or Let's Encrypt)
- Firewall and HAProxy integration
- luci-app-simplex: LuCI dashboard with:
- Service status monitoring
- Server address display with copy-to-clipboard
- Full configuration forms for SMP, XFTP, and TLS
- Install/certificate management actions
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>
Content-Type based CVE detection must happen before SSRF patterns
to avoid false positives when routing through localhost.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
LAN transparent mode now requires explicit opt-in via transparent.enabled
to prevent HTTPS certificate errors for LAN clients.
Changes:
- mitmproxyctl: Check transparent_enabled before setting up LAN firewall rules
- LuCI settings: Add warning about certificate requirements for LAN mode
- Default config already has transparent.enabled='0'
WAN protection mode remains active for incoming threat detection.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add WAF-like functionality to mitmproxy for protecting services exposed
to the internet. Incoming WAN traffic is redirected through mitmproxy
for threat detection before reaching backend services.
Features:
- WAN protection mode with nftables rules for incoming traffic
- Enhanced bot scanner detection with 50+ scanner signatures
- Behavioral detection for config/admin/backup/shell hunting
- CrowdSec integration with new scenarios for bot scanners
- LuCI interface for WAN protection configuration
- DPI mirror mode support (secondary feature)
New CrowdSec scenarios:
- secubox/mitmproxy-botscan: Detect automated reconnaissance
- secubox/mitmproxy-shell-hunter: Detect shell/backdoor hunting
- secubox/mitmproxy-config-hunter: Detect credential file hunting
- secubox/mitmproxy-suspicious-ua: Detect suspicious user agents
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of showing clickable model suggestions when Ollama is stopped,
display a helpful message prompting the user to start Ollama first.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace pipe-to-while loops with grep/cut to avoid subshell variable
scope issues in method_status, method_get_providers, and method_set_provider.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
DNS Guard (luci-secubox-dnsguard):
- Privacy-focused DNS manager with KISS UI
- DNS provider feed: FDN, Quad9, Cloudflare, Mullvad, AdGuard, etc.
- Smart Config auto-detects fastest DNS for location
- Category filtering (privacy, security, fast, family, adblock)
- One-click provider switching with dnsmasq integration
Ollama:
- Add suggested models grid when no models installed
- Clickable model cards to download directly
- Models: tinyllama, llama3.2, phi3, gemma2, qwen2.5, mistral, codellama
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change Gitea default port to 3001 (avoid AdGuard Home conflict)
- Add process_name and description to Gitea known service
- Use reserved port from config, verify if actually listening
- Add separate listening/running flags for better status reporting
- Reserved ports are tracked for dedup, dynamic detection fills gaps
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change AdGuard Home default port to 3003 (avoid Gitea conflict)
- Update config file path to /var/lib/adguardhome/AdGuardHome.yaml
- Add netstat-based port detection for running processes
- Actual listening port overrides default when service is running
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>