# RMM Frontend React + Vite + TailwindCSS Web-Frontend fuer das OPNsense RMM System. ## Eckdaten | | | |---|---| | **Server** | your-backend (Debian 13, Nginx) | | **Tech** | React 18, Vite, TailwindCSS, Recharts, Zustand, lucide-react | | **Theme** | Dark mit Orange-Akzent, komplett deutsch | | **Auth** | JWT Login (8h Token) | | **Default-Login** | `admin` / `YOUR_PASSWORD` | | **Backend** | https://your-backend:8443 | ## Seiten | Seite | Route | Beschreibung | |-------|-------|-------------| | Login | `/login` | JWT Login | | Dashboard | `/` | Status-Kacheln, Agent-Liste, AgentPanel per Klick | | Firewalls | `/agents` | Suchbare Tabelle, AgentPanel mit Tabs, Hinzufuegen/Loeschen | | Tunnel | `/tunnels` | Globale Tunnel-Uebersicht ueber alle Firewalls | | Firmware | `/firmware` | Multi-Plattform Upload, Agent-Update-Trigger | | Kunden | `/customers` | CRUD Kundenverwaltung | | Einstellungen | `/settings` | Benutzerverwaltung, Passwoerter aendern | ## AgentPanel Tabs Das Side-Panel oeffnet sich per Klick auf eine Firewall (Dashboard oder Firewalls-Seite): | Tab | Inhalt | |-----|--------| | Uebersicht | Hardware, OS, Uptime, CPU/RAM, Lizenz (Business Edition) | | Interfaces | Netzwerk-Interfaces mit IP, MAC, Status, RX/TX | | Dienste | Laufende Services mit Status-Badge | | Tunnel | Quick-Buttons (WebGUI, SSH, Custom), aktive Tunnel | | VPN | WireGuard-Instanzen mit Transfer-Statistiken | | WireGuard | Peer-Management (CRUD), Client-Config mit Copy-Button | | Routen | Routing-Tabelle | | DHCP | Aktive Leases mit Suche (IP, MAC, Hostname) | | Zertifikate | Karten-Layout mit Ablaufdatum und Fortschrittsbalken | | Backups | Config-Backup erstellen, Liste, Download als XML | | Agent | Version, Agent-ID, Update-Button, Remote-Befehle | --- ## API Endpoints Alle Aufrufe gehen ueber den API Client (`src/api/client.js`). Base-URL wird ueber `VITE_API_URL` oder Nginx-Proxy konfiguriert. Auth: JWT Bearer Token im `Authorization` Header. ### Authentifizierung ``` POST /api/v1/auth/login Login (username, password) → JWT Token GET /api/v1/auth/me Eigene Benutzerdaten ``` **Beispiel:** ```bash # Login curl -sk -X POST https://your-backend:8443/api/v1/auth/login \ -d '{"username":"admin","password":"YOUR_PASSWORD"}' # → {"token":"eyJhbG...","user":{"id":1,"username":"admin"}} # Eigene Daten curl -sk -H "Authorization: Bearer " \ https://your-backend:8443/api/v1/auth/me ``` ### Agents (Firewalls) ``` GET /api/v1/agents Alle Agents auflisten GET /api/v1/agents/{id} Agent + Systemdaten abrufen DELETE /api/v1/agents/{id} Agent loeschen POST /api/v1/agents Firewall pre-registrieren GET /api/v1/agents/{id}/events Agent-Events (limit=N) PUT /api/v1/agents/{id}/customer Kunden zuordnen DELETE /api/v1/agents/{id}/customer Kundenzuordnung entfernen ``` **Beispiele:** ```bash # Alle Agents curl -sk -H "Authorization: Bearer " \ https://your-backend:8443/api/v1/agents # Agent-Details mit Systemdaten curl -sk -H "Authorization: Bearer " \ https://your-backend:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee # Firewall pre-registrieren curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/agents \ -d '{"name":"OPN.intra.kunde.de","customer_id":1}' # Agent loeschen curl -sk -H "Authorization: Bearer " -X DELETE \ https://your-backend:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887 # Events (letzte 50) curl -sk -H "Authorization: Bearer " \ "https://your-backend:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/events?limit=50" # Kunden zuordnen curl -sk -H "Authorization: Bearer " -X PUT \ https://your-backend:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/customer \ -d '{"customer_id":1}' ``` ### Kunden (Customers) ``` GET /api/v1/customers Alle Kunden POST /api/v1/customers Neuen Kunden anlegen PUT /api/v1/customers/{id} Kunden aktualisieren DELETE /api/v1/customers/{id} Kunden loeschen GET /api/v1/customers/{id}/agents Agents eines Kunden ``` **Beispiele:** ```bash # Kunden anlegen curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/customers \ -d '{"number":"K05001","name":"Beispiel GmbH"}' # Kunden aktualisieren curl -sk -H "Authorization: Bearer " -X PUT \ https://your-backend:8443/api/v1/customers/1 \ -d '{"number":"K05001","name":"Beispiel AG"}' # Agents eines Kunden curl -sk -H "Authorization: Bearer " \ https://your-backend:8443/api/v1/customers/1/agents ``` ### Benutzer (Users) ``` GET /api/v1/users Alle Benutzer POST /api/v1/users Neuen Benutzer anlegen PUT /api/v1/users/{id}/password Passwort aendern (min. 6 Zeichen) DELETE /api/v1/users/{id} Benutzer loeschen ``` **Beispiele:** ```bash # Benutzer anlegen curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/users \ -d '{"username":"operator","password":"Sicher!123"}' # Passwort aendern curl -sk -H "Authorization: Bearer " -X PUT \ https://your-backend:8443/api/v1/users/1/password \ -d '{"password":"NeuesPasswort!123"}' ``` ### Metriken (TimescaleDB) ``` GET /api/v1/agents/{id}/metrics Rohe Metriken GET /api/v1/agents/{id}/metrics/summary Aggregierte Metriken ``` Verfuegbare Metriken: `cpu_usage`, `memory_used_percent`, `memory_used_bytes`, `memory_total_bytes`, `uptime_seconds`, `disk_used_percent`, `disk_used_bytes`, `interface_rx_bytes`, `interface_tx_bytes`, `gateway_rtt_ms`, `gateway_loss_percent` **Beispiele:** ```bash # CPU letzte 24h curl -sk -H "Authorization: Bearer " \ "https://your-backend:8443/api/v1/agents/6beb8dfd.../metrics?metric=cpu_usage" # RAM mit Zeitraum curl -sk -H "Authorization: Bearer " \ "https://your-backend:8443/api/v1/agents/6beb8dfd.../metrics?metric=memory_used_percent&from=2026-03-01T00:00:00Z&to=2026-03-01T23:59:59Z" # 5-Minuten-Durchschnitte curl -sk -H "Authorization: Bearer " \ "https://your-backend:8443/api/v1/agents/6beb8dfd.../metrics/summary?metric=cpu_usage&bucket=5+minutes" ``` ### Config-Backups ``` POST /api/v1/agents/{id}/backup Backup jetzt ausloesen GET /api/v1/agents/{id}/backups Alle Backups auflisten GET /api/v1/agents/{id}/backups/{id} Backup herunterladen (?format=xml) GET /api/v1/agents/{id}/backups/latest Neuestes Backup DELETE /api/v1/agents/{id}/backups/{id} Backup loeschen GET /api/v1/agents/{id}/backups/diff Diff (?a=ID&b=ID) ``` **Beispiele:** ```bash # Backup ausloesen curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/agents/6beb8dfd.../backup # Backups auflisten curl -sk -H "Authorization: Bearer " \ https://your-backend:8443/api/v1/agents/6beb8dfd.../backups # Als XML herunterladen curl -sk -H "Authorization: Bearer " \ "https://your-backend:8443/api/v1/agents/6beb8dfd.../backups/latest?format=xml" \ -o config-backup.xml # Diff zwischen zwei Backups curl -sk -H "Authorization: Bearer " \ "https://your-backend:8443/api/v1/agents/6beb8dfd.../backups/diff?a=1&b=3" ``` ### Tunnel ``` POST /api/v1/agents/{id}/tunnel Tunnel oeffnen GET /api/v1/agents/{id}/tunnels Aktive Tunnel auflisten DELETE /api/v1/agents/{id}/tunnel/{tid} Tunnel schliessen ``` **Beispiele:** ```bash # SSH-Tunnel curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/agents/e92e87a6.../tunnel \ -d '{"target_host":"127.0.0.1","target_port":22}' # → {"tunnel_id":"abc123","proxy_port":10000,...} # Dann: ssh -p 10000 root@your-backend # WebGUI-Tunnel (OPNsense Port 4444) curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/agents/e92e87a6.../tunnel \ -d '{"target_host":"127.0.0.1","target_port":4444}' # Im Browser: https://your-backend:10001/ # PVE WebGUI-Tunnel (Proxmox Port 8006) curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/agents/3f0a83a2.../tunnel \ -d '{"target_host":"127.0.0.1","target_port":8006}' # Aktive Tunnel curl -sk -H "Authorization: Bearer " \ https://your-backend:8443/api/v1/agents/e92e87a6.../tunnels # Tunnel schliessen curl -sk -H "Authorization: Bearer " -X DELETE \ https://your-backend:8443/api/v1/agents/e92e87a6.../tunnel/abc123 ``` ### WireGuard Peer-Management ``` GET /api/v1/agents/{id}/wireguard/peers Alle Peers auflisten POST /api/v1/agents/{id}/wireguard/peers Neuen Peer anlegen DELETE /api/v1/agents/{id}/wireguard/peers/{uuid} Peer loeschen ``` **Beispiele:** ```bash # Peer anlegen (Auto: Keypair, naechste freie IP, Endpoint) curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/agents/6beb8dfd.../wireguard/peers \ -d '{"name":"VPN_MUELLER","allowed_ips":"0.0.0.0/0","dns":""}' # → {peer_config: "[Interface]\nPrivateKey=...\n[Peer]\n...", ...} # Alle Peers curl -sk -H "Authorization: Bearer " \ https://your-backend:8443/api/v1/agents/6beb8dfd.../wireguard/peers # Peer loeschen curl -sk -H "Authorization: Bearer " -X DELETE \ https://your-backend:8443/api/v1/agents/6beb8dfd.../wireguard/peers/89c10e2d-148e-11f1-a7af-7c5a1c6c7b73 ``` ### Remote-Befehle (Exec) ``` POST /api/v1/agents/{id}/exec Befehl ausfuehren ``` **Beispiel:** ```bash curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/agents/e92e87a6.../exec \ -d '{"command":"uptime","timeout":30}' # → {"data":{"output":"10:30AM up 45 days, ..."}, "status":"ok"} ``` ### Updates ``` POST /api/v1/agents/{id}/update-check Verfuegbare Updates pruefen POST /api/v1/agents/{id}/update Normales Update (Core + Packages) POST /api/v1/agents/{id}/major-update Major-Upgrade (2-Phasen) POST /api/v1/agents/{id}/reboot Reboot ``` **Beispiele:** ```bash # Update-Check curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/agents/e92e87a6.../update-check # Update mit Reboot curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/agents/e92e87a6.../update \ -d '{"reboot":true}' # Major-Update Phase 1 curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/agents/e92e87a6.../major-update \ -d '{"version":"26.1","reboot":true}' ``` ### Firmware / Agent-Update ``` GET /api/v1/firmware Alle Firmware-Versionen POST /api/v1/firmware/upload?version=X&platform=Y Binary hochladen GET /api/v1/firmware/download?platform=Y Binary herunterladen (Updater) POST /api/v1/agents/{id}/request-update Update-Flag setzen DELETE /api/v1/agents/{id}/request-update Update-Flag zuruecksetzen POST /api/v1/agents/request-update-all Alle Agents updaten ``` **Beispiele:** ```bash # Firmware-Info curl -sk -H "Authorization: Bearer " \ https://your-backend:8443/api/v1/firmware # Firmware hochladen (FreeBSD) curl -sk -H "Authorization: Bearer " -X POST \ "https://your-backend:8443/api/v1/firmware/upload?version=1.0.3&platform=freebsd" \ --data-binary @build/rmm-agent # Firmware hochladen (Linux) curl -sk -H "Authorization: Bearer " -X POST \ "https://your-backend:8443/api/v1/firmware/upload?version=1.0.1&platform=linux" \ --data-binary @build/rmm-agent-linux # Update fuer einzelnen Agent anfordern curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/agents/e92e87a6.../request-update # Update fuer alle Agents curl -sk -H "Authorization: Bearer " -X POST \ https://your-backend:8443/api/v1/agents/request-update-all ``` ### Hub-Status ``` GET /api/v1/hub/status WebSocket Hub Status ``` **Beispiel:** ```bash curl -sk -H "Authorization: Bearer " \ https://your-backend:8443/api/v1/hub/status # → {"connected_agents":3,"active_tunnels":1} ``` --- ## Build & Deploy ```bash cd frontend npm install npm run build # ~330 KB JS, ~32 KB CSS # Deploy ssh root@your-backend 'rm -rf /var/www/html/assets/*' # Alte Hashes loeschen! scp -r dist/* root@your-backend:/var/www/html/ ``` **Wichtig:** Vor Deploy immer `assets/` loeschen — Vite generiert Hash-basierte Dateinamen, alte Dateien bleiben sonst auf dem Server. ## Entwicklung ```bash cd frontend npm run dev # Startet Vite Dev-Server mit Proxy zu Backend ``` Vite Proxy-Config (`vite.config.js`): `/api/` wird auf `https://your-backend:8443` weitergeleitet. ## Dateistruktur ``` frontend/ ├── src/ │ ├── App.jsx # Router + ProtectedRoute │ ├── main.jsx # Entry Point │ ├── index.css # TailwindCSS + Custom Styles │ ├── api/client.js # API Client (alle Endpoints) │ ├── stores/auth.js # Zustand Auth Store (JWT Token) │ ├── layouts/AppLayout.jsx # Sidebar Navigation + Outlet │ ├── components/ │ │ ├── AgentPanel.jsx # Side Panel mit 11 Tabs │ │ └── StatusBadge.jsx # Online/Offline/Stale Badge │ └── pages/ │ ├── Dashboard.jsx # Status-Kacheln + Agent-Liste │ ├── Agents.jsx # Firewall-Tabelle + Pre-Registration │ ├── AgentDetail.jsx # Detail-Ansicht (full page, legacy) │ ├── Tunnels.jsx # Globale Tunnel-Uebersicht │ ├── Firmware.jsx # Multi-Plattform Firmware + Updates │ ├── Customers.jsx # Kunden CRUD │ ├── SettingsPage.jsx # User-Management + Passwort │ └── Login.jsx # JWT Login ├── vite.config.js # Vite Config mit API Proxy ├── tailwind.config.js └── package.json ```