rmm2/frontend/README.md

421 lines
14 KiB
Markdown

# 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 <TOKEN>" \
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 <TOKEN>" \
https://your-backend:8443/api/v1/agents
# Agent-Details mit Systemdaten
curl -sk -H "Authorization: Bearer <TOKEN>" \
https://your-backend:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee
# Firewall pre-registrieren
curl -sk -H "Authorization: Bearer <TOKEN>" -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 <TOKEN>" -X DELETE \
https://your-backend:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887
# Events (letzte 50)
curl -sk -H "Authorization: Bearer <TOKEN>" \
"https://your-backend:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/events?limit=50"
# Kunden zuordnen
curl -sk -H "Authorization: Bearer <TOKEN>" -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 <TOKEN>" -X POST \
https://your-backend:8443/api/v1/customers \
-d '{"number":"K05001","name":"Beispiel GmbH"}'
# Kunden aktualisieren
curl -sk -H "Authorization: Bearer <TOKEN>" -X PUT \
https://your-backend:8443/api/v1/customers/1 \
-d '{"number":"K05001","name":"Beispiel AG"}'
# Agents eines Kunden
curl -sk -H "Authorization: Bearer <TOKEN>" \
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 <TOKEN>" -X POST \
https://your-backend:8443/api/v1/users \
-d '{"username":"operator","password":"Sicher!123"}'
# Passwort aendern
curl -sk -H "Authorization: Bearer <TOKEN>" -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 <TOKEN>" \
"https://your-backend:8443/api/v1/agents/6beb8dfd.../metrics?metric=cpu_usage"
# RAM mit Zeitraum
curl -sk -H "Authorization: Bearer <TOKEN>" \
"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 <TOKEN>" \
"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 <TOKEN>" -X POST \
https://your-backend:8443/api/v1/agents/6beb8dfd.../backup
# Backups auflisten
curl -sk -H "Authorization: Bearer <TOKEN>" \
https://your-backend:8443/api/v1/agents/6beb8dfd.../backups
# Als XML herunterladen
curl -sk -H "Authorization: Bearer <TOKEN>" \
"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 <TOKEN>" \
"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 <TOKEN>" -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 <TOKEN>" -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 <TOKEN>" -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 <TOKEN>" \
https://your-backend:8443/api/v1/agents/e92e87a6.../tunnels
# Tunnel schliessen
curl -sk -H "Authorization: Bearer <TOKEN>" -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 <TOKEN>" -X POST \
https://your-backend:8443/api/v1/agents/6beb8dfd.../wireguard/peers \
-d '{"name":"VPN_MUELLER","allowed_ips":"0.0.0.0/0","dns":"<DNS-SERVER>"}'
# → {peer_config: "[Interface]\nPrivateKey=...\n[Peer]\n...", ...}
# Alle Peers
curl -sk -H "Authorization: Bearer <TOKEN>" \
https://your-backend:8443/api/v1/agents/6beb8dfd.../wireguard/peers
# Peer loeschen
curl -sk -H "Authorization: Bearer <TOKEN>" -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 <TOKEN>" -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 <TOKEN>" -X POST \
https://your-backend:8443/api/v1/agents/e92e87a6.../update-check
# Update mit Reboot
curl -sk -H "Authorization: Bearer <TOKEN>" -X POST \
https://your-backend:8443/api/v1/agents/e92e87a6.../update \
-d '{"reboot":true}'
# Major-Update Phase 1
curl -sk -H "Authorization: Bearer <TOKEN>" -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 <TOKEN>" \
https://your-backend:8443/api/v1/firmware
# Firmware hochladen (FreeBSD)
curl -sk -H "Authorization: Bearer <TOKEN>" -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 <TOKEN>" -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 <TOKEN>" -X POST \
https://your-backend:8443/api/v1/agents/e92e87a6.../request-update
# Update fuer alle Agents
curl -sk -H "Authorization: Bearer <TOKEN>" -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 <TOKEN>" \
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
```