Fix portal auth and add watchdog support

api/main.py:
- Persist default admin user on first load
- Add startup event to ensure users.json exists
- Better error handling for JSON decode errors

secubox-portal.service:
- Restart=always with WatchdogSec=30
- RuntimeDirectory=secubox ensures socket dir exists
- ExecStartPre creates /etc/secubox with proper ownership
- StartLimitBurst=5 prevents restart loops

Fixes authentication issues on fresh boot.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-03-24 12:54:04 +01:00
parent 948003c307
commit 482ffaf7aa
51 changed files with 622 additions and 222 deletions

121
docs/SCREENSHOTS-VM.md Normal file
View File

@ -0,0 +1,121 @@
# SecuBox Module Screenshots - SecuBox VM (VirtualBox)
*Generated: 2026-03-24 12:52:31*
**Host:** https://localhost:9443
**Description:** Development/testing virtual machine
---
## Module Gallery
### Access
| Module | Screenshot | Status |
|--------|------------|--------|
| 🔐 **Authentication** | ![Authentication](screenshots/vm/auth.png) | ✅ Captured |
| 🛡️ **Network Access Control** | ![Network Access Control](screenshots/vm/nac.png) | ✅ Captured |
| 👥 **User Management** | ![User Management](screenshots/vm/users.png) | ✅ Captured |
| 🔐 **Login Portal** | ![Login Portal](screenshots/vm/portal.png) | ✅ Captured |
### Apps
| Module | Screenshot | Status |
|--------|------------|--------|
| 🎨 **Streamlit** | ![Streamlit](screenshots/vm/streamlit.png) | ✅ Captured |
| ⚡ **StreamForge** | ![StreamForge](screenshots/vm/streamforge.png) | ✅ Captured |
| 📦 **Repository** | ![Repository](screenshots/vm/repo.png) | ✅ Captured |
### DNS
| Module | Screenshot | Status |
|--------|------------|--------|
| 🌍 **DNS Server** | ![DNS Server](screenshots/vm/dns.png) | ✅ Captured |
| 🛡️ **Vortex DNS** | ![Vortex DNS](screenshots/vm/vortex-dns.png) | ✅ Captured |
| 📡 **Mesh DNS** | ![Mesh DNS](screenshots/vm/meshname.png) | ✅ Captured |
### Dashboard
| Module | Screenshot | Status |
|--------|------------|--------|
| 🏠 **Dashboard** | ![Dashboard](screenshots/vm/hub.png) | ✅ Captured |
| 🛡️ **Security Operations Center** | ![Security Operations Center](screenshots/vm/soc.png) | ✅ Captured |
| 📋 **Migration Roadmap** | ![Migration Roadmap](screenshots/vm/roadmap.png) | ✅ Captured |
### Email
| Module | Screenshot | Status |
|--------|------------|--------|
| 📧 **Mail Server** | ![Mail Server](screenshots/vm/mail.png) | ✅ Captured |
| 💌 **Webmail** | ![Webmail](screenshots/vm/webmail.png) | ✅ Captured |
### Monitoring
| Module | Screenshot | Status |
|--------|------------|--------|
| 📊 **Netdata** | ![Netdata](screenshots/vm/netdata.png) | ✅ Captured |
| 🔬 **Deep Packet Inspection** | ![Deep Packet Inspection](screenshots/vm/dpi.png) | ✅ Captured |
| 📱 **Device Intelligence** | ![Device Intelligence](screenshots/vm/device-intel.png) | ✅ Captured |
| 👁️ **Watchdog** | ![Watchdog](screenshots/vm/watchdog.png) | ✅ Captured |
| 🎬 **Media Flow** | ![Media Flow](screenshots/vm/mediaflow.png) | ✅ Captured |
### Network
| Module | Screenshot | Status |
|--------|------------|--------|
| 🌐 **Network Modes** | ![Network Modes](screenshots/vm/netmodes.png) | ✅ Captured |
| 📊 **QoS Manager** | ![QoS Manager](screenshots/vm/qos.png) | ✅ Captured |
| 📈 **Traffic Shaping** | ![Traffic Shaping](screenshots/vm/traffic.png) | ✅ Captured |
| ⚡ **HAProxy** | ![HAProxy](screenshots/vm/haproxy.png) | ✅ Captured |
| 🚀 **CDN Cache** | ![CDN Cache](screenshots/vm/cdn.png) | ✅ Captured |
| 🏗️ **Virtual Hosts** | ![Virtual Hosts](screenshots/vm/vhost.png) | ✅ Captured |
### Privacy
| Module | Screenshot | Status |
|--------|------------|--------|
| 🧅 **Tor Network** | ![Tor Network](screenshots/vm/tor.png) | ✅ Captured |
| 🌐 **Exposure Settings** | ![Exposure Settings](screenshots/vm/exposure.png) | ✅ Captured |
| 🔐 **Zero-Knowledge Proofs** | ![Zero-Knowledge Proofs](screenshots/vm/zkp.png) | ✅ Captured |
### Publishing
| Module | Screenshot | Status |
|--------|------------|--------|
| 📰 **Publishing** | ![Publishing](screenshots/vm/publish.png) | ✅ Captured |
| 💧 **Droplet** | ![Droplet](screenshots/vm/droplet.png) | ✅ Captured |
| 📝 **Metablogizer** | ![Metablogizer](screenshots/vm/metablogizer.png) | ✅ Captured |
### Security
| Module | Screenshot | Status |
|--------|------------|--------|
| 🛡️ **CrowdSec** | ![CrowdSec](screenshots/vm/crowdsec.png) | ✅ Captured |
| 🔥 **Web Application Firewall** | ![Web Application Firewall](screenshots/vm/waf.png) | ✅ Captured |
| 🔥 **Vortex Firewall** | ![Vortex Firewall](screenshots/vm/vortex-firewall.png) | ✅ Captured |
| 🔒 **System Hardening** | ![System Hardening](screenshots/vm/hardening.png) | ✅ Captured |
| 🔍 **MITM Proxy** | ![MITM Proxy](screenshots/vm/mitmproxy.png) | ✅ Captured |
### Services
| Module | Screenshot | Status |
|--------|------------|--------|
| 📦 **Services Portal** | ![Services Portal](screenshots/vm/c3box.png) | ✅ Captured |
| 🦊 **Gitea** | ![Gitea](screenshots/vm/gitea.png) | ✅ Captured |
| ☁️ **Nextcloud** | ![Nextcloud](screenshots/vm/nextcloud.png) | ✅ Captured |
### System
| Module | Screenshot | Status |
|--------|------------|--------|
| ⚙️ **System** | ![System](screenshots/vm/system.png) | ✅ Captured |
| 💾 **Backup** | ![Backup](screenshots/vm/backup.png) | ✅ Captured |
### VPN
| Module | Screenshot | Status |
|--------|------------|--------|
| 🔗 **WireGuard VPN** | ![WireGuard VPN](screenshots/vm/wireguard.png) | ✅ Captured |
| 🕸️ **Mesh Network** | ![Mesh Network](screenshots/vm/mesh.png) | ✅ Captured |
| 🔗 **P2P Network** | ![P2P Network](screenshots/vm/p2p.png) | ✅ Captured |

View File

@ -0,0 +1,418 @@
{
"vm": {
"host": {
"name": "SecuBox VM (VirtualBox)",
"url": "https://localhost:9443",
"description": "Development/testing virtual machine"
},
"modules": [
{
"module": "hub",
"name": "Dashboard",
"category": "Dashboard",
"success": true,
"screenshot": "docs/screenshots/vm/hub.png",
"error": null,
"status_code": 200
},
{
"module": "soc",
"name": "Security Operations Center",
"category": "Dashboard",
"success": true,
"screenshot": "docs/screenshots/vm/soc.png",
"error": null,
"status_code": 200
},
{
"module": "roadmap",
"name": "Migration Roadmap",
"category": "Dashboard",
"success": true,
"screenshot": "docs/screenshots/vm/roadmap.png",
"error": null,
"status_code": 200
},
{
"module": "crowdsec",
"name": "CrowdSec",
"category": "Security",
"success": true,
"screenshot": "docs/screenshots/vm/crowdsec.png",
"error": null,
"status_code": 200
},
{
"module": "waf",
"name": "Web Application Firewall",
"category": "Security",
"success": true,
"screenshot": "docs/screenshots/vm/waf.png",
"error": null,
"status_code": 200
},
{
"module": "vortex-firewall",
"name": "Vortex Firewall",
"category": "Security",
"success": true,
"screenshot": "docs/screenshots/vm/vortex-firewall.png",
"error": null,
"status_code": 200
},
{
"module": "hardening",
"name": "System Hardening",
"category": "Security",
"success": true,
"screenshot": "docs/screenshots/vm/hardening.png",
"error": null,
"status_code": 200
},
{
"module": "mitmproxy",
"name": "MITM Proxy",
"category": "Security",
"success": true,
"screenshot": "docs/screenshots/vm/mitmproxy.png",
"error": null,
"status_code": 200
},
{
"module": "netmodes",
"name": "Network Modes",
"category": "Network",
"success": true,
"screenshot": "docs/screenshots/vm/netmodes.png",
"error": null,
"status_code": 200
},
{
"module": "qos",
"name": "QoS Manager",
"category": "Network",
"success": true,
"screenshot": "docs/screenshots/vm/qos.png",
"error": null,
"status_code": 200
},
{
"module": "traffic",
"name": "Traffic Shaping",
"category": "Network",
"success": true,
"screenshot": "docs/screenshots/vm/traffic.png",
"error": null,
"status_code": 200
},
{
"module": "haproxy",
"name": "HAProxy",
"category": "Network",
"success": true,
"screenshot": "docs/screenshots/vm/haproxy.png",
"error": null,
"status_code": 200
},
{
"module": "cdn",
"name": "CDN Cache",
"category": "Network",
"success": true,
"screenshot": "docs/screenshots/vm/cdn.png",
"error": null,
"status_code": 200
},
{
"module": "vhost",
"name": "Virtual Hosts",
"category": "Network",
"success": true,
"screenshot": "docs/screenshots/vm/vhost.png",
"error": null,
"status_code": 200
},
{
"module": "dns",
"name": "DNS Server",
"category": "DNS",
"success": true,
"screenshot": "docs/screenshots/vm/dns.png",
"error": null,
"status_code": 200
},
{
"module": "vortex-dns",
"name": "Vortex DNS",
"category": "DNS",
"success": true,
"screenshot": "docs/screenshots/vm/vortex-dns.png",
"error": null,
"status_code": 200
},
{
"module": "meshname",
"name": "Mesh DNS",
"category": "DNS",
"success": true,
"screenshot": "docs/screenshots/vm/meshname.png",
"error": null,
"status_code": 200
},
{
"module": "wireguard",
"name": "WireGuard VPN",
"category": "VPN",
"success": true,
"screenshot": "docs/screenshots/vm/wireguard.png",
"error": null,
"status_code": 200
},
{
"module": "mesh",
"name": "Mesh Network",
"category": "VPN",
"success": true,
"screenshot": "docs/screenshots/vm/mesh.png",
"error": null,
"status_code": 200
},
{
"module": "p2p",
"name": "P2P Network",
"category": "VPN",
"success": true,
"screenshot": "docs/screenshots/vm/p2p.png",
"error": null,
"status_code": 200
},
{
"module": "tor",
"name": "Tor Network",
"category": "Privacy",
"success": true,
"screenshot": "docs/screenshots/vm/tor.png",
"error": null,
"status_code": 200
},
{
"module": "exposure",
"name": "Exposure Settings",
"category": "Privacy",
"success": true,
"screenshot": "docs/screenshots/vm/exposure.png",
"error": null,
"status_code": 200
},
{
"module": "zkp",
"name": "Zero-Knowledge Proofs",
"category": "Privacy",
"success": true,
"screenshot": "docs/screenshots/vm/zkp.png",
"error": null,
"status_code": 200
},
{
"module": "netdata",
"name": "Netdata",
"category": "Monitoring",
"success": true,
"screenshot": "docs/screenshots/vm/netdata.png",
"error": null,
"status_code": 200
},
{
"module": "dpi",
"name": "Deep Packet Inspection",
"category": "Monitoring",
"success": true,
"screenshot": "docs/screenshots/vm/dpi.png",
"error": null,
"status_code": 200
},
{
"module": "device-intel",
"name": "Device Intelligence",
"category": "Monitoring",
"success": true,
"screenshot": "docs/screenshots/vm/device-intel.png",
"error": null,
"status_code": 200
},
{
"module": "watchdog",
"name": "Watchdog",
"category": "Monitoring",
"success": true,
"screenshot": "docs/screenshots/vm/watchdog.png",
"error": null,
"status_code": 200
},
{
"module": "mediaflow",
"name": "Media Flow",
"category": "Monitoring",
"success": true,
"screenshot": "docs/screenshots/vm/mediaflow.png",
"error": null,
"status_code": 200
},
{
"module": "auth",
"name": "Authentication",
"category": "Access",
"success": true,
"screenshot": "docs/screenshots/vm/auth.png",
"error": null,
"status_code": 200
},
{
"module": "nac",
"name": "Network Access Control",
"category": "Access",
"success": true,
"screenshot": "docs/screenshots/vm/nac.png",
"error": null,
"status_code": 200
},
{
"module": "users",
"name": "User Management",
"category": "Access",
"success": true,
"screenshot": "docs/screenshots/vm/users.png",
"error": null,
"status_code": 200
},
{
"module": "portal",
"name": "Login Portal",
"category": "Access",
"success": true,
"screenshot": "docs/screenshots/vm/portal.png",
"error": "requires_auth",
"status_code": 200
},
{
"module": "c3box",
"name": "Services Portal",
"category": "Services",
"success": true,
"screenshot": "docs/screenshots/vm/c3box.png",
"error": null,
"status_code": 200
},
{
"module": "gitea",
"name": "Gitea",
"category": "Services",
"success": true,
"screenshot": "docs/screenshots/vm/gitea.png",
"error": null,
"status_code": 200
},
{
"module": "nextcloud",
"name": "Nextcloud",
"category": "Services",
"success": true,
"screenshot": "docs/screenshots/vm/nextcloud.png",
"error": null,
"status_code": 200
},
{
"module": "mail",
"name": "Mail Server",
"category": "Email",
"success": true,
"screenshot": "docs/screenshots/vm/mail.png",
"error": null,
"status_code": 200
},
{
"module": "webmail",
"name": "Webmail",
"category": "Email",
"success": true,
"screenshot": "docs/screenshots/vm/webmail.png",
"error": null,
"status_code": 200
},
{
"module": "publish",
"name": "Publishing",
"category": "Publishing",
"success": true,
"screenshot": "docs/screenshots/vm/publish.png",
"error": null,
"status_code": 200
},
{
"module": "droplet",
"name": "Droplet",
"category": "Publishing",
"success": true,
"screenshot": "docs/screenshots/vm/droplet.png",
"error": null,
"status_code": 200
},
{
"module": "metablogizer",
"name": "Metablogizer",
"category": "Publishing",
"success": true,
"screenshot": "docs/screenshots/vm/metablogizer.png",
"error": null,
"status_code": 200
},
{
"module": "streamlit",
"name": "Streamlit",
"category": "Apps",
"success": true,
"screenshot": "docs/screenshots/vm/streamlit.png",
"error": null,
"status_code": 200
},
{
"module": "streamforge",
"name": "StreamForge",
"category": "Apps",
"success": true,
"screenshot": "docs/screenshots/vm/streamforge.png",
"error": null,
"status_code": 200
},
{
"module": "repo",
"name": "Repository",
"category": "Apps",
"success": true,
"screenshot": "docs/screenshots/vm/repo.png",
"error": null,
"status_code": 200
},
{
"module": "system",
"name": "System",
"category": "System",
"success": true,
"screenshot": "docs/screenshots/vm/system.png",
"error": null,
"status_code": 200
},
{
"module": "backup",
"name": "Backup",
"category": "System",
"success": true,
"screenshot": "docs/screenshots/vm/backup.png",
"error": null,
"status_code": 200
}
],
"timestamp": "2026-03-24T12:50:43.368172"
},
"device": {}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 KiB

BIN
docs/screenshots/vm/cdn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
docs/screenshots/vm/dns.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

BIN
docs/screenshots/vm/dpi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

BIN
docs/screenshots/vm/hub.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

BIN
docs/screenshots/vm/nac.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

BIN
docs/screenshots/vm/p2p.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

BIN
docs/screenshots/vm/qos.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

BIN
docs/screenshots/vm/soc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

BIN
docs/screenshots/vm/tor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
docs/screenshots/vm/waf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

BIN
docs/screenshots/vm/zkp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

View File

@ -1,6 +1,6 @@
# SecuBox Debian - UI Documentation
*CRT P31 phosphor theme documentation*
*This documentation shows the Debian version with CRT P31 phosphor theme.*
## About SecuBox Debian
@ -14,205 +14,72 @@ The Debian version features a retro CRT terminal aesthetic inspired by P31 phosp
```css
:root {
/* P31 Phosphor Green Palette */
--p31-peak: #33ff66; /* Bright phosphor green */
--p31-hot: #66ffaa; /* Hot phosphor glow */
--p31-mid: #22cc44; /* Standard text */
--p31-dim: #0f8822; /* Dim text */
--p31-ghost: #052210; /* Ghost/borders */
/* Decay (Warnings/Errors) */
--p31-decay: #ffb347; /* Amber decay */
--p31-decay-dim: #cc7722;
/* CRT Tube Colors */
--p31-decay: #ffb347; /* Decay/warnings (amber) */
--tube-black: #050803; /* CRT black */
--tube-deep: #080d05; /* Deep background */
--tube-bezel: #0d1208; /* Bezel color */
/* Legacy Mappings */
--bg-dark: var(--tube-black);
--bg-card: var(--tube-deep);
--border: var(--p31-ghost);
--text: var(--p31-mid);
--text-dim: var(--p31-dim);
--primary: var(--p31-peak);
--cyan: var(--p31-peak);
--green: var(--p31-peak);
--red: var(--p31-decay);
--yellow: var(--p31-decay);
/* Glow Effects */
--bloom-text: 0 0 2px var(--p31-peak), 0 0 6px var(--p31-peak), 0 0 14px rgba(51,255,102,0.5);
--bloom-soft: 0 0 6px var(--p31-peak), 0 0 14px rgba(51,255,102,0.5);
}
```
### Theme Features
- **Phosphor glow effects** - Text shadow with bloom effect
- **Scanline overlay** - Optional CRT scanline effect
- **Monospace fonts** - Courier Prime for terminal aesthetic
- **Amber warnings** - P31 decay color for alerts
- **Responsive design** - Collapsible sidebar on mobile
### Shared CSS Files
| File | Purpose |
|------|---------|
| `/shared/crt-system.css` | Full CRT styling, animations, effects |
| `/shared/sidebar.css` | Navigation sidebar styles |
| `/shared/sidebar.js` | Dynamic menu loading |
- **Phosphor glow effects** on text and borders
- **Scanline overlay** for authentic CRT look
- **Monospace fonts** (Courier Prime)
- **Amber warnings** for alerts and errors
- **Responsive design** with collapsible sidebar
## Architecture
### Backend Stack
```
┌─────────────────────────────────────────────┐
│ Nginx │
│ (Reverse Proxy + Static) │
├─────────────────────────────────────────────┤
│ /api/v1/<module>/ → Unix Socket │
│ /static/ → /var/www/ │
├─────────────────────────────────────────────┤
│ FastAPI + Uvicorn │
│ (Per-module Python service) │
├─────────────────────────────────────────────┤
│ secubox_core │
│ (Shared: auth, config, logger) │
├─────────────────────────────────────────────┤
│ System Services │
│ (CrowdSec, WireGuard, nftables, etc.) │
└─────────────────────────────────────────────┘
```
- **FastAPI** - Modern async Python web framework
- **Uvicorn** - ASGI server on Unix sockets
- **Nginx** - Reverse proxy and static files
- **JWT** - Authentication tokens
- **TOML** - Configuration format
### Frontend Stack
- **Vanilla JS** - No framework dependencies
- **CSS Variables** - Themeable design system
- **Fetch API** - REST client with JWT
- **WebSocket** - Real-time updates (SOC)
- **LocalStorage** - Token persistence
- **WebSocket** - Real-time updates (SOC module)
- **Shared Components** - sidebar.js, crt-system.css
### Authentication Flow
## Module Count
```
1. User → /portal/login.html
2. Submit credentials → POST /api/v1/portal/login
3. Receive JWT token → localStorage.setItem('sbx_token', token)
4. API calls include → Authorization: Bearer <token>
5. Token expires → Redirect to login
```
| Category | Count |
|----------|-------|
| Dashboard | 3 |
| Security | 5 |
| Network | 6 |
| DNS | 3 |
| VPN/Privacy | 6 |
| Monitoring | 5 |
| Access Control | 4 |
| Services | 3 |
| Email | 2 |
| Publishing | 3 |
| Apps | 3 |
| System | 2 |
| **Total** | **47** |
## Module Categories
## Module Screenshots
| Category | Modules | Description |
|----------|---------|-------------|
| Dashboard | 3 | Hub, SOC, Roadmap |
| Security | 5 | CrowdSec, WAF, Vortex Firewall, Hardening, MITM |
| Network | 6 | Netmodes, QoS, Traffic, HAProxy, CDN, VHost |
| DNS | 3 | DNS, Vortex DNS, Meshname |
| VPN | 3 | WireGuard, Mesh, P2P |
| Privacy | 3 | Tor, Exposure, ZKP |
| Monitoring | 5 | Netdata, DPI, Device Intel, Watchdog, MediaFlow |
| Access | 4 | Auth, NAC, Users, Portal |
| Services | 3 | C3Box, Gitea, Nextcloud |
| Email | 2 | Mail, Webmail |
| Publishing | 3 | Publish, Droplet, Metablogizer |
| Apps | 3 | Streamlit, StreamForge, Repo |
| System | 2 | System, Backup |
| **Total** | **47** | |
See the [Module Gallery](Module-Gallery) for screenshots of each module.
## API Documentation
### Common Patterns
Each module exposes a REST API at `/api/v1/<module>/`:
```bash
# Get module status
curl -sk -H "Authorization: Bearer $TOKEN" \
https://secubox/api/v1/<module>/status
# Example: Get SOC status
curl -H "Authorization: Bearer $TOKEN" https://secubox/api/v1/soc/status
# List items
curl -sk -H "Authorization: Bearer $TOKEN" \
https://secubox/api/v1/<module>/list
# Create item
curl -sk -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "value"}' \
https://secubox/api/v1/<module>/create
# Delete item
curl -sk -X DELETE -H "Authorization: Bearer $TOKEN" \
https://secubox/api/v1/<module>/delete/<id>
```
### Example: SOC API
```bash
# World clock
curl -sk -H "Authorization: Bearer $TOKEN" \
https://secubox/api/v1/soc/clock
# Threat map
curl -sk -H "Authorization: Bearer $TOKEN" \
https://secubox/api/v1/soc/map/threats
# Create ticket
curl -sk -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title": "Suspicious Activity", "severity": "high"}' \
https://secubox/api/v1/soc/tickets
# WebSocket for real-time
wscat -c wss://secubox/api/v1/soc/ws \
-H "Authorization: Bearer $TOKEN"
```
## Deployment
### Supported Platforms
| Board | SoC | Arch | Profile |
|-------|-----|------|---------|
| MOCHAbin | Armada 7040 | arm64 | secubox-full |
| ESPRESSObin v7 | Armada 3720 | arm64 | secubox-lite |
| ESPRESSObin Ultra | Armada 3720 | arm64 | secubox-lite |
| VirtualBox VM | x86_64 | amd64 | secubox-full |
### Installation
```bash
# Add SecuBox repository
curl -fsSL https://apt.secubox.in/install.sh | sudo bash
# Install full suite
sudo apt install secubox-full
# Or lite version
sudo apt install secubox-lite
```
## Screenshots
See [Module Gallery](screenshots/) for UI screenshots.
To capture screenshots:
```bash
# Install dependencies
pip install -r scripts/requirements-screenshot.txt
playwright install chromium
# Capture from VM
python3 scripts/screenshot-tool.py --host vm
# Capture from device
python3 scripts/screenshot-tool.py --host device
# Compare both
python3 scripts/screenshot-tool.py --compare --all
# Example: List CrowdSec decisions
curl -H "Authorization: Bearer $TOKEN" https://secubox/api/v1/crowdsec/decisions
```
---

View File

@ -1,6 +1,6 @@
# SecuBox OpenWRT - UI Documentation
*Original OpenWRT LuCI interface documentation*
*This documentation shows the original OpenWRT LuCI interface.*
## About SecuBox OpenWRT
@ -15,45 +15,13 @@ The OpenWRT version uses the standard LuCI theme with SecuBox customizations:
- Responsive sidebar navigation
- Module-based organization
## Original Modules (LuCI Apps)
## Module Screenshots
| Module | Package | Description |
|--------|---------|-------------|
| Dashboard | luci-app-secubox | Main control center |
| CrowdSec | luci-app-crowdsec-dashboard | Collaborative security |
| WireGuard | luci-app-wireguard-dashboard | VPN management |
| Auth Guardian | luci-app-auth-guardian | Authentication |
| Client Guardian | luci-app-client-guardian | NAC |
| Network Modes | luci-app-network-modes | Network configuration |
| DPI | luci-app-netifyd-dashboard | Deep packet inspection |
| QoS | luci-app-bandwidth-manager | Bandwidth management |
| VHost | luci-app-vhost-manager | Virtual hosts |
| CDN Cache | luci-app-cdn-cache | CDN management |
| Netdata | luci-app-netdata-dashboard | Monitoring |
| Media Flow | luci-app-media-flow | Media analytics |
| System Hub | luci-app-system-hub | System administration |
| Droplet | luci-app-droplet | File upload |
| Metablogizer | luci-app-metablogizer | Blog publishing |
| Streamlit | luci-app-streamlit | App hosting |
| StreamForge | luci-app-streamlit-forge | App templates |
## Architecture
### Backend
- **LuCI** - Lua web framework
- **ubus** - IPC message bus
- **RPCD** - Remote procedure call daemon
- **UCI** - Unified Configuration Interface
- **procd** - Process management
### Frontend
- **LuCI Views** - Lua templates
- **JavaScript** - RPCD client library
- **CSS** - LuCI theme system
See the [Module Gallery](Module-Gallery) for screenshots of each module.
## Migration to Debian
SecuBox is being migrated from OpenWRT to Debian. See [secubox-deb](https://github.com/CyberMind-FR/secubox-deb).
SecuBox is being migrated from OpenWRT to Debian. See [secubox-deb](https://github.com/CyberMind-FR/secubox-deb) for the Debian version.
### Key Differences
@ -64,16 +32,6 @@ SecuBox is being migrated from OpenWRT to Debian. See [secubox-deb](https://gith
| Theme | LuCI Dark | CRT P31 Phosphor |
| Config | UCI | TOML |
| Init System | procd | systemd |
| IPC | ubus/RPCD | Unix sockets |
| Package Manager | opkg | apt |
### Migration Benefits
1. **Larger ecosystem** - Access to full Debian package repository
2. **Modern Python** - FastAPI async framework
3. **Better security** - AppArmor, audit rules, CrowdSec
4. **Container support** - LXC for isolated services
5. **Easier development** - Standard Python tooling
---

View File

@ -27,6 +27,17 @@ app = FastAPI(title="secubox-portal", version="1.0.0", root_path="/api/v1/portal
router = APIRouter()
log = get_logger("portal")
@app.on_event("startup")
async def startup_init():
"""Initialize portal on startup - ensure users exist."""
# Ensure /etc/secubox directory exists
USERS_FILE.parent.mkdir(parents=True, exist_ok=True)
# Load/create users (this will create default if missing)
users = _load_users()
log.info("Portal started with %d users", len(users))
# Configuration - use same secret as secubox_core.auth
def _get_jwt_secret() -> str:
"""Get JWT secret - must match secubox_core.auth._secret()"""
@ -45,12 +56,16 @@ _sessions: dict = {}
def _load_users() -> dict:
"""Load users from config file."""
"""Load users from config file, creating default if missing."""
import json
if USERS_FILE.exists():
return json.loads(USERS_FILE.read_text())
try:
return json.loads(USERS_FILE.read_text())
except (json.JSONDecodeError, IOError) as e:
log.error("Failed to load users.json: %s", e)
# Default admin user (password: secubox)
return {
default_users = {
"admin": {
"password_hash": hashlib.sha256("secubox".encode()).hexdigest(),
"email": "admin@secubox.local",
@ -58,6 +73,10 @@ def _load_users() -> dict:
"created": datetime.now().isoformat()
}
}
# Persist default users immediately
_save_users(default_users)
log.info("Created default admin user (password: secubox)")
return default_users
def _save_users(users: dict):

View File

@ -1,7 +1,9 @@
[Unit]
Description=SecuBox Portal Authentication API
After=network.target secubox-core.service
Requires=secubox-core.service
Wants=secubox-core.service
StartLimitIntervalSec=300
StartLimitBurst=5
[Service]
UMask=0000
@ -9,11 +11,26 @@ Type=simple
User=secubox
Group=secubox
WorkingDirectory=/usr/lib/secubox/portal
# Ensure runtime directory exists with proper permissions
RuntimeDirectory=secubox
RuntimeDirectoryMode=0755
RuntimeDirectoryPreserve=yes
# Ensure config directory is writable
ExecStartPre=/bin/mkdir -p /etc/secubox
ExecStartPre=/bin/chown secubox:secubox /etc/secubox
ExecStart=/usr/bin/python3 -m uvicorn api.main:app \
--uds /run/secubox/portal.sock \
--log-level warning
Restart=on-failure
RestartSec=5
# Watchdog: restart always, with delay
Restart=always
RestartSec=3
WatchdogSec=30
# Security
PrivateTmp=true
NoNewPrivileges=true
ProtectSystem=strict