rmm2/frontend

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:

# 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:

# 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:

# 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:

# 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:

# 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:

# 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:

# 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:

# 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":"10.172.100.210"}'
# → {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:

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:

# 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:

# 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:

curl -sk -H "Authorization: Bearer <TOKEN>" \
  https://your-backend:8443/api/v1/hub/status
# → {"connected_agents":3,"active_tunnels":1}

Build & Deploy

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

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