Docs aufgesplittet: README + docs/BACKEND + AGENT + FRONTEND + API + FIRMWARE
This commit is contained in:
parent
fb5930051e
commit
77ec200b42
124
docs/AGENT.md
Normal file
124
docs/AGENT.md
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
# Agent — Installation & Konfiguration
|
||||||
|
|
||||||
|
Der RMM-Agent laeuft auf OPNsense (FreeBSD) und wird als OPNsense-Plugin mit WebGUI-Konfiguration installiert.
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
- **Collectors**: Hardware, CPU, Memory, Disk, Network, Services, WireGuard, DHCP, Routing, Gateways, Zertifikate, Plugins, Updates, Cron
|
||||||
|
- **WebSocket Client**: Persistente Verbindung zum Backend, automatisches Reconnect mit Backoff
|
||||||
|
- **Command Handler**: Remote-Befehlsausfuehrung, Tunnel-Connect/Disconnect
|
||||||
|
- **Tunnel Manager**: Session-basierte TCP-Verbindungen zu lokalen Diensten
|
||||||
|
|
||||||
|
## 1. Agent bauen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make agent # Erzeugt build/rmm-agent (freebsd/amd64)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Plugin installieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Binary + Installer auf die Firewall kopieren
|
||||||
|
scp build/rmm-agent root@OPNSENSE:/tmp/
|
||||||
|
scp opnsense-plugin/install.sh root@OPNSENSE:/tmp/
|
||||||
|
|
||||||
|
# Installer ausfuehren
|
||||||
|
ssh root@OPNSENSE '/bin/sh /tmp/install.sh'
|
||||||
|
```
|
||||||
|
|
||||||
|
Der Installer richtet alles ein:
|
||||||
|
- Binary nach `/usr/local/rmm/rmm-agent`
|
||||||
|
- rc.d Service (`/usr/local/etc/rc.d/rmm_agent`)
|
||||||
|
- OPNsense MVC Plugin (Model, Controller, View)
|
||||||
|
- configd Actions (start/stop/restart/status/reconfigure)
|
||||||
|
- Plugin-Hook fuer Service-Integration
|
||||||
|
- Setup-Script das Config aus dem Model generiert
|
||||||
|
|
||||||
|
## 3. WebGUI konfigurieren
|
||||||
|
|
||||||
|
1. OPNsense WebGUI oeffnen
|
||||||
|
2. **Services > RMM Agent**
|
||||||
|
3. Felder ausfuellen:
|
||||||
|
- **Aktiviert**: Ankreuzen
|
||||||
|
- **Backend URL**: `https://BACKEND_IP:8443`
|
||||||
|
- **API Key**: Backend API-Key eintragen
|
||||||
|
- **Agent Name**: Optional (Standard: Hostname)
|
||||||
|
- **Heartbeat Intervall**: 60 (Sekunden)
|
||||||
|
- **Self-Signed Zertifikate**: Ankreuzen bei self-signed Backend-Certs
|
||||||
|
4. **Speichern & Anwenden** klicken
|
||||||
|
|
||||||
|
Der Agent startet automatisch und meldet sich am Backend an.
|
||||||
|
|
||||||
|
### OPNsense Plugin WebGUI Fix (v1.0.3)
|
||||||
|
|
||||||
|
Der `SettingsController` wurde gefixt:
|
||||||
|
- **Config-Parsing**: Korrektes Parsen von `rmmagent[general][KEY]` Formular-Feldern (OPNsense MVC-Konvention)
|
||||||
|
- **Initialer config.xml Eintrag**: Beim ersten Speichern wird automatisch der `<rmmagent>` Knoten in der `config.xml` angelegt
|
||||||
|
|
||||||
|
## 4. Verifizieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Status in der WebGUI: Badge zeigt "Running"
|
||||||
|
|
||||||
|
# Oder per SSH:
|
||||||
|
ssh root@OPNSENSE 'service rmm_agent status'
|
||||||
|
|
||||||
|
# Auf dem Backend: Agent sollte erscheinen
|
||||||
|
curl -sk -H "X-API-Key: DEIN_API_KEY" https://BACKEND_IP:8443/api/v1/agents
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pre-Registration
|
||||||
|
|
||||||
|
Firewalls koennen vorab im System registriert werden, bevor der Agent installiert wird:
|
||||||
|
|
||||||
|
1. Im Frontend auf "Firewall hinzufuegen" klicken (oder `POST /api/v1/agents`)
|
||||||
|
2. Name und optionalen Kunden angeben
|
||||||
|
3. Agent wird mit `hostname="(ausstehend)"` angelegt
|
||||||
|
4. Bei der eigentlichen Agent-Registration wird automatisch nach Name gematcht (`GetAgentByName`)
|
||||||
|
5. Der pre-registrierte Eintrag wird mit den echten Agent-Daten aktualisiert
|
||||||
|
|
||||||
|
## Agent-Update (via Updater — empfohlen)
|
||||||
|
|
||||||
|
Der **rmm-updater** ist ein separater Daemon, der auf jeder Firewall neben dem Agent laeuft.
|
||||||
|
Er prueft alle 60 Sekunden ob ein Update ansteht und fuehrt es automatisch durch.
|
||||||
|
|
||||||
|
**Flow:**
|
||||||
|
1. Neue Agent-Binary im Frontend hochladen (Firmware-Seite)
|
||||||
|
2. Update-Button bei einzelnem Agent oder "Alle updaten" klicken
|
||||||
|
3. Updater erkennt den Flag, laedt die Binary vom Backend, stoppt Agent, ersetzt Binary, startet Agent
|
||||||
|
4. Flag wird automatisch zurueckgesetzt
|
||||||
|
|
||||||
|
**Technische Details:**
|
||||||
|
- Separates Go-Binary (`rmm-updater`), laeuft als `rmm_updater` rc.d Service
|
||||||
|
- Liest die gleiche `config.yaml` wie der Agent (Backend-URL, API-Key)
|
||||||
|
- Download ueber `GET /api/v1/firmware/download?platform=freebsd`
|
||||||
|
- SHA256-Verifizierung vor Ersetzung
|
||||||
|
- Automatisches Rollback bei fehlgeschlagenem Agent-Start
|
||||||
|
- Backup der alten Binary als `.bak` waehrend des Updates
|
||||||
|
- Logs: `/var/log/rmm-updater.log`
|
||||||
|
|
||||||
|
**Manuelles Update (Fallback):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make agent
|
||||||
|
scp build/rmm-agent root@OPNSENSE:/tmp/
|
||||||
|
ssh root@OPNSENSE '/bin/sh -c "service rmm_agent stop; cp /tmp/rmm-agent /usr/local/rmm/rmm-agent; chmod +x /usr/local/rmm/rmm-agent; service rmm_agent start"'
|
||||||
|
```
|
||||||
|
|
||||||
|
Oder Plugin komplett neu installieren (`install.sh` ist idempotent — installiert Agent + Updater).
|
||||||
|
|
||||||
|
## Service-Filter (v1.0.3)
|
||||||
|
|
||||||
|
Boot- und Init-Scripts werden nicht mehr in der Dienste-Liste angezeigt:
|
||||||
|
- **Gefiltert**: `bgfsck`, `cleanvar`, `dmesg`, `hostid`, `ldconfig`, `motd`, `newsyslog`, `ntpd`, `resolv`, `syslogd`, `var` und andere System-Boot-Scripts
|
||||||
|
- **Angezeigt**: Nur echte OPNsense-Dienste (OpenVPN, Unbound, DHCPd, WireGuard, etc.)
|
||||||
|
- `pluginctl` wird mit vollem Pfad `/usr/local/sbin/pluginctl` aufgerufen (FreeBSD-Kompatibilitaet)
|
||||||
|
|
||||||
|
## Hinweise
|
||||||
|
|
||||||
|
- **Agent-ID** wird persistent in `/usr/local/rmm/agent_id` gespeichert — ueberlebt Neuinstallationen
|
||||||
|
- **Config** wird bei "Speichern & Anwenden" aus dem OPNsense-Model nach `/usr/local/rmm/config.yaml` generiert
|
||||||
|
- **Logs**: `/var/log/rmm-agent.log`
|
||||||
|
- **PID-File**: `/var/run/rmm_agent.pid`
|
||||||
|
- Agent braucht **root** auf OPNsense (fuer Hardware-/Service-Daten)
|
||||||
|
- OPNsense WebGUI typischerweise auf **Port 4444** (nicht 443)
|
||||||
351
docs/API.md
Normal file
351
docs/API.md
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
# API-Referenz
|
||||||
|
|
||||||
|
Vollstaendige REST API Dokumentation mit allen Endpoints und Beispielen.
|
||||||
|
|
||||||
|
**Base-URL**: `https://192.168.85.13:8443/api/v1`
|
||||||
|
|
||||||
|
## Authentifizierung
|
||||||
|
|
||||||
|
Zwei Auth-Methoden (CombinedAuth Middleware):
|
||||||
|
- **API-Key** (Header `X-API-Key`): Fuer Agents und automatisierte Zugriffe
|
||||||
|
- **JWT Bearer Token** (Header `Authorization: Bearer <token>`): Fuer Frontend-Benutzer
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| POST | `/auth/login` | Login (username + password → JWT Token, 8h Ablauf) |
|
||||||
|
| GET | `/auth/me` | Eigene Benutzerdaten |
|
||||||
|
|
||||||
|
Default-Admin: `admin` / `Start!123` (min. 6 Zeichen).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Agent-Management
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| POST | `/agent/register` | Agent registrieren (mit optionaler `agent_id`) |
|
||||||
|
| POST | `/agent/heartbeat` | Systemdaten senden |
|
||||||
|
| POST | `/agents` | Firewall pre-registrieren (`{name, customer_id?}`) |
|
||||||
|
| GET | `/agents` | Alle Agents auflisten |
|
||||||
|
| GET | `/agents/{id}` | Agent + Systemdaten abrufen |
|
||||||
|
| GET | `/agents/{id}/system` | Nur Systemdaten |
|
||||||
|
| DELETE | `/agents/{id}` | Agent loeschen |
|
||||||
|
|
||||||
|
### Agent-Status
|
||||||
|
|
||||||
|
Status wird automatisch aus `last_heartbeat` berechnet:
|
||||||
|
|
||||||
|
| Status | Bedingung |
|
||||||
|
|--------|-----------|
|
||||||
|
| `online` | Heartbeat < 2 Minuten |
|
||||||
|
| `stale` | Heartbeat < 5 Minuten |
|
||||||
|
| `offline` | Heartbeat > 5 Minuten |
|
||||||
|
| `unknown` | Kein Heartbeat vorhanden |
|
||||||
|
|
||||||
|
### Pre-Registration
|
||||||
|
|
||||||
|
`POST /agents` mit `{"name": "FW-NAME", "customer_id": 1}` — legt Agent mit `hostname="(ausstehend)"` an.
|
||||||
|
Bei Agent-Registration wird automatisch nach Name gematcht (`GetAgentByName`).
|
||||||
|
|
||||||
|
### Beispiele
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Alle Agents auflisten
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents
|
||||||
|
|
||||||
|
# Einzelner Agent mit Systemdaten
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887
|
||||||
|
|
||||||
|
# Nur Systemdaten
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887/system
|
||||||
|
|
||||||
|
# Agent loeschen
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X DELETE \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887
|
||||||
|
|
||||||
|
# Hub-Status (verbundene Agents, aktive Tunnel)
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
https://192.168.85.13:8443/api/v1/hub/status
|
||||||
|
|
||||||
|
# Remote-Command ausfuehren
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X POST \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887/exec \
|
||||||
|
-d '{"command":"uptime","timeout":30}'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Agent-Events
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| GET | `/agents/events` | Alle Events (`?limit=N&type=X`) |
|
||||||
|
| GET | `/agents/{id}/events` | Events eines Agents (`?limit=N&type=X`) |
|
||||||
|
|
||||||
|
Event-Typen: `online`, `offline`, `stale`, `connected`, `disconnected`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Alle Events (letzte 10)
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
"https://192.168.85.13:8443/api/v1/agents/events?limit=10"
|
||||||
|
|
||||||
|
# Nur Offline-Events eines Agents
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
"https://192.168.85.13:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/events?type=offline"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Kunden (Customers)
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| GET | `/customers` | Alle Kunden auflisten |
|
||||||
|
| POST | `/customers` | Neuen Kunden anlegen (`{number, name}`) |
|
||||||
|
| GET | `/customers/{id}` | Einzelnen Kunden abrufen |
|
||||||
|
| PUT | `/customers/{id}` | Kunden aktualisieren |
|
||||||
|
| DELETE | `/customers/{id}` | Kunden loeschen |
|
||||||
|
| GET | `/customers/{id}/agents` | Agents eines Kunden |
|
||||||
|
| PUT | `/agents/{id}/customer` | Agent einem Kunden zuordnen |
|
||||||
|
| DELETE | `/agents/{id}/customer` | Kundenzuordnung entfernen |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Benutzer (Users)
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| GET | `/users` | Alle Benutzer auflisten |
|
||||||
|
| POST | `/users` | Neuen Benutzer anlegen |
|
||||||
|
| PUT | `/users/{id}/password` | Passwort aendern (min. 6 Zeichen) |
|
||||||
|
| DELETE | `/users/{id}` | Benutzer loeschen |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Metriken (TimescaleDB)
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| GET | `/agents/{id}/metrics` | Rohe Metriken (`?metric=X&from=&to=&limit=N`) |
|
||||||
|
| GET | `/agents/{id}/metrics/summary` | Aggregierte Metriken (`?metric=X&bucket=5+minutes&from=&to=`) |
|
||||||
|
|
||||||
|
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`
|
||||||
|
|
||||||
|
Retention: 90 Tage (Raw), Compression nach 7 Tagen.
|
||||||
|
|
||||||
|
### Beispiele
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# CPU-Auslastung der letzten 24h
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
"https://192.168.85.13:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/metrics?metric=cpu_usage"
|
||||||
|
|
||||||
|
# RAM-Nutzung mit Zeitraum
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
"https://192.168.85.13:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/metrics?metric=memory_used_percent&from=2026-02-28T00:00:00Z&to=2026-02-28T23:59:59Z"
|
||||||
|
|
||||||
|
# 5-Minuten-Durchschnitte der CPU
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
"https://192.168.85.13:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/metrics/summary?metric=cpu_usage&bucket=5+minutes"
|
||||||
|
|
||||||
|
# Stuendliche RAM-Zusammenfassung
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
"https://192.168.85.13:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/metrics/summary?metric=memory_used_percent&bucket=1+hour"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Config-Backup
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| POST | `/agents/{id}/backup` | Backup jetzt ausloesen (via WebSocket) |
|
||||||
|
| GET | `/agents/{id}/backups` | Alle Backups auflisten (`?limit=N`) |
|
||||||
|
| GET | `/agents/{id}/backups/{id\|latest}` | Backup herunterladen (`?format=xml` fuer Raw-XML) |
|
||||||
|
| DELETE | `/agents/{id}/backups/{id}` | Einzelnes Backup loeschen |
|
||||||
|
| GET | `/agents/{id}/backups/diff?a={id}&b={id}` | Zeilenweises Diff zwischen zwei Backups |
|
||||||
|
|
||||||
|
Backups werden dedupliziert: gleicher SHA256-Hash = kein neuer Eintrag.
|
||||||
|
|
||||||
|
### Beispiele
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Backup ausloesen
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X POST \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/backup
|
||||||
|
|
||||||
|
# Alle Backups auflisten
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/backups
|
||||||
|
|
||||||
|
# Neuestes Backup als XML herunterladen
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
"https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887/backups/latest?format=xml" \
|
||||||
|
-o config-backup.xml
|
||||||
|
|
||||||
|
# Diff zwischen Backup 1 und 3
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
"https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887/backups/diff?a=1&b=3"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tunnel-Management
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| POST | `/agents/{id}/tunnel` | Tunnel oeffnen |
|
||||||
|
| GET | `/agents/{id}/tunnels` | Aktive Tunnel auflisten |
|
||||||
|
| DELETE | `/agents/{id}/tunnel/{tid}` | Tunnel schliessen |
|
||||||
|
| POST | `/agents/{id}/exec` | Remote-Command ausfuehren |
|
||||||
|
|
||||||
|
### Beispiele
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# SSH-Tunnel zur OPNsense
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X POST \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887/tunnel \
|
||||||
|
-d '{"target_host":"127.0.0.1","target_port":22}'
|
||||||
|
# Response: {"tunnel_id":"xxx","proxy_port":10000,...}
|
||||||
|
# Verbinden: ssh -p 10000 root@192.168.85.13
|
||||||
|
|
||||||
|
# WebGUI-Tunnel (OPNsense auf Port 4444)
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X POST \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887/tunnel \
|
||||||
|
-d '{"target_host":"127.0.0.1","target_port":4444}'
|
||||||
|
# Im Browser: https://192.168.85.13:10001/
|
||||||
|
|
||||||
|
# Aktive Tunnel auflisten
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887/tunnels
|
||||||
|
|
||||||
|
# Tunnel schliessen
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X DELETE \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887/tunnel/TUNNEL_ID
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Updates & Reboot
|
||||||
|
|
||||||
|
Siehe [FIRMWARE.md](FIRMWARE.md) fuer den vollstaendigen Update-Prozess.
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| POST | `/agents/{id}/update-check` | Verfuegbare Updates pruefen |
|
||||||
|
| POST | `/agents/{id}/update` | Normales Update (Core + Packages) |
|
||||||
|
| POST | `/agents/{id}/major-update` | Major-Upgrade auf Zielversion |
|
||||||
|
| POST | `/agents/{id}/reboot` | Reboot ausfuehren |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Firmware / Agent-Update
|
||||||
|
|
||||||
|
Siehe [FIRMWARE.md](FIRMWARE.md) fuer Details.
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| GET | `/firmware` | Alle Firmware-Versionen |
|
||||||
|
| POST | `/firmware/upload?version=X&platform=Y` | Binary hochladen |
|
||||||
|
| GET | `/firmware/download?platform=Y` | Binary herunterladen |
|
||||||
|
| POST | `/agents/{id}/request-update` | Update-Flag setzen |
|
||||||
|
| DELETE | `/agents/{id}/request-update` | Update-Flag zuruecksetzen |
|
||||||
|
| POST | `/agents/request-update-all` | Alle Agents updaten |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## WireGuard-Peer Management
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| POST | `/agents/{id}/wireguard/peers` | Neuen Peer anlegen |
|
||||||
|
| GET | `/agents/{id}/wireguard/peers` | Alle Peers auflisten (`?server_name=X`) |
|
||||||
|
| DELETE | `/agents/{id}/wireguard/peers/{uuid}` | Peer loeschen |
|
||||||
|
|
||||||
|
### Peer anlegen — Parameter
|
||||||
|
|
||||||
|
| Parameter | Pflicht | Default | Beschreibung |
|
||||||
|
|-----------|---------|---------|-------------|
|
||||||
|
| `name` | Ja | — | Peer-Name (z.B. "VPN_MUELLER") |
|
||||||
|
| `allowed_ips` | Nein | `0.0.0.0/0` | AllowedIPs fuer Client-Config |
|
||||||
|
| `dns` | Nein | — | DNS-Server fuer Client-Config |
|
||||||
|
| `server_name` | Nein | `ALWAYSON_VPN` | Name der WG-Server-Instanz |
|
||||||
|
| `endpoint` | Nein | WAN-IP:Port | Oeffentlicher Endpoint (Auto-Detect) |
|
||||||
|
|
||||||
|
### Ablauf beim Anlegen
|
||||||
|
|
||||||
|
1. Keypair wird auf der Firewall generiert (`wg genkey`/`wg pubkey`)
|
||||||
|
2. Naechste freie IP aus dem Tunnel-Subnetz wird automatisch vergeben
|
||||||
|
3. Peer wird in `config.xml` eingetragen und dem Server zugewiesen
|
||||||
|
4. `configctl wireguard configure` laedt die Aenderung
|
||||||
|
5. Response enthaelt die komplette Client-Config (ready for import)
|
||||||
|
|
||||||
|
### Beispiele
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Peer anlegen
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X POST \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/wireguard/peers \
|
||||||
|
-d '{"name":"VPN_MUELLER","allowed_ips":"0.0.0.0/0","dns":"10.172.100.210"}'
|
||||||
|
|
||||||
|
# Peer mit eigenem Endpoint
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X POST \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/wireguard/peers \
|
||||||
|
-d '{"name":"VPN_EXTERN","allowed_ips":"0.0.0.0/0","endpoint":"vpn.kunde.de:8080"}'
|
||||||
|
|
||||||
|
# Alle Peers auflisten
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/wireguard/peers
|
||||||
|
|
||||||
|
# Peer loeschen
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X DELETE \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/6beb8dfd38ecf03eab6c0f21b4ac7bee/wireguard/peers/89c10e2d-148e-11f1-a7af-7c5a1c6c7b73
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## WebSocket
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| GET | `/agent/ws?agent_id=X&api_key=X` | WebSocket-Verbindung (Agent) |
|
||||||
|
| GET | `/hub/status` | Hub-Status (connected agents, aktive Tunnel) |
|
||||||
|
|
||||||
|
### WebSocket Commands (Backend → Agent)
|
||||||
|
|
||||||
|
```json
|
||||||
|
// Remote-Befehl ausfuehren
|
||||||
|
{"type":"command","id":"cmd1","command":"exec","params":{"command":"uptime","timeout":30}}
|
||||||
|
|
||||||
|
// Update-Check
|
||||||
|
{"type":"command","id":"cmd2","command":"update_check"}
|
||||||
|
|
||||||
|
// Normales Update
|
||||||
|
{"type":"command","id":"cmd3","command":"update","params":{"reboot":false}}
|
||||||
|
|
||||||
|
// Major-Update
|
||||||
|
{"type":"command","id":"cmd4","command":"major_update","params":{"version":"26.1","reboot":true}}
|
||||||
|
|
||||||
|
// Reboot
|
||||||
|
{"type":"command","id":"cmd5","command":"reboot","params":{"delay":5}}
|
||||||
|
|
||||||
|
// Config-Backup
|
||||||
|
{"type":"command","id":"cmd8","command":"backup","params":{}}
|
||||||
|
|
||||||
|
// Tunnel-Session oeffnen
|
||||||
|
{"type":"command","id":"cmd6","command":"tunnel_connect","params":{"session_id":"xxx","tunnel_id":"xxx","target_host":"127.0.0.1","target_port":22}}
|
||||||
|
|
||||||
|
// Tunnel-Session schliessen
|
||||||
|
{"type":"command","id":"cmd7","command":"tunnel_disconnect","params":{"session_id":"xxx"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Binary WebSocket Messages (Tunnel-Daten)
|
||||||
|
|
||||||
|
Format: `[session_id_length:1][session_id][tcp_payload]`
|
||||||
|
|
||||||
|
Tunnel-Daten werden als Binary WebSocket Messages uebertragen (kein Base64-Overhead).
|
||||||
176
docs/BACKEND.md
Normal file
176
docs/BACKEND.md
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
# Backend — Installation & Konfiguration
|
||||||
|
|
||||||
|
Das RMM-Backend laeuft auf Linux (Debian 12+) und stellt die REST API, den WebSocket Hub und den Tunnel Manager bereit.
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
- **REST API**: Agent-Registrierung, Heartbeat, Systemdaten, Tunnel-Management
|
||||||
|
- **WebSocket Hub**: Verwaltet Agent-Verbindungen, routet Commands und Binary-Messages
|
||||||
|
- **Tunnel Manager**: Proxy-Listener, Session-Tracking, Ready-Handshake
|
||||||
|
- **PostgreSQL + TimescaleDB**: Relationale Daten + Time-Series Metriken
|
||||||
|
|
||||||
|
## 1. PostgreSQL + TimescaleDB installieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Debian 12+ (Bookworm/Trixie)
|
||||||
|
apt install -y postgresql postgresql-client
|
||||||
|
|
||||||
|
# TimescaleDB Repository hinzufuegen
|
||||||
|
echo "deb https://packagecloud.io/timescale/timescaledb/debian/ bookworm main" \
|
||||||
|
> /etc/apt/sources.list.d/timescaledb.list
|
||||||
|
curl -L https://packagecloud.io/timescale/timescaledb/gpgkey | gpg --dearmor \
|
||||||
|
> /etc/apt/trusted.gpg.d/timescaledb.gpg
|
||||||
|
apt update
|
||||||
|
|
||||||
|
# TimescaleDB passend zur PG-Version installieren (z.B. PG 17)
|
||||||
|
apt install -y timescaledb-2-postgresql-17
|
||||||
|
|
||||||
|
# TimescaleDB in postgresql.conf aktivieren
|
||||||
|
echo "shared_preload_libraries = 'timescaledb'" >> /etc/postgresql/17/main/conf.d/timescaledb.conf
|
||||||
|
systemctl restart postgresql
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Datenbank und User anlegen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo -u postgres psql <<EOF
|
||||||
|
CREATE USER rmm WITH PASSWORD 'SICHERES_PASSWORT';
|
||||||
|
CREATE DATABASE rmm OWNER rmm;
|
||||||
|
\c rmm
|
||||||
|
CREATE EXTENSION IF NOT EXISTS timescaledb;
|
||||||
|
GRANT ALL ON SCHEMA public TO rmm;
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Verbindung testen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
psql -h 127.0.0.1 -U rmm -d rmm -c "SELECT default_version FROM pg_available_extensions WHERE name='timescaledb';"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make all # Backend (linux/amd64) + Agent (freebsd/amd64)
|
||||||
|
make backend # Nur Backend
|
||||||
|
make agent # Nur Agent
|
||||||
|
```
|
||||||
|
|
||||||
|
Binaries landen in `build/`. Kein CGO — reine Go-Compilation.
|
||||||
|
|
||||||
|
## 4. TLS-Zertifikate generieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make certs
|
||||||
|
```
|
||||||
|
|
||||||
|
Oder manuell:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p certs
|
||||||
|
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 \
|
||||||
|
-keyout certs/server.key -out certs/server.crt \
|
||||||
|
-days 3650 -nodes \
|
||||||
|
-subj "/CN=rmm-backend/O=RMM" \
|
||||||
|
-addext "subjectAltName=IP:BACKEND_IP,IP:127.0.0.1,DNS:localhost"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. Backend konfigurieren (`config.yaml`)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
listen_addr: ":8443"
|
||||||
|
tls_cert: "certs/server.crt"
|
||||||
|
tls_key: "certs/server.key"
|
||||||
|
api_keys:
|
||||||
|
- "SICHERER_API_KEY"
|
||||||
|
|
||||||
|
database:
|
||||||
|
host: "127.0.0.1"
|
||||||
|
port: 5432
|
||||||
|
user: "rmm"
|
||||||
|
password: "SICHERES_PASSWORT"
|
||||||
|
dbname: "rmm"
|
||||||
|
sslmode: "disable" # "require" wenn PG ueber Netz
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternativ per Environment-Variablen: `RMM_LISTEN_ADDR`, `RMM_TLS_CERT`, `RMM_TLS_KEY`, `RMM_DB_HOST`, `RMM_DB_PASSWORD`.
|
||||||
|
|
||||||
|
## 6. Backend deployen und starten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verzeichnis anlegen
|
||||||
|
ssh root@BACKEND_IP "mkdir -p /opt/rmm/certs"
|
||||||
|
|
||||||
|
# Binary + Config + Certs kopieren
|
||||||
|
scp build/rmm-backend root@BACKEND_IP:/opt/rmm/rmm-backend
|
||||||
|
scp config.yaml root@BACKEND_IP:/opt/rmm/config.yaml
|
||||||
|
scp certs/server.* root@BACKEND_IP:/opt/rmm/certs/
|
||||||
|
|
||||||
|
# Systemd-Service einrichten
|
||||||
|
ssh root@BACKEND_IP 'cat > /etc/systemd/system/rmm-backend.service << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=RMM Backend
|
||||||
|
After=network.target postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory=/opt/rmm
|
||||||
|
ExecStart=/opt/rmm/rmm-backend /opt/rmm/config.yaml
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF'
|
||||||
|
|
||||||
|
ssh root@BACKEND_IP "systemctl daemon-reload && systemctl enable rmm-backend && systemctl start rmm-backend"
|
||||||
|
```
|
||||||
|
|
||||||
|
Oder per Makefile: `make deploy-backend`
|
||||||
|
|
||||||
|
## 7. Starten und verifizieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Status pruefen
|
||||||
|
systemctl status rmm-backend
|
||||||
|
|
||||||
|
# Log pruefen
|
||||||
|
journalctl -u rmm-backend -f
|
||||||
|
|
||||||
|
# API testen
|
||||||
|
curl -sk -H "X-API-Key: DEIN_API_KEY" https://BACKEND_IP:8443/api/v1/agents
|
||||||
|
```
|
||||||
|
|
||||||
|
Beim ersten Start:
|
||||||
|
- Tabellen werden automatisch angelegt
|
||||||
|
- Hypertable `metrics` wird erstellt (TimescaleDB)
|
||||||
|
- Retention Policy (90 Tage) und Compression Policy (nach 7 Tagen) werden automatisch gesetzt
|
||||||
|
- Default-Admin `admin` / `Start!123` wird erstellt
|
||||||
|
|
||||||
|
## Datenbank-Schema (automatisch)
|
||||||
|
|
||||||
|
| Tabelle | Typ | Beschreibung |
|
||||||
|
|---------|-----|-------------|
|
||||||
|
| `agents` | Relational | Agent-Registry (ID, Name, Hostname, IP, Version, Heartbeat, customer_id, update_requested) |
|
||||||
|
| `system_data` | Relational | Letzte Systemdaten pro Agent (JSONB) |
|
||||||
|
| `config_backups` | Relational | OPNsense Config-Backups (dedupliziert per SHA256) |
|
||||||
|
| `agent_events` | Relational | Online/Offline/Connected Events |
|
||||||
|
| `customers` | Relational | Kundenstammdaten (Nummer, Name) |
|
||||||
|
| `users` | Relational | Benutzer (Username, bcrypt-Hash, Display-Name) |
|
||||||
|
| `agent_firmware` | Relational | Agent-Binaries pro Plattform+Version (BYTEA, SHA256) |
|
||||||
|
| `metrics` | TimescaleDB Hypertable | Time-Series Metriken (CPU, RAM, Disk, Network, Gateway) |
|
||||||
|
|
||||||
|
### TimescaleDB Policies
|
||||||
|
|
||||||
|
- **Retention**: Rohdaten werden nach 90 Tagen automatisch geloescht
|
||||||
|
- **Compression**: Daten aelter als 7 Tage werden komprimiert (segmentby: agent_id+metric)
|
||||||
|
|
||||||
|
### DB-Funktionen
|
||||||
|
|
||||||
|
- `GetAgentByName`: Sucht Agent nach Name — verwendet fuer Pre-Registration Matching bei Agent-Registrierung
|
||||||
|
|
||||||
|
## Hinweise
|
||||||
|
|
||||||
|
- Backend braucht **kein root** — laeuft als normaler User auf Port 8443
|
||||||
|
- Beim Deploy: **alte Prozesse killen** bevor neuer startet (sonst "bind: address already in use")
|
||||||
|
- FreeBSD csh hat kein `$()` — Agent verwendet `/bin/sh -c` fuer Commands
|
||||||
121
docs/FIRMWARE.md
Normal file
121
docs/FIRMWARE.md
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
# Firmware-Management & Update-Prozess
|
||||||
|
|
||||||
|
Multi-Plattform Firmware-Verwaltung fuer Agent-Binaries und OPNsense-Updates.
|
||||||
|
|
||||||
|
## Agent-Firmware (Binary-Updates)
|
||||||
|
|
||||||
|
### Ueberblick
|
||||||
|
|
||||||
|
Der Update-Prozess fuer Agent-Binaries nutzt den **rmm-updater** Daemon:
|
||||||
|
|
||||||
|
1. Neue Agent-Binary im Frontend hochladen (Firmware-Seite) oder per API
|
||||||
|
2. Update-Flag bei einzelnem Agent oder "Alle updaten" setzen
|
||||||
|
3. Updater auf der Firewall erkennt den Flag (pollt alle 60s)
|
||||||
|
4. Binary wird vom Backend heruntergeladen und SHA256-verifiziert
|
||||||
|
5. Agent wird gestoppt, Binary ersetzt, Agent gestartet
|
||||||
|
6. Flag wird automatisch zurueckgesetzt
|
||||||
|
|
||||||
|
### Unterstuetzte Plattformen
|
||||||
|
|
||||||
|
| Plattform | Binary | Ziel |
|
||||||
|
|-----------|--------|------|
|
||||||
|
| `freebsd` | `rmm-agent` | OPNsense Firewalls (amd64) |
|
||||||
|
| `linux` | `rmm-agent-linux` | Linux-basierte Agents |
|
||||||
|
| `windows` | `rmm-agent.exe` | Windows-basierte Agents |
|
||||||
|
|
||||||
|
### API-Endpoints
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| GET | `/api/v1/firmware` | Alle Firmware-Versionen (pro Plattform) |
|
||||||
|
| GET | `/api/v1/firmware?platform=freebsd` | Firmware einer Plattform |
|
||||||
|
| POST | `/api/v1/firmware/upload?version=X&platform=Y` | Binary hochladen (Body = Raw Binary) |
|
||||||
|
| GET | `/api/v1/firmware/download?platform=Y` | Binary herunterladen (fuer 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` | Update-Flag fuer alle Agents setzen |
|
||||||
|
| POST | `/api/v1/agents/{id}/agent-update` | Legacy: Binary direkt via WebSocket pushen |
|
||||||
|
|
||||||
|
### Beispiele
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# FreeBSD Agent hochladen
|
||||||
|
curl -sk -X POST "https://192.168.85.13:8443/api/v1/firmware/upload?version=1.0.3&platform=freebsd" \
|
||||||
|
-H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
--data-binary @build/rmm-agent
|
||||||
|
|
||||||
|
# Linux Agent hochladen
|
||||||
|
curl -sk -X POST "https://192.168.85.13:8443/api/v1/firmware/upload?version=1.0.3&platform=linux" \
|
||||||
|
-H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" \
|
||||||
|
--data-binary @build/rmm-agent-linux
|
||||||
|
|
||||||
|
# Update fuer einzelnen Agent anfordern
|
||||||
|
curl -sk -X POST "https://192.168.85.13:8443/api/v1/agents/e92e87a6.../request-update" \
|
||||||
|
-H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9"
|
||||||
|
|
||||||
|
# Update fuer alle Agents anfordern
|
||||||
|
curl -sk -X POST "https://192.168.85.13:8443/api/v1/agents/request-update-all" \
|
||||||
|
-H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Updater — Technische Details
|
||||||
|
|
||||||
|
- Separates Go-Binary (`rmm-updater`), laeuft als `rmm_updater` rc.d Service
|
||||||
|
- Liest die gleiche `config.yaml` wie der Agent (Backend-URL, API-Key)
|
||||||
|
- Download ueber `GET /api/v1/firmware/download?platform=freebsd`
|
||||||
|
- SHA256-Verifizierung vor Ersetzung
|
||||||
|
- Automatisches Rollback bei fehlgeschlagenem Agent-Start
|
||||||
|
- Backup der alten Binary als `.bak` waehrend des Updates
|
||||||
|
- Logs: `/var/log/rmm-updater.log`
|
||||||
|
|
||||||
|
## OPNsense-Updates (Core + Packages)
|
||||||
|
|
||||||
|
### Normales Update
|
||||||
|
|
||||||
|
Patches innerhalb der gleichen Version:
|
||||||
|
|
||||||
|
1. `opnsense-update` — Core-Update herunterladen
|
||||||
|
2. `pkg upgrade -y` — Paket-Updates installieren
|
||||||
|
3. Nachpruefung: `opnsense-update -c` — Exit 1 = Reboot noetig
|
||||||
|
|
||||||
|
Response enthaelt `reboot_required: true/false` fuer das Frontend.
|
||||||
|
|
||||||
|
### Major-Upgrade
|
||||||
|
|
||||||
|
z.B. 25.7 → 26.1:
|
||||||
|
|
||||||
|
1. `opnsense-update -r <version> -bkp` — Repository wechseln + Base + Kernel + Packages herunterladen
|
||||||
|
2. `pkg-static update -f` — Repository-Katalog forciert aktualisieren
|
||||||
|
3. `pkg-static upgrade -y` — Alle Pakete auf neue Version installieren
|
||||||
|
4. **Reboot erforderlich** (immer bei Major-Upgrade)
|
||||||
|
|
||||||
|
### API-Endpoints
|
||||||
|
|
||||||
|
| Methode | Endpoint | Beschreibung |
|
||||||
|
|---------|----------|-------------|
|
||||||
|
| 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 auf Zielversion |
|
||||||
|
| POST | `/api/v1/agents/{id}/reboot` | Reboot ausfuehren |
|
||||||
|
|
||||||
|
### Beispiele
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verfuegbare Updates pruefen
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X POST \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887/update-check
|
||||||
|
|
||||||
|
# Normales Update mit Reboot
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X POST \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887/update \
|
||||||
|
-d '{"reboot":true}'
|
||||||
|
|
||||||
|
# Major-Upgrade auf Version 26.7
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X POST \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887/major-update \
|
||||||
|
-d '{"version":"26.7","reboot":true}'
|
||||||
|
|
||||||
|
# Reboot (5s Verzoegerung default)
|
||||||
|
curl -sk -H "X-API-Key: 01532e5a7c9e70bf2757df77a2f5b9b9" -X POST \
|
||||||
|
https://192.168.85.13:8443/api/v1/agents/e92e87a684b20db15d8d2344583c5887/reboot
|
||||||
|
```
|
||||||
86
docs/FRONTEND.md
Normal file
86
docs/FRONTEND.md
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
# Frontend — Build & Deploy
|
||||||
|
|
||||||
|
React + Vite + TailwindCSS Web-Frontend, deployed als statische Dateien auf Nginx.
|
||||||
|
|
||||||
|
## Eckdaten
|
||||||
|
|
||||||
|
- **Server**: 192.168.85.20 (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` / `Start!123`
|
||||||
|
|
||||||
|
## Seiten
|
||||||
|
|
||||||
|
| Seite | Beschreibung |
|
||||||
|
|-------|-------------|
|
||||||
|
| Dashboard | Uebersicht aller Firewalls, Status-Kacheln, AgentPanel per Klick |
|
||||||
|
| Firewalls | Suchbare Tabelle, AgentPanel mit Tabs (Uebersicht, Interfaces, Dienste, Tunnel, VPN, WireGuard, Routen, DHCP, Zertifikate, Backups, Agent); Firewall hinzufuegen/loeschen |
|
||||||
|
| Tunnel | Globale Tunnel-Uebersicht ueber alle Firewalls |
|
||||||
|
| Firmware | Multi-Plattform Firmware-Upload, Agent-Update-Trigger |
|
||||||
|
| Kunden | CRUD Kundenverwaltung |
|
||||||
|
| Einstellungen | Benutzerverwaltung, Passworte aendern |
|
||||||
|
|
||||||
|
## Features (v1.0.3)
|
||||||
|
|
||||||
|
### Firewall hinzufuegen / Pre-Registration
|
||||||
|
- Dialog mit Name + optionalem Kunden
|
||||||
|
- Zeigt Installationsanleitung mit Copy-Buttons fuer die Shell-Befehle
|
||||||
|
- Agent wird mit `hostname="(ausstehend)"` angelegt, automatisches Matching bei Registration
|
||||||
|
|
||||||
|
### Firewall loeschen
|
||||||
|
- Papierkorb-Icon im AgentPanel
|
||||||
|
- Loescht Agent und alle zugehoerigen Daten (Systemdaten, Events, Backups, Metriken)
|
||||||
|
|
||||||
|
### OPNsense Business Edition Lizenz-Anzeige
|
||||||
|
Im **Uebersicht-Tab** des AgentPanel:
|
||||||
|
- Product Name (z.B. "OPNsense Business Edition")
|
||||||
|
- Subscription Key
|
||||||
|
- Ablaufdatum
|
||||||
|
- Restlaufzeit mit visuellem Farbbalken (gruen/gelb/rot je nach verbleibender Zeit)
|
||||||
|
|
||||||
|
### Agent-Tab
|
||||||
|
- **Agent-Info**: Version, Agent-ID, Plattform, Uptime
|
||||||
|
- **Update-Button**: Direktes Agent-Update anfordern
|
||||||
|
- **Befehle**: Remote-Shell-Befehle direkt aus dem Frontend ausfuehren
|
||||||
|
|
||||||
|
### Firmware-Seite
|
||||||
|
- Multi-Platform Upload (FreeBSD, Linux, Windows)
|
||||||
|
- Versions-Uebersicht pro Plattform mit SHA256-Hash und Groesse
|
||||||
|
- Agent-Update-Buttons (einzeln oder alle)
|
||||||
|
|
||||||
|
## Build & Deploy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
npm run build # ~330 KB JS, ~32 KB CSS
|
||||||
|
ssh root@192.168.85.20 'rm -rf /var/www/html/assets/*' # Alte Hashes loeschen!
|
||||||
|
scp -r dist/* root@192.168.85.20:/var/www/html/
|
||||||
|
```
|
||||||
|
|
||||||
|
**Wichtig:** Vor Deploy immer `assets/` loeschen — Vite generiert Hash-basierte Dateinamen, alte Dateien bleiben sonst auf dem Server und Browser-Cache liefert 404.
|
||||||
|
|
||||||
|
## Dateistruktur
|
||||||
|
|
||||||
|
```
|
||||||
|
frontend/
|
||||||
|
├── src/
|
||||||
|
│ ├── App.jsx # Router + ProtectedRoute
|
||||||
|
│ ├── api/client.js # API Client (auth, agents, firmware, tunnels, etc.)
|
||||||
|
│ ├── stores/auth.js # Zustand Auth Store (JWT Token)
|
||||||
|
│ ├── layouts/AppLayout.jsx # Sidebar + Outlet
|
||||||
|
│ ├── components/
|
||||||
|
│ │ ├── AgentPanel.jsx # Side Panel mit Tabs (Uebersicht bis Agent)
|
||||||
|
│ │ └── StatusBadge.jsx # Online/Offline/Stale Badge
|
||||||
|
│ └── pages/
|
||||||
|
│ ├── Dashboard.jsx # Status-Kacheln + Agent-Liste
|
||||||
|
│ ├── Agents.jsx # Firewall-Tabelle
|
||||||
|
│ ├── AgentDetail.jsx # Detail-Ansicht (full page)
|
||||||
|
│ ├── Tunnels.jsx # Globale Tunnel-Uebersicht
|
||||||
|
│ ├── Firmware.jsx # Multi-Plattform Firmware + Update-Trigger
|
||||||
|
│ ├── Customers.jsx # Kunden CRUD
|
||||||
|
│ ├── SettingsPage.jsx # User-Management
|
||||||
|
│ └── Login.jsx # JWT Login
|
||||||
|
├── vite.config.js
|
||||||
|
└── package.json
|
||||||
|
```
|
||||||
Loading…
x
Reference in New Issue
Block a user