- 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>
- Add AdGuard Home to known services (port 3000, security category)
- Enhance _add_exposed_service to handle YAML config files
- Add process name detection and running status for known services
- Fix subshell issue in dynamic service detection (while loop)
- Add port deduplication between known and dynamic services
- Include description and process fields in service response
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updated packages:
- luci-app-ollama: KISS UI rewrite
- luci-app-secubox-netdiag: Temperature monitoring and port mode controls
- secubox-core, secubox-p2p: Latest versions
- All other packages rebuilt with current SDK
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Ollama:
- Complete KISS UI rewrite with simplified dashboard
- RPC declarations without expect clauses for reliability
- Service controls, model management, and chat interface
Network Diagnostics:
- Add temperature display with color-coded thresholds
- Add error collection and export functionality
- Add port mode switching (speed/duplex/EEE)
- Add collect_errors, get_port_modes, get_temperature RPC methods
- Add set_port_mode RPC method for port configuration
- Fix ACL permissions for new methods
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>
getDecisions() was looking for result.alerts but RPC returns
result.decisions - fixed to use correct property name.
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>
Move mitmproxy from Services to SecuBox → Security & Access menu
alongside CrowdSec for better organization.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use SVG output instead of PNG (PNG disabled in OpenWrt qrencode)
- Fix endpoint port duplication when port already in endpoint string
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix qrcode require path (slash to dot notation)
- Load hosting status asynchronously to prevent XHR timeout
- Dashboard now loads instantly with sites, HAProxy/IP populate after
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The RPCD returns data directly without wrapping in a 'result' object,
but api.js was using expect: { result: {} } which caused empty data
in the UI (0 sites shown instead of 6).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace overview.js with dashboard.js using standard cbi-* classes
- Add api.js module for RPC declarations
- Show port, runtime, backend_running status in sites table
- Add sync_config, discover_vhosts, import_vhost RPC methods
- Update ACL with new method permissions
- Menu: Sites -> Dashboard
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Running Instances section with enable/disable/delete actions
- Add Instance form to create new instances on different ports
- Add Gitea clone functionality to pull apps from repositories
- Add Gitea configuration section in Settings page
- RPCD handler now supports:
- get_gitea_config, save_gitea_config
- gitea_clone, gitea_pull, gitea_list_repos
- API module exports all new Gitea methods
- Upload supports both .py files and .zip archives
- Instance status shown with colored indicators
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When an app has no description, return empty string instead of null
to prevent "null" text from being rendered in the instances table.
Also: secubox-p2p bumped to v0.6.0-r3 with catalog fix.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When HAProxy inspection mode routes all vhosts through mitmproxy_inspector,
the catalog now uses the original_backend UCI property to correctly map
domains to their actual services.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use POST method for creating new files and PUT for updates.
Gitea requires this distinction - PUT with no SHA fails for new files.
Changes:
- Use POST for creating new files in catalog_push_gitea()
- Use PUT only when existing SHA is available (updates)
- Add explicit branch parameter for consistency
- Bump version to 0.6.0-r2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add file exec permissions for:
- /usr/bin/secubox-services-status
- /bin/sh
Required for fs.exec() to work in LuCI frontend.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create /usr/bin/secubox-services-status helper script
- Update portal scanInitServices to use helper script
- Fallback to inline script if helper not available
- Fixes 0/0 services display caused by fs.exec output buffering
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use pgrep without -f flag (OpenWrt compatibility)
- Use printf instead of echo for reliable output
- Add explicit /bin/sh path
- Add error logging for debugging
Fixes 0/0 services display on dashboard.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Distributed Catalog:
- Implement catalog_push_gitea() to push node catalogs via Gitea REST API
- Add catalog_push_merged_gitea() for merged catalog sync
- Create /api/factory/catalog-sync POST endpoint for triggering sync
- Catalogs pushed to catalog/nodes/{hostname}.json in Gitea repo
Health Probing:
- Add get_service_health() with cached latency measurement
- HTTP probe with curl to measure response time
- Fallback to /proc/net/tcp port check
- 60-second cache TTL to keep catalog endpoint fast
Files:
- factory.sh: Gitea REST API integration for catalog push
- catalog: Health probing with latency measurement
- catalog-sync: New CGI endpoint for sync operations
- Makefile: Install catalog-sync endpoint
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>
The mitmproxy container mounts /srv/mitmproxy as /data, so the GeoIP
database path must use /data/GeoLite2-Country.mmdb for the addon to
find it. This enables proper country detection for external IPs in
threat logs, allowing CrowdSec SSRF scenarios to correctly identify
and ban foreign attackers.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The threat monitor now checks netifyd_running and dpi_available fields
in addition to ndpid running status. This fixes the "nDPId not running"
warning when only netifyd is installed.
- Check ndpid.running OR netifyd_running OR dpi_available
- Show flow count in DPI service badge
- Rename badge from "nDPId" to "DPI" for clarity
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change analytics addon to write threats to /data/threats.log (bind-mounted to host)
- Add CrowdSec acquisition config to read from /srv/mitmproxy/threats.log
- Add parser for mitmproxy JSON threat logs with source_ip in Meta
- Add scenarios for web attacks, scanners, SSRF, and CVE exploits
- Update RPCD to read alerts from host-visible path without lxc-attach
This enables automatic IP banning when mitmproxy detects:
- SQL injection, XSS, command injection (capacity: 3, ban: 15m)
- Path traversal, XXE, LDAP injection, Log4Shell
- Aggressive web scanning (capacity: 10, ban: 10m)
- SSRF attempts from external IPs (capacity: 5, ban: 10m)
- Known CVE exploits (immediate trigger, ban: 30m)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The alerts, threat_stats, clear_alerts, haproxy_enable, haproxy_disable,
and sync_routes methods were not in the ACL file, causing permission
denied errors when calling them from LuCI.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The RPCD was looking for alerts in /tmp/secubox-mitm-alerts.json but
the analytics addon writes to /var/log/crowdsec/secubox-mitm.log in
JSONL format (one JSON object per line).
Changes:
- RPCD: Read from container's /var/log/crowdsec/secubox-mitm.log
- RPCD: Convert JSONL to JSON array using awk
- JS: Handle new field names (source_ip, timestamp, request)
Alerts now display correctly in LuCI dashboard.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The sync-routes command was failing to generate routes for most vhosts due to:
- Subshell bug: pipe in while loop caused variable changes to be lost
- Only supported old-style backends (inline .server field)
- Did not support new-style backends with separate =server sections
Changes:
- Rewrite sync-routes to avoid subshell by using temp file
- Add support for both backend styles (inline and separate server sections)
- Use original_backend field when vhosts are in inspection mode
- Skip luci/fallback/mitmproxy_inspector backends in route generation
Now properly generates 13+ routes for HAProxy backend inspection.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add HAProxy → mitmproxy → Backend inspection chain for filtering
all vhost traffic through mitmproxy with threat detection
- Add haproxy_router.py addon for Host-based request routing
- Add mitmproxyctl commands: sync-routes, haproxy-enable, haproxy-disable
- Add auth token to status response for Web UI auto-authentication
- Add HAProxy Backend Inspection section to LuCI status page with
enable/disable/sync controls
- Add HAProxy Router settings section to LuCI settings page
- LXC container now supports dual-port mode (8888 + 8889 for HAProxy)
- Token displayed with copy button in dashboard
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Swiss Army knife for SecuBox with interactive menu and direct commands:
- status: System overview with services, docker, mesh
- mesh: P2P mesh operations (peers, discover, sync)
- security: CrowdSec status, threats, block/unblock
- docker: Container management
- haproxy: Vhosts and reload
- network: Diagnostics, ports, connections
- recover: Snapshot/restore operations
- feed: Package management
Also updates feed with Jitsi packages and core v0.10.0-r11.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- secubox-app-jitsi: Docker-based Jitsi stack with jitsctl control CLI
- luci-app-jitsi: LuCI web configuration interface
- Catalog entry for SecuBox AppStore
Features:
- End-to-end encrypted video conferencing
- HAProxy integration with WebSocket/SSL support
- Mesh federation for SecuBox P2P network
- User authentication management
- Backup/restore functionality
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Distributed service registry with HAProxy vhost discovery
- Multi-endpoint URLs (haproxy/mesh/local) per service
- DNS federation for mesh peers (*.sb.local via dnsmasq)
- Catalog tab with service filtering and QR codes
- Linked peers navigation panel
- Tools panel with DNS management
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Separate static files from CGI scripts in uhttpd configuration:
- Static files (index.html) served from /www
- CGI scripts executed from /www/api/*
- API base changed from /factory/ to /api/factory/
This fixes HAProxy routing where /factory/ serves the UI and
/api/factory/* routes to the P2P API backend.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement distributed service catalog that discovers HAProxy vhosts
and provides multi-endpoint access URLs (haproxy/mesh/local). Add
dynamic DNS federation that auto-populates dnsmasq with mesh peer
hostnames (hostname.mesh.local).
New features:
- /factory/catalog API endpoint with service registry
- Catalog tab (📚) in Factory UI with endpoint filtering
- QR codes with URL type switching (haproxy/mesh/local)
- Linked mesh peers navigation panel
- DNS federation via /tmp/hosts/secubox-mesh
- CLI commands: dns-enable/disable/update, catalog sync/list/generate
Bumps secubox-p2p to v0.6.0.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add mesh-services CGI endpoint for aggregated service discovery
across all mesh peers
- Update Factory UI with tabbed interface: Dashboard and Mesh Services
- Mesh Services panel features:
- Real-time service discovery from all nodes
- Filter by search, status, or node
- Direct access links for services with ports
- Status indicators (running/stopped/disabled)
- Summary stats (nodes online, running/total services)
- Bump version to 0.5.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change API base URL to use relative /factory/ path instead of
absolute URL with port 7331. HAProxy routes /factory/* API paths
to the factory backend while serving UI from luci backend.
This fixes mixed content blocking when accessing via HTTPS.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace signify-openbsd calls with HMAC-based signatures
(OpenWrt's signify lacks -n flag for no-passphrase)
- Fix API paths in UI: use /factory/ not /api/factory/
- Support cross-port API calls (UI on 8081, API on 7331)
- Update LuCI view to use relative /factory/ path
- Update feed with secubox-p2p 0.4.0 packages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement mesh-distributed, cryptographically-validated control center:
- Add factory.sh library with Ed25519 signing via signify-openbsd
- Add Merkle tree calculation for /etc/config validation
- Add CGI endpoints: dashboard, tools, run, snapshot, pubkey
- Add KISS Web UI (~280 lines vanilla JS, inline CSS, zero deps)
- Add gossip-based 3-peer fanout for snapshot synchronization
- Add offline operations queue with replay on reconnect
- Add LuCI iframe integration under MirrorBox > Factory tab
- Configure uhttpd alias for /factory/ on port 7331
- Bump secubox-p2p version to 0.4.0
Factory UI accessible at http://<device>:7331/factory/
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- secubox-p2p upgraded to v0.3.0 with multi-address mesh support
- WAN IP detection via ipify/ifconfig.me for NAT traversal
- WireGuard tunnel IP enumeration for secure redundancy
- Failover priority: WireGuard → WAN → LAN
- luci-app-secubox-portal KISS redesign (~1000 → ~500 lines)
- Service categorization: Web/Proxy, Security, AI/ML, Containers, Media, Apps
- Dynamic init.d service scanning with 60s caching
- Rebuilt all packages in feed
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add get_wan_ip() to detect real WAN/public IP address
- Add get_wg_ips() to enumerate WireGuard tunnel addresses
- Add get_node_addresses() returning JSON array of all addresses
- Update register_self() to include WAN and WireGuard addresses
- Update get_node_status() API to expose all addresses
- Update add_peer() to support multi-address peers
- Update daemon connectivity check to try:
1. WireGuard tunnel (secure redundancy)
2. WAN address (external reach)
3. LAN address (local fallback)
- Add UCI options: advertise_wan, advertise_wireguard, prefer_wireguard
- Version bump to 0.3.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Simplify portal to ~500 lines (from ~1000)
- Add service categories: Web/Proxy, Security, AI/ML, Containers, Media, Apps
- Dynamic init.d service scanning with status detection
- Clean dark theme with inline CSS (no external dependencies)
- Quick stats: Services, Memory, Uptime, Network
- Active ports section for external services
- Responsive grid layouts for all screen sizes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Services tab to TUI displaying services from all mesh peers
- Implement get_peer_services() fetching via P2P API (port 7331/services)
- Add 60-second caching to avoid slow repeated API calls
- Group services into categories: Web/Proxy, Security, AI/ML, Containers, Apps
- Fix service endpoint URL: /services not /api/services
- Increase API timeout to 15s for comprehensive service scans
- Version bump to 1.2.0
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>
- Console v1.1.0 with mesh participation as first-class peer
- Add announce command to register console on mesh devices
- Add mesh command to query P2P network status and peers
- Improve discovery with 3-phase approach (mesh peers, network scan, probe)
- Implement working update mechanism with SSH-based downloads
- Add proper Add Device modal dialog in Textual TUI
- Add Discover dialog with async progress display
- Show console identity in Mesh tab (node ID, name, IP, port)
- Auto-announce during discover and sync operations
- Add announce button and keybinding (m) in TUI
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The RPC `expect: { peers: [] }` extracts the array directly, so result
IS the peers array, not result.peers. Added Array.isArray() defensive
check for consistent handling.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix register_self() to handle JSON whitespace with awk
- Update get_peers() to auto-register local node if peers list is empty
- Ensure node identity is initialized before querying peers
This ensures C3BOX always shows itself in the P2P Hub peers view.
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 /chain/tip endpoint for blockchain tip query
- Add /catalog/console endpoint for version info
- Add symlinks for /api/ prefix compatibility
- Fix chain.json malformed JSON structure
Enables console to discover C3BOX device via mesh API
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>
When a site's DNS doesn't point to our public IP, skip the external
HTTP check to avoid 5-second timeouts. This significantly speeds up
the get_hosting_status API call which was causing XHR timeouts in
the LuCI frontend.
Sites with DNS mismatch now show frontend_status: "dns_mismatch"
instead of timing out.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BusyBox ash does not support 'local' keyword outside of functions.
Removed 'local' from update_vhost case handler to fix "not in a function"
error that caused ubus calls to fail with no response.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add mDNS service announcement via avahi-publish for _secubox._tcp
- Add REST API endpoints on port 7331 (/api/peers, /api/status, /api/services)
- Add node self-registration to ensure local node visible in mesh view
- Add UCI defaults for uhttpd P2P API instance and firewall rules
- Bump secubox-p2p version to 0.2.0
fix(vhost-manager): Fix uninitialized variable syntax errors
- Add 'local' keyword to variable declarations on lines 606, 621, 693
fix(metablogizer,service-registry): Add HAProxy availability fallback
- Add haproxy_available() helper to check if HAProxy is running
- Gracefully skip HAProxy operations when service unavailable
- Store pending HAProxy config for later when service becomes available
- Prevent crashes when HAProxy container is stopped
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Set umask 022 before file operations
- chmod 644 immediately after base64 decode
- chmod 755 on site_path after each upload
- Prevents 403 Forbidden from restrictive permissions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Dynamic .onion address generation for hosted sites:
- enable_tor: Create Tor hidden service for a site
- disable_tor: Remove Tor hidden service
- get_tor_status: Get Tor status for all sites
- Sites now include onion_address and onion_url in listings
When enabled, sites are accessible via both:
- Public domain (https://domain.com)
- Tor hidden service (http://xxx.onion)
Also includes DNS resolution fix using Google DNS API.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
KISS approach to DNS resolution:
1. Primary: Use Google DNS API (https://dns.google/resolve)
- Most reliable, bypasses local resolver issues
2. Fallback: nslookup with tail -1 to skip DNS server line
3. Fallback: host command
The bug was parsing nslookup output which includes DNS server
address (127.0.0.1) before the actual resolved IP.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- apps.js: ZIP file upload with tree view file selection
- Client-side ZIP parsing for file list preview
- Interactive tree with checkboxes for file selection
- Select All / Deselect All / Python Only buttons
- Supports both .py and .zip file uploads
- api.js: Added previewZip() and uploadZip() RPC methods
- luci.streamlit RPCD:
- preview_zip: List ZIP contents with file sizes
- upload_zip: Extract selected files to app directory
- Automatic main .py file detection and registration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CDN Cache:
- Add file read permissions for cache, logs, and SSL dirs
- Add new RPCD methods to ACL (get_ca_cert, set_ssl_bump)
Tor Shield:
- Create tor-ip-update.sh for caching exit/real IPs
- Use --socks5-hostname for DNS through Tor
- Add cron job for periodic IP updates
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CDN Cache:
- Migrate from nginx to Squid proxy for better caching
- Add aggressive caching rules for Windows Update, Linux repos, Steam, Apple
- Proper firewall integration via UCI (transparent proxy)
- Real-time stats from Squid access logs
Network Modes:
- Complete UI rework with MirrorBox dark theme
- 9 network modes with emojis and descriptions
- Dynamic CSS animations and modern styling
Fixes:
- Fix jshn boolean handling in secubox-recovery (1/0 vs true/false)
- Fix nDPId RPCD to use netifyd as fallback DPI provider
- Update media-flow and security-threats dashboards
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Overview Page (SOC Admin Landing):
- Architecture diagram with layer visualization
- Modular component cards with status indicators
- Network topology with animated orbital nodes
- System status grid with health indicators
- Development roadmap timeline
Profiles Page (Dynamic Cloning):
- Component readiness tracking with progress bars
- Quick presets for common configurations
- Package feeds management with toggles
- Saved profiles list with load/delete
- Clone & deploy actions (export, import, sync, push)
Menu Structure:
- Renamed P2P Hub to MirrorBox
- Added Overview as landing page
- Added Profiles for cloning management
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add new RPCD methods to luci.gitea for P2P mesh auto-setup:
- create_user: Create regular Gitea user via CLI
- generate_token: Generate access token with configurable scopes
- create_repo: Create repository for a user via admin API
These methods enable automated P2P mesh repository setup without
requiring manual token generation in Gitea web UI.
Requires lxc-attach package for container access.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add autoCreateMeshRepo() function that automatically:
- Generates repo name from hostname: secubox-mesh-{hostname}
- Detects local Gitea server (gitea.local, git.local, etc.)
- Only prompts for access token on first use (one-time setup)
- Creates private repository with README
- Pushes initial mesh state immediately
Replace manual "➕ Create" button with "🚀 Auto Setup" for seamless
mesh repository initialization.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add complete backend implementation for Gitea integration and local backups
with admin permissions:
RPCD Methods (luci.secubox-p2p):
- get_gitea_config / set_gitea_config - Gitea server configuration
- create_gitea_repo - Create new Gitea repository via API
- list_gitea_repos - List user's Gitea repositories
- get_gitea_commits - Fetch commit history
- push_gitea_backup - Push config/packages/scripts to Gitea
- pull_gitea_backup - Restore from Gitea commit
- create_local_backup - Create local backup snapshot
- list_local_backups - List available local backups
- restore_local_backup - Restore from local backup
UCI Config (secubox-p2p):
- gitea section: server_url, repo_name, access_token, auto_backup options
- backup section: backup_dir, max_backups, auto_cleanup
Frontend (hub.js):
- Updated createGiteaRepo() to use backend API
- Updated backup functions to use backend storage
- Added refreshGiteaCommits() for real API calls
- Load function now fetches Gitea config and backup list
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add createGiteaRepo() function with modal interface for creating new Gitea
repositories directly from the P2P Hub. Users can configure server URL,
repo name, description, access token, and options (private, init README,
push current state).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Backup & Versioning panel with three cards:
- Mesh Auto-Backup: scheduled snapshots with configurable targets
- Test Cloning: clone config from any peer with auto-sync option
- Gitea History: connect to Gitea for version control and commit feed
- Add backup history modal with restore/delete actions
- Add Gitea configuration modal with server/repo/token settings
- Add formatTime helper for relative timestamps
- Add comprehensive CSS for backup panel, gitea commits, history modal
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add self-peer for local mesh testing without remote nodes
- Add gigogne (nested matryoshka) distribution mode with configurable depth
- Add distribution mode selector: gigogne, mono, ring, full-mesh
- Add visual indicators for self/gigogne peers on globe and peers panel
- Add test mode badge and clear test button
- Add rebuildGigogneStructure for dynamic mode switching
- Update CSS with gigogne/self peer styles and animations
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Animated 3D globe with CSS transformations
- Peer nodes positioned around globe with depth sorting
- Master node at center with pulse animation
- Connection lines between master and peers
- Stars background with twinkle animation
- Health indicators with emoji status (💚💛❤️)
- Quick stats (Peers, Online, Services, Registry)
- Quick actions (Discover, Sync All, Add Peer)
- Responsive layout for mobile
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>
Installs all packages from the local feed in dependency order:
1. secubox-core and secubox-app (base)
2. secubox-app-* backend packages
3. luci-app-* frontend packages
4. luci-theme-* themes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix recursive inclusion bug where secubox-app-bonus was including itself
causing 1GB package size (now 7.5MB with 73 packages)
- Fix Packages index generation to strip Source/SourceName/SourceDateEpoch/URL
fields that caused opkg parsing issues
- Add rebuild_bonus_package() to local-build.sh for proper feed embedding
- Update secubox-feed install command to handle local dependencies from files
(workaround for opkg signature bug with file:// URLs)
- Clean up libc dependency stripping in Packages generation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Even rpcd, bash, jsonfilter, jq depend on libc themselves. Since these
packages are always present on a working OpenWrt/SecuBox system, we should
not declare any dependencies at all.
- secubox-core 0.10.0-r9: DEPENDS:= (empty)
- luci-app-secubox-admin 1.0.0-r19: LUCI_DEPENDS:= (empty)
This prevents opkg from trying to resolve any feed packages and their
cascading libc dependencies.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The OpenWrt SDK automatically adds libc as a dependency to all packages,
even pure shell/JavaScript packages that don't need it. This causes
opkg installation failures when the local feed version of libc doesn't
match the router's installed version.
Solution: Add PKG_FLAGS:=nonshared to Makefiles of arch-independent
packages (secubox-core, luci-app-secubox-admin, secubox-app-bonus).
This tells the build system these packages don't link against libc.
Changes:
- secubox-core: 0.10.0-r6 → r7 with PKG_FLAGS:=nonshared
- luci-app-secubox-admin: 1.0.0-r17 → r18 with PKG_FLAGS:=nonshared
- secubox-app-bonus: 0.3.0-r1 → r2 with PKG_FLAGS:=nonshared
- Regenerated Packages index without libc dependencies
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add four major features to enhance SecuBox AppStore:
1. Feed Source Management:
- Feed types: published, unpublished, development
- Share tokens for private feed access
- CLI: secubox feed list/add/share/import
- LuCI: Feed type badges and share URLs in catalog-sources
2. Profile Export/Import:
- Export configurations with feed sources embedded
- Import from URL or file with merge/replace modes
- CLI: secubox profile export/import/share
- LuCI: New profiles.js view with export/import dialogs
3. Skill System:
- Capability discovery from module catalogs
- Quality indicators based on provider count
- CLI: secubox skill list/providers/install/check
- LuCI: New skills.js view with provider browser
4. Feedback Loop:
- Issue reporting and resolution tracking
- Search existing resolutions
- CLI: secubox feedback report/resolve/search/list
- LuCI: New feedback.js view for knowledge base
Technical changes:
- RPCD backend with 17 new API methods
- POSIX shell compatibility fixes (ESC via printf, tr A-Z a-z)
- LuCI menu entries for new views
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove all LuCI dependencies (luci-base, rpcd, luci-lib-jsonc)
- Remove LuCI-specific files (RPCD backend, ACL, menu, JS views)
- Package now only provides local opkg feed and documentation
- Remove Packages.sig to avoid signature verification errors
- Update local-build.sh to skip signature generation for local feeds
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update local-build.sh to remove libc from Packages index
- Prevents opkg architecture mismatch errors on install
- Regenerate secubox-feed with 74 packages
- Update RPCD scripts for lyrion, mailinabox, metablogizer, nextcloud
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add RPCD methods to mitmproxy: settings, save_settings, set_mode,
setup_firewall, clear_firewall
- Add apply_now parameter to tor-shield save_settings to restart
service and apply iptables rules immediately
- Update ACL files with new permissions
- Add Save & Apply button to tor-shield settings page
- Update api.js files to use correct RPCD method signatures
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The direct services provider was calling jsonfilter in a loop for each
listening port (~40 ports), causing XHR timeouts in the UI.
Changes:
- Disable direct provider by default (set enabled=0)
- Add limit of 20 services if enabled
- Skip common system ports (22, 53, 67, 68, 123, 547, 953)
- Add note about enabling via UCI if needed
The real services come from HAProxy vhosts and UCI published services.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Run Lyrion as nobody (uid 65534) via LXC init.uid/gid settings
- Use cgroup2 memory limit format (lxc.cgroup2.memory.max)
- Convert memory limit string (1G, 256M) to bytes for cgroup2
- Skip opkg install if LXC binaries already exist
- Set proper file ownership during rootfs creation
- Remove su command from start.sh (handled by LXC config)
Fixes the container crash loop caused by Lyrion refusing to run as root.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tor Shield:
- Store current_preset in UCI when enabling with preset
- Return current_preset in status response
- Initialize currentPreset from stored UCI value on page load
Security Threats:
- Fix get_security_stats() firewall packet counting
- Use correct nftables chain names (input_wan, handle_reject)
- Fix grep -c exit code issue (returns 1 when no matches)
- Improve numeric validation (use tr -cd to strip non-digits)
- Add fallbacks for HAProxy socket paths
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- refresh_ips now fetches reverse DNS for exit IP
- Status includes exit_hostname from cache
- Dashboard displays hostname below exit IP
- get_exit_ip also returns hostname
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The expect: { success: false } was causing LuCI RPC to return false
instead of the actual response. Changed all expect declarations to
empty objects to get raw API responses.
Also improved error messages to show actual response for debugging.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Clicking a preset card now enables/restarts Tor with that preset
- Previously it only selected the preset for next toggle
- Added better error handling for toggle and preset changes
- Page reloads after successful preset change
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The toggle handler was receiving status captured at render time which
could be stale due to polling. Now fetches fresh status before deciding
to enable or disable, and does a full page reload after action.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The cumulative impact summary was showing zeros because it only checked
the plugins catalog. Now also counts:
- HAProxy vhosts directly from UCI
- Running LXC containers
- Running Docker containers
- Firewall WAN ACCEPT rules with ports
- DNSmasq entries
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix disabled buttons in Network Tweaks using conditional rendering
- Change AdGuard Home ports to avoid conflicts (web: 3003, dns: 5353)
- Add DNS & Proxy link from Tor Shield to Network Tweaks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add always-visible toggle switch at top of dashboard
- Clear visual indication: green when protected, red when exposed
- Shows protection status text and toggle switch
- Easier one-click enable/disable of Tor protection
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add AdGuard Home status card with enable/disable and Open UI button
- Add setAdGuardEnabled RPCD method for Docker container control
- Rename section to "DNS & Proxy Services"
- Responsive grid layout for 3 service cards
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CDN cache status card with enable/disable and restart buttons
- Add WPAD auto-proxy card with enable/disable toggle
- Add getProxyStatus, getWpadStatus, setWpadEnabled RPCD methods
- Move menu to Services section
- Update ACL for CDN cache and WPAD control
Also fixes:
- security-threats: Fix HAProxy socket path for connection stats
- tor-shield: Add missing ACL methods for excluded destinations
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add get_excluded_destinations() method to list bypassed destinations
- Add add_excluded_destination() to exclude IPs/CIDRs/domains from Tor
- Add remove_excluded_destination() to remove exclusions
- Add apply_exclusions() to restart tor-shield with new rules
- Domain resolution attempts to get IP for iptables compatibility
- Existing private network CIDRs (192.168/10/172.16/127) are default excluded
Also includes metablogizer fixes:
- reload_haproxy() helper function
- Server address uses 127.0.0.1 for uhttpd backends
- fix_permissions() on file uploads
PKG_RELEASE: tor-shield=3, metablogizer=3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add reload_haproxy() helper function for consistent reloads
- Use 127.0.0.1 for uhttpd backend address instead of 192.168.255.1
- Call fix_permissions() on upload_file to ensure correct file access
- Update delete_site to use reload_haproxy helper
- Bump PKG_RELEASE to 3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BREAKING: Default policy changed from quarantine to open
- Disabled by default (was enabled)
- Default policy: open (was quarantine - blocked new devices!)
- Auto-zoning: disabled by default
- Auto-parking zone: lan_private (was guest)
- Night block schedule: disabled by default
- Threat auto-ban: disabled by default
Safety mechanisms added:
- MAX_BLOCKED_DEVICES limit (10) prevents mass blocking
- check_safety_limit() function validates before blocking
- clear_all_cg_rules() emergency function via RPCD
- safety_status RPCD method to check current state
UI improvements:
- Added warnings for restrictive policies
- Reordered options (safe options first)
- Clearer descriptions of consequences
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move 9 service apps from admin/secubox/services/ to admin/services/:
- localai, lyrion, magicmirror2, mailinabox, mmpm
- nextcloud, ollama, vhost-manager, mitmproxy
Services now appear under standard LuCI Services menu for consistency.
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>
- Add get_network_info RPCD method:
- Public IPv4/IPv6 detection via external services
- Reverse DNS hostname lookup
- External port accessibility test (upstream router/ISP check)
- Enhance check_service_health:
- Compare DNS resolution against actual public IP
- Detect private IP misconfiguration (192.168.x.x pointing)
- Test external port reachability
- Add Network Connectivity panel to dashboard:
- Shows public IPs with hostnames
- External port 80/443 accessibility status
- Local firewall and HAProxy status
- Improve URL Readiness Checker:
- Display public IP info
- Show specific recommendations with IP addresses
- Detect and explain DNS pointing to private IP
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Document all features including:
- Health monitoring and URL readiness checker
- Service publishing workflow
- Health check API usage
- Troubleshooting guide for common issues
- UCI configuration reference
- RPCD methods reference
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add health check RPCD methods:
- check_service_health: Check DNS, cert, firewall for single domain
- check_all_health: Batch check all published services
- Add URL Readiness Checker wizard card to dashboard:
- Check if domain DNS resolves correctly
- Verify firewall ports 80/443 are open
- Check SSL certificate status
- Show actionable recommendations
- Display inline health status badges on service rows:
- DNS resolution status (ok/failed)
- Certificate expiry (ok/warning/critical/expired)
- Add health summary bar showing overall system status
- Add per-service health check button
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Automatically creates firewall rules for HAProxy when:
- Requesting a certificate (haproxyctl cert add)
- Publishing a service with a domain (service-registry)
Added firewall rules:
- HAProxy-HTTP: Allow port 80 from WAN (ACME challenges)
- HAProxy-HTTPS: Allow port 443 from WAN (HTTPS traffic)
Rules are only created if they don't exist, preventing duplicates.
Firewall reloads automatically after rule creation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Certificate issuance now uses webroot mode instead of standalone:
- HAProxy routes /.well-known/acme-challenge/ to local ACME webserver
- Added acme_challenge backend on port 8402
- Uses busybox httpd to serve challenge files
- No HAProxy restart required during certificate requests
- Config auto-regenerates before cert request to ensure ACME backend
This eliminates downtime during certificate issuance and allows
multiple concurrent certificate requests.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
HAProxy Certificates:
- Add async certificate request API (start_cert_request, get_cert_task)
- Non-blocking ACME requests with background processing
- Real-time progress tracking with phases (starting → validating → requesting → verifying → complete)
- Add staging vs production mode toggle for ACME
- New modern UI with visual progress indicators
- Task persistence and polling support
Service Registry:
- Fix QR codes using api.qrserver.com (Google Charts deprecated)
- Fix form prefill with proper _new section selectors
- Add change event dispatch for LuCI form bindings
- Update landing page generator with working QR API
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove expect clause from RPC declarations to get raw response
- Add proper error handling with catch blocks for all RPC calls
- Fix landing page generator to chmod 644 after generation
- Fixes "No Services Found" issue in dashboard
- Fixes "Forbidden" error when accessing landing page
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement Service Registry LuCI app for unified service management:
- RPCD backend aggregating services from HAProxy, Tor, netstat, LXC
- One-click publish to clearnet (HAProxy+ACME) and/or Tor hidden service
- Static landing page generator with QR codes for all URLs
- LuCI dashboard with service grid, quick publish form
- CLI tool (secubox-registry) for command-line management
- Share buttons for X, Telegram, WhatsApp
RPCD methods: list_services, publish_service, unpublish_service,
generate_landing_page, get_qr_data, list_categories
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix tor-shield/api.js: Use baseclass.extend() pattern correctly
- Fix tor-shield ACL: Add missing 'restart' write permission
- Fix secubox-app-tor: Disable conflicting default tor init in postinst
- Move metablogizer menu from secubox/services to admin/services
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The RPC declaration with `expect: { sites: [] }` extracts the array
directly, so data[1] IS the sites array, not an object with .sites property.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add /etc/config/metablogizer with default settings
- Update Makefile to install config as conffile
- Fixes 404 error when accessing MetaBlogizer in LuCI
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>
- Change evt.Line contains -> evt.Line.Raw contains in parsers
(pipeline.Line type requires .Raw accessor for string operations)
- Remove invalid filter: field from acquisition configs
(filter belongs in parsers, not acquisition files)
Fixes CrowdSec v1.7.6 startup failures.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New luci-app-metablogizer package replacing metabolizer with simplified
static site publishing:
- RPCD backend with create/delete/sync site methods
- Auto HAProxy vhost creation with SSL/ACME
- Nginx LXC container integration for serving static files
- Git sync from Gitea repositories
- QR code generation for published URLs
- Social share buttons (Twitter, LinkedIn, Facebook, Telegram, WhatsApp, Email)
- Drag-and-drop file upload UI
- SecuBox light theme styling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Bump CrowdSec version from 1.7.4 to 1.7.6
- Add modernc.org/sqlite v1.34.2 vendor module (Go 1.21 compatible)
- Patch strings.SplitSeq in hubtest for Go 1.23 compatibility
- Add replace directive for sqlite to use vendored version
Built and tested: crowdsec_1.7.6-r1_aarch64_cortex-a72.ipk (80MB)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- README.md: Update to v0.16.0 with all 38 modules categorized
- CHANGELOG.md: Create comprehensive changelog (v0.12.0-v0.16.0)
- CLAUDE.md: Add toolchain build rules for Go/CGO packages
- secubox-tools/README.md: Add SDK vs toolchain build guidance
- TODO-ANALYSE.md: Mark completed tasks, update health score
- HISTORY.md: Document ARM64 toolchain discovery, multi-instance
- dev-status-widget.js: Update stats (38 modules, 1500 commits)
SDK builds produce LSE atomics that crash on some ARM64 CPUs.
Go/CGO packages (crowdsec, netifyd) must use full toolchain.
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>
- Add publish_to_www RPCD method to publish static files to /www/blog
- Add Build & Publish card in sync.js with configurable publish path
- Add generate RPC call for building site
- Fix file permissions for all RPCD scripts and init.d scripts
- Bump luci-app-hexojs to 1.0.0-r3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Streamlit Instances:
- Add Publish button with HAProxy integration (uses instance port)
- Add Edit dialog for modifying instance settings
- Replace enable/disable buttons with checkbox
- Get LAN IP dynamically from status data
- Bump luci-app-streamlit to r8
HAProxy:
- Add haproxy-acme-cron script for background cert processing
- Cron runs every 5 minutes to issue pending ACME certificates
- Prevents UI blocking during certificate issuance
- Bump secubox-app-haproxy to r19
RPCD:
- Fix json_error to return consistent format with json_success
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix enabled/disabled select showing wrong value
- Normalize memory limit values (1G/2G/4G -> 1024M/2048M/4096M)
- Fix boolean value handling for headless and usage stats
- Use Object.assign for conditional selected attribute
- Bump to r6
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Instances tab to LuCI Streamlit dashboard
- RPCD backend: list/add/remove/enable/disable instances
- API module: instance management methods
- UI: Instance table with status, port, enable/disable/remove actions
- Add Instance form with app selector and auto port assignment
- Apply & Restart button to apply instance changes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move nested functions outside parent functions (ash doesn't support local functions)
- Fix _build_instance_entry and _print_instance_json syntax
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add multi-instance mode: run multiple apps on different ports
- New UCI config structure with 'instance' sections
- Container starts multiple streamlit processes via STREAMLIT_INSTANCES env
- CLI commands: instance list/add/remove/enable/disable
- Each instance has its own port, requirements auto-install
- Backward compatible: single-app mode still works
- Bumped to 1.0.0-r4
Example config:
config instance 'dashboard'
option app 'dashboard.py'
option port '8502'
option enabled '1'
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Auto-detect and install app-specific requirements on container start
- Supports: <app>.requirements.txt, <app>_requirements.txt, requirements.txt
- Uses hash-based caching to avoid reinstalling on each restart
- Bumped to 1.0.0-r3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes:
- HAProxy: Prevent duplicate server names when both inline and separate
server UCI sections exist for same backend
- Streamlit: Force --server.headless=true in start script (required for server)
- Dashboard: Optimize get_dashboard_data RPC call (6.56s → 0.09s) by using
fast catalog counting instead of slow appstore list command
- Exposure: Add themed dashboard with SecuBox styling
- ACL: Add missing RPCD permissions for various LuCI apps
Version bumps:
- luci-app-exposure: 1.0.0-r3
- secubox-core: 0.10.0-r5
- secubox-app-haproxy: 1.0.0-r18
- secubox-app-streamlit: 1.0.0-r2
- Portal: v0.15.51
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add cert_is_production() to detect Let's Encrypt staging certificates
- Add cert_validate_public() to verify certificate publicly via curl/openssl
- Add cert_info() to display certificate details (domain, issuer, dates)
- Add cmd_cert_verify command for on-demand certificate verification
- Update cmd_cert_list to show staging/production status with icons
- Update cmd_cert_add to warn about staging mode and verify after issuance
- Bump package release to r16
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace buttons with toggle switches for enabling/disabling exposures
- Show current exposure status with colored indicators
- Load and display Tor hidden services and SSL backends status
- Add stats cards for exposable services, Tor services, and SSL backends
- Modal dialogs for configuring exposure parameters on toggle
- Bump luci-app-exposure to 1.0.0-r2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix HAProxy certificate key naming (.key -> .crt.key) for directory loading
- Add auto-fix in container startup script for existing certificates
- Add list_exposed_services RPC method to fetch services from secubox-exposure
- Add dynamic port scanning for running services discovery
- Add "Quick Select" dropdown in Add Server modal for service auto-fill
- Bump luci-app-haproxy to 1.0.0-r8
- Bump secubox-app-haproxy to 1.0.0-r15
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- HAProxy overview: Add prominent emergency banner showing service status
with quick health indicators (Container/HAProxy/Config) and one-click
Restart/Start/Stop buttons
- SecuBox dashboard: Add Critical Services Quick Restart section with
buttons for HAProxy, CrowdSec, Tor Shield, and Gitea
- Metabolizer config: Fix portal_path to /www/blog
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Exposure Manager:
- Fix RPCD subshell issues in status and ssl_list methods
- Fix JS views to handle both array and object API responses
MagicMirror2:
- Change default port from 8082 to 8085 (avoid CyberFeed conflict)
- Update mm2ctl, RPCD, settings.js, dashboard.js, config
Tor Shield:
- Add restart method to RPCD and API
- Add health status minicard (Service, Bootstrap, DNS, Kill Switch)
Portal:
- Add 'active-ports' section for detected services
- Separate portal apps (Services) from detected ports (Active Ports)
Service Detection:
- Prioritize port-based identification over process name
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- RPCD: Use temp file for scan to avoid pipe subshell issues
- api.js: Use baseclass.extend() for proper LuCI module pattern
- Menu: Remove UCI dependency that caused 404
- Makefile: Make haproxy/tor optional dependencies
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New features in this release:
- Service Exposure integration in network section
- Security stats on dashboard (WAN drops, firewall rejects, CrowdSec)
- Threat Monitor in security cards
- Fixed http:// URLs for local services
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New app entry for service-exposure in portal network apps:
- Port conflict management
- Tor hidden services
- HAProxy SSL backends
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New unified tool for service exposure management:
- Port conflict detection and resolution (scan, conflicts, fix-port)
- Dynamic Tor hidden service management (tor add/list/remove)
- HAProxy SSL reverse proxy configuration (ssl add/list/remove)
Commands:
secubox-exposure scan # List listening services
secubox-exposure conflicts # Detect port collisions
secubox-exposure tor add gitea # Create .onion for service
secubox-exposure ssl add svc domain # Add HAProxy SSL backend
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Service detection now prioritizes process name matching over port-based
detection for more accurate identification of netifyd, streamlit,
cyberfeed, metabolizer, magicmirror, and picobrew services.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Services in LXC/Docker containers don't have SSL certificates,
so always use http:// instead of inheriting the browser's protocol.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add threat-monitor app to security section in portal.js
- Add security stats RPC call (get_security_stats)
- Display packets blocked and alerts on dashboard
- Add Threat Monitor to featured quick access apps
- Show WAN dropped + firewall rejects in events section
- Link to Threat Monitor dashboard from events
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Security Stats:
- Add get_security_stats RPCD method for quick overview
- Track WAN drops, firewall rejects, CrowdSec bans
- Add secubox-stats CLI tool for quick stats check
Gitea Mirror Commands:
- Add mirror-sync to trigger mirror repository sync
- Add mirror-list to show all mirrored repos
- Add mirror-create to create new mirrors from GitHub URLs
- Add repo-list to list all repositories
- Requires API token: uci set gitea.main.api_token=<token>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- haproxy: Add explicit restart_service function
- tor-shield: Add explicit restart_service function
- wireguard-dashboard/qrcode.js: Use baseclass.extend() pattern
to fix "factory yields invalid constructor" error
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
HAProxy requires certificate files to contain both the fullchain
(cert + intermediate CA) and the private key concatenated together.
Changes:
- haproxyctl: Fix cert_add to create combined .pem files
- haproxy-sync-certs: New script to sync ACME certs to HAProxy format
- haproxy.sh: ACME deploy hook for HAProxy
- init.d: Sync certs before starting HAProxy
- Makefile: Install new scripts, add cron job for cert sync
This fixes the "No Private Key found" error when HAProxy tries to
load certificates that only contain the fullchain without the key.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The RPC expect clause unwraps responses - when `expect: { peers: [] }`
is used, the response `{peers: [...]}` gets unwrapped to just `[...]`.
Fixed:
- api.js: getAllData and getMonitoringData now handle both array
and object formats for peers, interfaces, and rates
- overview.js: render and polling functions now safely unwrap
data that may be array or nested object
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
RPCD backend:
- Fix critical json_init bug: variables must be extracted BEFORE
json_init() which wipes the loaded JSON. Affected functions:
save_settings, do_enable, set_bridges, add/remove_hidden_service
- Fix process detection: use pgrep instead of pid file
- Fix uptime calculation: get PID from pgrep, not pid file
- Fix RPC expect unwrapping in getDashboardData for presets
Init script:
- Remove PidFile directive (procd manages the process)
- Clean up stale files before starting to avoid permission issues
- Set proper ownership on torrc after generation
- Fix iptables chain creation to handle "already exists" gracefully
- Remove from OUTPUT chain before attempting chain deletion
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The RPC expect clause unwraps the response, so circuits data may be
an array directly rather than an object with circuits property.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix subshell bug in get_circuits (pipe loses JSON state)
- Add has_control flag to status for frontend awareness
- Fix UseBridges without bridge lines causing Tor to fail
- Fix hidden service directory ownership (tor:tor)
- Change log output from file to syslog
- Fix run directory ownership and permissions (700)
- Add CookieAuthentication for control socket auth
- Use socat instead of nc (BusyBox lacks Unix socket support)
- Add socat as package dependency
- Optimize duplicate curl calls in status check
- Use fallback IP services for real_ip detection
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add get_services RPCD method to detect listening TCP services
- Map known ports to service names, icons, and categories
- Display clickable service cards in portal Services tab
- Services link directly to their URLs (e.g., :3000 for Gitea)
- Filter to show only externally accessible services with URLs
- Add ACL permissions for portal and admin apps
Detected services include: Gitea, HexoJS, CyberFeed, Streamlit,
HAProxy Stats, Netifyd, LuCI, Lyrion, and more.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
HexoJS now serves dynamically on :4000 via HAProxy vhost routing.
- Disabled auto_publish in metabolizer
- Disabled portal in hexojs
- /www stays free for SecuBox portal and other apps
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 'generate' as alias for 'build' command
- Rename cmd_publish for drafts to cmd_publish_draft
- Fix duplicate cmd_publish functions
- Add portal config section with /www/blog path
- publish draft <slug> for drafts, publish for portal
- Metabolizer integration now working
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- RPCD _add_backend now parses inline 'server' option format
- Servers embedded in backend response with inline flag
- update_server converts inline servers to separate UCI sections
- delete_server handles both inline and separate server sections
- API and UI pass inline flag for proper handling
Fixes server port editing in LuCI backends interface.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add showEditVhostModal() for editing virtual host properties
- Add showEditBackendModal() for editing backend configuration
- Add showEditServerModal() for editing server properties
- Modern card-based UI with inline edit/delete actions
- Toggle enable/disable for backends
- Fix haproxyctl to read server option from backend UCI sections
- Add debug logging to container startup script
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change all hardcoded /blog/ paths to use / as root:
Theme configuration:
- _config.yml: Menu paths now /cybersecurity/ instead of /blog/cybersecurity/
- Blog submenu path changed to /categories/
Layout templates:
- post.ejs: Category link uses url_for with root path
- index.ejs: "Voir le blog" links to /categories/
- category.ejs: Breadcrumb and back links use /categories/
Scripts:
- dynamic-blog.js: Category paths now /{slug}/ instead of /blog/{slug}/
- Menu blog path changed to /categories/
Presets:
- tech.yml: Menu paths updated
- portfolio.yml: Blog link updated
hexoctl:
- Default portal_path changed from /www/blog to /www
- Help text updated
This allows the blog to be served from the root URL with categories
at /{category}/ paths.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change pidfile from haproxy-lxc.pid to haproxy.pid for consistency
with the actual container name.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change container references from 'haproxy-lxc' to 'haproxy' to match
the actual container name used by secubox-app-haproxy. This fixes
the LuCI status view showing container_running: false.
Fixes affected methods:
- method_status: container existence and state checks
- method_get_stats: container running check
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Templates now properly use Hexo's url_for() helper:
- apps.ejs: navigation links
- category.ejs: breadcrumb, apps, services, blog links
- showcase.ejs: contact, portfolio, apps, services links
This ensures all links work correctly when root is set to a
subdirectory (e.g., /blog/ instead of /)
Bumped release to r5
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Calculate web root from portal path (e.g., /www/blog → /blog/)
- Update _config.yml root setting before regenerating
- Run hexo clean && generate to apply new root
- Bumped release to r4
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Piped while loop runs in subshell, JSON additions don't persist
- Use temp file + redirect to avoid subshell issue
- Also fix list_backups with same pattern
- Bumped release to r2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Server now binds to 0.0.0.0 instead of localhost for external access
- Added publish command to copy static files to /www/blog/
- Startup script always regenerates to ensure correct binding
- Bumped release to r3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add gitea_status, gitea_sync, gitea_clone, gitea_save_config RPCD methods
- Add Gitea section to sync.js with config form and sync buttons
- Update ACL for new Gitea methods
- Fix luci-app-metabolizer install section for RPCD executable
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove yaml import, use simple string parsing for front matter
- Remove dependency on host metabolizerctl
- Use environment variables for paths (METABOLIZER_CONTENT)
- Remove switch_page calls that fail in container
- CMS now works standalone inside Streamlit container
- Bump to r2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Export PATH at top of startup script for git binary
- Export HOME=/data for proper environment
- Set SCRIPT_TYPE=sh in app.ini (no bash in Alpine)
- Bump to r5
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Alpine's adduser wasn't creating the group properly, causing
chown git:git to fail with "unknown group".
- Add explicit addgroup -g 1000 git before adduser
- Use -G git flag to assign user to the group
- Bump to r4
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use /bin/sh instead of /bin/bash for git user shell
- Check for su-exec binary instead of marker file for deps
- Always recreate git user on startup (doesn't persist in container)
- Set explicit UID 1000 for git user
- Bump release to r3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create /data, /opt, /run directories in rootfs during install
- Simplify mount entries (single /data mount)
- Ensure host data directories exist before creating LXC config
- Install dependencies (git, su-exec, etc.) on first container run
- Create required subdirectories in startup script
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add is_installed() and is_running() checks to init.d
- Show reason when service not running (disabled/not installed)
- Enable gitea by default in UCI config
- Require installation before starting
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Metabolizer Blog Pipeline - integrated CMS for SecuBox:
- Gitea: Mirror GitHub repos, store blog content
- Streamlit: CMS app with markdown editor and live preview
- HexoJS: Static site generator (clean → generate → publish)
- Webhooks: Auto-rebuild on git push
- Portal: Static blog served at /blog/
Pipeline: Edit in Streamlit CMS → Push to Gitea → Build with Hexo → Publish
Packages:
- secubox-app-streamlit: Streamlit server with LXC container
- luci-app-streamlit: LuCI dashboard for Streamlit apps
- secubox-app-metabolizer: CMS pipeline orchestrator
CMS Features:
- Two-column markdown editor with live preview
- YAML front matter editor
- Post management (drafts, publish, unpublish)
- Media library with image upload
- Git sync and Hexo build controls
- Cyberpunk theme styling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Amber (#ffb000) for titles, borders, hover effects
- Green (#33ff33) for dates, sources, navigation
- Gradient timeline line (amber → green → amber)
- Glow effects on text and borders
- Audio items highlighted in green
- Status bar with item count and sync time
- Emojified content from AWK parser preserved
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Left panel (1/3): CRT monitor style with:
- Phosphor green text with glow effect
- Scanlines overlay
- Screen curvature effect
- Power LED with pulse animation
- VT323 monospace font
- Scrollable latest 15 items
- Right panel (2/3): Standard cyberpunk timeline with:
- Vertical timeline with neon gradient line
- Date grouping
- Audio player support
- Source badges
- Responsive: stacks vertically on mobile (CRT on top)
- Auto-refresh every 3 minutes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Star Wars opening crawl style timeline with:
- Starfield background with twinkling stars
- "A long time ago in a network far, far away...." intro
- CYBERFEED logo zoom animation
- 3D perspective text crawl (rotateX transform)
- Yellow text (#ffd700) with cyan accents (#0ff)
- Auto-refresh every 3 minutes
- Controls: PAUSE, RESET, HOME, REFRESH
- Fix LuCI API array handling in getFeeds/getItems:
- RPC `expect` declarations auto-extract nested properties
- Response IS the array, not res.feeds/res.items
- Add Array.isArray check to handle both cases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move emoji injection inside AWK parser to avoid corrupting JSON keys
- Use grep -o | wc -l for accurate item count on single-line JSON
- Emojis now only applied to title and desc fields, not URLs or keys
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rewrite RSS parser to use BusyBox-compatible AWK (no capture groups)
- Use extract_tag() helper with substr() instead of match() capture
- Use extract_attr() helper for XML attribute extraction
- Fix settings.js select elements to properly set initial value
- Use sel.value = ... instead of selected attribute
- Add new UCI config options for enhanced features:
- download_media, media_dir, history_file, generate_timeline
- Bump versions: secubox-app-cyberfeed 0.2.1, luci-app-cyberfeed 0.1.1
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Radio France presets (France Inter, France Culture, France Info, FIP, Mouv)
- Add international radio (BBC World, NPR)
- Add tech podcasts (Darknet Diaries, Changelog, Syntax.fm)
- Add 'radio' category to feed selector
- One-click quick-add buttons for all radio presets
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- get_feeds now returns {"feeds": [...]} instead of raw array
- get_items now returns {"items": [...]} instead of raw array
- Updated api.js to extract arrays from wrapped responses
- Fixes feed list not displaying in LuCI dashboard
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New packages:
- secubox-app-cyberfeed: Core RSS aggregator service
- Pure shell script, OpenWrt compatible
- Cyberpunk emoji injection based on content keywords
- Caching with configurable TTL
- JSON and HTML output with neon/glitch effects
- RSS-Bridge support for social media (Facebook, Twitter, YouTube)
- luci-app-cyberfeed: LuCI dashboard with cyberpunk theme
- Dashboard with stats, quick actions, recent items
- Feed management with add/delete
- RSS-Bridge templates for easy social media setup
- Preview with category filtering
- Settings page for service configuration
Features:
- Auto-emojification (security, tech, mystical themes)
- Dark neon UI with scanlines and glitch effects
- RSS-Bridge integration for Facebook/Twitter/YouTube
- Category-based filtering
- Auto-refresh via cron (5 min default)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add pollRegistered flag to prevent duplicate poll registration
- Fix refreshDashboard to use replaceChild instead of dom.content
- Build content arrays explicitly to avoid null values in arrays
- Fix disabled attribute handling for action buttons
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix TypeError "haproxy.api factory yields invalid constructor" by
refactoring api.js to use correct LuCI module pattern:
- Define RPC calls at module level with rpc.declare()
- Reference them in baseclass.extend() object
- Add getDashboardData helper function at module level
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add secubox-app-haproxy: LXC-containerized HAProxy service
- Alpine Linux container with HAProxy
- Multi-certificate SSL/TLS termination with SNI routing
- ACME/Let's Encrypt auto-renewal
- Virtual hosts management
- Backend health checks and load balancing
- Add luci-app-haproxy: Full LuCI web interface
- Overview dashboard with service status
- Virtual hosts management with SSL options
- Backends and servers configuration
- SSL certificate management (ACME + import)
- ACLs and URL-based routing rules
- Statistics dashboard and logs
- Settings for ports, timeouts, ACME
- Update luci-app-secubox-portal:
- Add Services category with HAProxy, HexoJS, PicoBrew,
Tor Shield, Jellyfin, Home Assistant, AdGuard Home, Nextcloud
- Make portal dynamic - only shows installed apps
- Add empty state UI for sections with no apps
- Remove 404 errors for uninstalled apps
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add start-hexo.sh script as container init command
- Set PATH properly for hexo CLI in lxc_exec()
- Container now starts Hexo server automatically on boot
- Falls back to tail -f /dev/null if no site exists
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- secubox-app-hexojs: LXC-containerized Hexo service with Node.js
- hexoctl control script for container/site management
- Bundled CyberMind theme with dark/light mode
- Theme presets (minimal, tech, portfolio)
- Post/page scaffolds
- luci-app-hexojs: Full CMS dashboard
- Overview with stats and quick actions
- Post editor with Markdown toolbar and preview
- Media library browser
- Categories and tags management
- Apps portfolio for CyberMind theme
- Build and deploy to GitHub Pages
- GitHub Sync wizard (clone, pull, push)
- Theme configuration and presets
- Site settings
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add secubox-app-tor (backend) and luci-app-tor-shield (frontend) packages
for Tor anonymization on OpenWrt.
Backend features:
- UCI configuration with presets (anonymous, selective, censored)
- procd init script with iptables transparent proxy
- torctl CLI tool for status, enable/disable, circuits, leak-test
- DNS over Tor and kill switch support
- Hidden services and bridge management
Frontend features:
- Modern purple/onion themed dashboard
- One-click master toggle with visual status
- Real-time circuit visualization (Guard -> Middle -> Exit)
- Hidden services (.onion) management with copy/QR
- Bridge configuration (obfs4, snowflake, meek-azure)
- Leak detection tests
- Advanced settings for ports and exit node restrictions
Note: LuCI package renamed to luci-app-tor-shield to avoid conflict
with existing luci-app-tor package in OpenWrt LuCI feeds.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Flask 1.1.2 requires specific old versions of dependencies:
- Jinja2==2.11.3 (escape moved in 3.1)
- markupsafe==1.1.1
- itsdangerous==1.1.0 (json removed in 2.x)
- Werkzeug==1.0.1
- click==7.1.2
- pybeerxml<2.0.0 (Parser import changed in 2.x)
- marshmallow<4.0.0
Also:
- Use pip-installed package instead of git repo mount
- Simplify LXC mounts to just data directories
Tested and working on OpenWrt 24.10.5.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add two new packages for self-hosted brewing controller support:
secubox-app-picobrew:
- LXC container-based PicoBrew Server installation
- Alpine Linux rootfs with Python/Flask environment
- UCI configuration for port, memory, brewing defaults
- procd service management with respawn
- Commands: install, uninstall, update, status, logs, shell
luci-app-picobrew:
- Modern dashboard UI with SecuBox styling
- Service controls (start/stop/restart/install/update)
- Real-time status monitoring and logs
- Settings page for server and brewing configuration
- RPCD backend with full API coverage
Supports PicoBrew Zymatic, Z, Pico C, and Pico Pro devices.
Repository: https://github.com/CyberMind-FR/picobrew-server
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The wizard.js was looking for a global QRCode object that doesn't exist.
Updated to import and use our qrcode module like other views do.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed from baseclass.extend() to simple object return pattern
to match other libraries (chart.js). The baseclass dependency
was causing the module to fail loading.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The JavaScript QR code fallback was limited to Version 5 (106 bytes max),
but WireGuard configs are typically 200-250 bytes. This caused QR code
generation to fail when the backend qrencode binary is not installed.
Changes:
- Auto-select optimal QR version (1-20) based on data length
- Support up to 858 bytes (Version 20)
- Proper Reed-Solomon error correction with dynamic generator polynomials
- Data interleaving for multiple EC blocks
- Alignment patterns for all versions
- Version info encoding for version 7+
- Quiet zone in SVG output
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Refactor CROWDSEC object to use luci.crowdsec-dashboard RPC instead of file.exec
- Add getNftablesStats() for accurate blocked IPs count from firewall bouncer
- Update updateDiskUsage() to use luci.system-hub.get_system_status RPC
- Update loadSystemLogs() to use luci.system-hub.get_logs RPC
- Add proper ACL permissions for luci.crowdsec-dashboard and luci.system-hub
- Bump version to 1.5.0-r3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Downgrade golang.org/x/net from v0.44.0 to v0.33.0 (Go 1.23 compatible)
- Patch out http.Protocols usage (Go 1.24+ feature) from:
- pkg/acquisition/modules/http/run.go
- pkg/acquisition/modules/appsec/config.go
- pkg/acquisition/modules/kubernetesaudit/config.go
- pkg/apiserver/apiserver.go
- Patch strings.SplitSeq to strings.Split (Go 1.24+ iterator feature) in:
- cmd/crowdsec-cli/clisetup/acquisition.go
- cmd/crowdsec/flags.go
This fixes the build failure caused by CrowdSec 1.7.4 using Go 1.24+
features while OpenWrt SDK ships Go 1.23.x.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The -x flag requires exact process name match which doesn't work
reliably on OpenWrt/BusyBox. Removed -x from all pgrep calls in:
- luci-app-bandwidth-manager
- luci-app-secubox-security-threats
- luci-app-auth-guardian
- luci-app-media-flow
- luci-app-vhost-manager
- luci-app-network-modes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add RPC call to fetch CrowdSec nftables statistics
- Replace Security Modules widget with IPs Blocked widget
- Show active/inactive status based on firewall bouncer health
- Add detailed breakdown in System Overview (IPv4/IPv6, CAPI/local)
- Gracefully handle missing CrowdSec dashboard package
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove -q (quiet) flag from wget to show download errors
- Use architecture-specific tarball (60MB) instead of multi-arch (126MB)
- Add fallback to multi-arch tarball if ARM download fails
- Add explicit error messages for download and extraction failures
- Verify download file exists and is non-empty before extraction
The previous -q flag was hiding the actual wget error, making it
difficult to diagnose download failures in the chroot environment.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- lxc_create_rootfs now checks for Lyrion installation (slimserver.pl)
instead of just Alpine (alpine-release) to detect complete installs
- Auto-cleanup incomplete installations where Alpine downloaded but
Lyrion failed to install (e.g., network issues during chroot)
- Add verification after installation to confirm Lyrion was installed
- Add 'destroy' command to manually clean up failed installations
- Bump version to 2.0.1
This fixes the issue where 'lyrionctl install' would report success
when Alpine was downloaded but the chroot setup script failed silently.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use L.url() for proper ubus endpoint URL
- Pass messages as array instead of JSON string
- Add credentials and better error handling
- Fix AbortController error handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change default API port from 8080 to 8081
- Increase chat API timeout to 120 seconds (LLMs can be slow on ARM)
- Use custom fetch-based chat call with AbortController for timeout control
- Fix wget/curl timeout for RPCD backend
Resolves "XHR request timed out" errors when using chat with TinyLlama.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace Docker/LXC-based approach with direct binary download
- Download LocalAI v2.25.0 binary from GitHub releases
- Add localaictl CLI for install, model management, and service control
- Change default port to 8081 (avoid CrowdSec conflict on 8080)
- Remove secubox-app-localai-wb (merged into secubox-app-localai)
- Add model presets: tinyllama, phi2, mistral
Usage:
localaictl install
localaictl model-install tinyllama
/etc/init.d/localai enable && /etc/init.d/localai start
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New package for building LocalAI from source with llama-cpp backend:
- localai-wb-ctl: On-device build management
- check: Verify build prerequisites
- install-deps: Install build dependencies
- build: Compile LocalAI with llama-cpp
- Model management, service control
- build-sdk.sh: Cross-compile script for SDK
- Uses OpenWrt toolchain for ARM64
- Produces optimized binary with llama-cpp
Alternative to Docker-based secubox-app-localai for native builds.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New LuCI application for Ollama management:
- Dashboard with service status and controls
- Model management (pull, remove, list)
- Chat interface with model selection
- Settings page for configuration
Files:
- RPCD backend (luci.ollama)
- Dashboard, Models, Chat, Settings views
- ACL and menu definitions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Download Docker image layers directly via Registry API
- No dockerd or podman daemon required anymore
- Same approach as mitmproxy and magicmirror2 packages
- All backends included (llama-cpp, whisper, etc.)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Updated default version from v2.25.0 to v3.10.0
- Fixed binary URL format: local-ai-v3.10.0-linux-arm64
- Updated Docker image tag to v3.10.0-ffmpeg
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add runtime_is_working() to verify daemon connectivity
- Falls back to standalone binary with helpful message if daemon not running
- Provides hint: /etc/init.d/dockerd start
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When using `localaictl install --lxc`:
1. If podman/docker available: extracts rootfs from Docker image
- Includes ALL backends (llama-cpp, whisper, etc.)
- Creates LXC container with full LocalAI capabilities
2. If no docker/podman: falls back to standalone binary
- Limited backend support
This gives the best of both worlds:
- LXC lightweight container management
- Full Docker image backends
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- is_running() now checks LXC with lxc-info before Docker/Podman
- get_status() calculates uptime from LXC container PID
- Order: LXC -> Podman -> Docker -> native process
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update is_running() to detect Docker/Podman containers
- Fix get_status() uptime calculation for containers
- Improve do_chat() with better error messages and logging
- Use curl if available for API calls (more reliable than wget POST)
- Add debug logging to syslog (logger -t localai-chat)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
LocalAI changes:
- Rewrite localaictl to use Docker/Podman instead of standalone binary
- Use localai/localai:v2.25.0-ffmpeg image with all backends included
- Fix llama-cpp backend not found issue
- Auto-detect podman or docker runtime
- Update UCI config with Docker settings
New Ollama package:
- Add secubox-app-ollama as lighter alternative to LocalAI
- Native ARM64 support with backends included
- Simple CLI: ollamactl pull/run/list
- Docker image ~1GB vs 2-4GB for LocalAI
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The LuCI rpc.declare with expect: { models: [] } returns the array
directly, not wrapped in {models: [...]}. Fixed all views to handle
this correctly.
- models.js: Check Array.isArray(data) first
- dashboard.js: Extract array from results[1] directly
- chat.js: Same array handling fix
Version: 0.1.0-r12
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add secubox-app-localai package with LXC container support for LocalAI service
- Add luci-app-localai with dashboard, chat, models and settings views
- Implement RPCD backend for LocalAI API integration via /v1/models and /v1/chat/completions
- Use direct RPC declarations in LuCI views for reliable frontend communication
- Add LocalAI and Glances to secubox-portal services page
- Move Glances from services to monitoring section
Packages:
- secubox-app-localai: 0.1.0-r1
- luci-app-localai: 0.1.0-r8
- luci-app-secubox-portal: 0.6.0-r5
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Improve Services tab with pgrep-based status detection
- Add service enable/disable toggle buttons
- Add port forwards table to Firewall tab
- Add process list to System tab
- Add CrowdSec alerts table
- Reorganize quick actions into grouped layout
- Add Flush DNS, Sync NTP, and LuCI Admin shortcuts
- Change URL path from /secubox-dashboard/ to /secubox/
- Bump version to 1.4.1 (v2.4)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use separate -B and -p args for bind address and port
- Add hostname resolution by populating /etc/hosts dynamically
- Add --disable-autodiscover and --disable-check-update flags
- Fixes DNS resolution errors causing immediate container exit
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add secubox-app-glances and luci-app-glances packages:
secubox-app-glances:
- LXC container with nicolargo/glances:latest-full Docker image
- Web UI on port 61208, API on port 61209
- UCI configuration for monitoring options and alert thresholds
- glancesctl management script
luci-app-glances:
- Dashboard view with service status and quick actions
- Embedded Web UI view with iframe
- Settings view for configuration
- RPCD backend with proper ACL permissions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>