diff --git a/.claude/HISTORY.md b/.claude/HISTORY.md index c2a4e9c7..a2e9a547 100644 --- a/.claude/HISTORY.md +++ b/.claude/HISTORY.md @@ -1749,3 +1749,27 @@ git checkout HEAD -- index.html - HAProxy configuration status with configure button - Emancipate form for public exposure - Logs viewer with refresh button + +### 2026-02-15: Generative LuCI Navigation Tree +- **Created luci.secubox-portal RPCD backend** for dynamic component discovery + - `get_tree`: Auto-discovers all `luci-app-*` packages, groups by category + - `get_containers`: Lists LXC containers from `/srv/lxc/` with running state + - `get_vhosts`: Lists HAProxy vhosts from UCI with domain/backend/ssl info + - Categories: SecuBox Core, Security, Media & Streaming, Network & Proxy, Development & CMS, IoT & Home, AI & Communication, System & Management, Other SecuBox Apps +- **Updated luci-tree.js** with dynamic RPC-based interface + - Three tabs: LuCI Apps, Containers, Vhosts + - Refresh button for live updates without page reload + - Stats row showing categories, links, packages, containers, vhosts counts + - Search functionality for filtering modules + - Cyberpunk dark theme with green/cyan accents +- **ACL permissions** for unauthenticated portal access to tree methods + +### 2026-02-15: PeerTube Configuration Fixes +- **Redis ARM64-COW-BUG**: Added `ignore-warnings ARM64-COW-BUG` to redis.conf +- **Redis sentinel**: Disabled (using standalone Redis, not sentinel cluster) +- **RTMPS**: Disabled (no SSL key file needed for live streaming) +- **HAProxy WAF bypass**: Added `waf_bypass=1` to tube.gk2.secubox.in vhost + - Without bypass, mitmproxy WAF stripped Host header causing OAuth errors + - PeerTube validates requests against configured webserver.hostname +- **Listen hostname**: Set to `0.0.0.0` (not domain name) for proper binding +- **Webserver hostname**: Set to `tube.gk2.secubox.in` for OAuth validation diff --git a/.claude/WIP.md b/.claude/WIP.md index 72ad5429..caf8fac9 100644 --- a/.claude/WIP.md +++ b/.claude/WIP.md @@ -1,6 +1,6 @@ # Work In Progress (Claude) -_Last updated: 2026-02-14 (WAF architecture configured)_ +_Last updated: 2026-02-15 (PeerTube + Generative LuCI Tree)_ > **Architecture Reference**: SecuBox Fanzine v3 — Les 4 Couches @@ -74,16 +74,35 @@ _Last updated: 2026-02-14 (WAF architecture configured)_ - User management: create-user, reset-password, list-users - Backup/restore PostgreSQL database - UCI config: main, server, live, transcoding, storage, network, admin sections + - Fixed: Redis ARM64-COW-BUG via `ignore-warnings` config + - Fixed: Redis sentinel disabled (using standalone Redis) + - Fixed: RTMPS disabled (no SSL keys needed) + - Fixed: HAProxy waf_bypass=1 for proper OAuth routing - **PeerTube LuCI Dashboard** — DONE (2026-02-15) - Created `luci-app-peertube` package - - RPCD handler with 11 methods: status, start, stop, install, uninstall, update, logs, emancipate, live_enable, live_disable, configure_haproxy + - RPRD handler with 11 methods: status, start, stop, install, uninstall, update, logs, emancipate, live_enable, live_disable, configure_haproxy - Dashboard with install wizard, status display, service controls - Live streaming toggle with firewall integration - HAProxy configuration button - Emancipate form for public exposure - Logs viewer with refresh +- **Generative LuCI Tree** — DONE (2026-02-15) + - Created `luci.secubox-portal` RPCD backend for dynamic component discovery + - Three RPC methods: get_tree, get_containers, get_vhosts + - Auto-discovers all installed `luci-app-*` packages and groups by category: + - SecuBox Core, Security, Media & Streaming, Network & Proxy + - Development & CMS, IoT & Home, AI & Communication, System & Management + - Discovers LXC containers from `/srv/lxc/` with running state + - Discovers HAProxy vhosts from UCI with domain/backend/ssl info + - Updated `luci-tree.js` with: + - Three tabs: LuCI Apps, Containers, Vhosts + - Refresh button for live updates + - Stats showing packages, containers, vhosts counts + - Search functionality for filtering + - ACL permissions for unauthenticated portal access + ### Just Completed (2026-02-14) - **mitmproxy WAF Wildcard Route Priority Fix** — DONE (2026-02-14) diff --git a/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxyctl b/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxyctl index 571e9f35..77ebdba4 100644 --- a/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxyctl +++ b/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxyctl @@ -1821,6 +1821,8 @@ cmd_reload() { generate_config log_info "Reloading HAProxy configuration..." + # Copy generated config to container's /etc/haproxy/ (HAProxy reads from there) + lxc_exec cp /opt/haproxy/config/haproxy.cfg /etc/haproxy/haproxy.cfg # HAProxy in master-worker mode (-W) reloads gracefully on SIGUSR2 # Fallback to SIGHUP if USR2 fails lxc_exec killall -USR2 haproxy 2>/dev/null || \ diff --git a/package/secubox/secubox-app-mitmproxy/root/srv/mitmproxy/addons/haproxy_router.py b/package/secubox/secubox-app-mitmproxy/root/srv/mitmproxy/addons/haproxy_router.py index 13e8a359..48c733f8 100644 --- a/package/secubox/secubox-app-mitmproxy/root/srv/mitmproxy/addons/haproxy_router.py +++ b/package/secubox/secubox-app-mitmproxy/root/srv/mitmproxy/addons/haproxy_router.py @@ -116,12 +116,19 @@ class HaproxyRouter: host = flow.request.host_header or flow.request.host backend = self._get_backend(host) - # Set the upstream server + # Save original Host header before routing + original_host_header = flow.request.headers.get("Host", host) + + # Set the upstream server (changes internal routing destination) flow.request.host = backend[0] flow.request.port = backend[1] + # CRITICAL: Restore original Host header for backend validation + # Many backends (PeerTube OAuth, etc.) validate Host header against config + flow.request.headers["Host"] = original_host_header + # Log routing decision - ctx.log.debug(f"ROUTE: {host} -> {backend[0]}:{backend[1]}") + ctx.log.debug(f"ROUTE: {host} -> {backend[0]}:{backend[1]} (Host: {original_host_header})") # Store original host for analytics flow.metadata['original_host'] = host