Add wireguard-ui-multi core: multi-server DB, WireGuard manager, REST API, UI, installers

Implements the from-scratch multi-server WireGuard management fork per
CLAUDE.md spec: sqlite schema (servers/peers/audit_log/users), Curve25519
key generation, per-interface config rendering + wg-quick/systemd control,
nftables hook scaffolding, session+CSRF-protected REST API with QR code
and config download endpoints, a minimal vanilla-JS web UI, legacy
wg0.conf migration, and both a native installer and a Proxmox LXC
provisioning script (with auto-detected latest Debian template).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
sysops
2026-07-10 02:53:14 +02:00
co-authored by Claude Sonnet 5
parent 3d6608ef80
commit 3b3ffd8ebf
26 changed files with 3236 additions and 0 deletions
+234
View File
@@ -0,0 +1,234 @@
# wireguard-ui-multi
Native Multi-Server-Verwaltungsoberfläche für WireGuard — **ohne Docker**.
Im Gegensatz zum ursprünglichen `wireguard-ui`, das genau eine WireGuard-Instanz
verwaltet, kann `wireguard-ui-multi` mehrere unabhängige WireGuard-Interfaces
gleichzeitig verwalten (z. B. `wg-home`, `wg-rz`, `wg-winter`), jedes mit
eigenem Port, eigenem Adressbereich, eigenen Peers und eigenem Status.
Zielumgebungen: Debian/Ubuntu, Proxmox LXC Container, generisches Linux mit
systemd. Betrieb als natives Go-Binary.
## Features
- **Multi-Server-Verwaltung**: beliebig viele WireGuard-Server, jeder mit
eigenem Interface-Namen, Port, Private/Public Key, Adressbereich, DNS, MTU
und Enabled/Disabled-Status (Tabelle `servers` in SQLite).
- **Peer-Verwaltung pro Server**: Peers gehören zu genau einem Server
(Fremdschlüssel `server_id`), inklusive Name, E-Mail, Public/Private/
Preshared Key, Allowed IPs, Endpoint, Persistent Keepalive, Enabled-Status
und optionalem Ablaufdatum (`expires_at`).
- **Automatische Config-Erzeugung**: Server-Configs werden nach
`/etc/wireguard/<interface>.conf` im Standard-`wg-quick`-Format geschrieben.
- **Service-Steuerung**: Start/Stop/Reload je Interface über `wg-quick up`,
`wg-quick down` und `wg syncconf` (Hot-Reload ohne Verbindungsabbruch),
Status-Abfrage über `wg show`.
- **QR-Code & Config-Download**: Peer-Konfiguration kann als `.conf`-Datei
heruntergeladen oder als QR-Code (PNG) angezeigt werden — Private Keys
verlassen den Server nur in dieser generierten Peer-Config, nie über die
UI/JSON-API.
- **REST-API** für Server- und Peer-Verwaltung (siehe unten) plus
Web-Dashboard.
- **Firewall-Vorbereitung**: optionale Lifecycle-Hook-Skripte
(`server-start`, `server-stop`, `peer-add`, `peer-remove`) in
`/etc/wireguard-manager/hooks/` sowie ein Generator für einen
Vorschlags-nftables-Ruleset pro Server (Port freigeben, Forwarding
Tunnel ↔ LAN-Interface).
- **Audit Log**: Tabelle `audit_log` protokolliert Aktionen mit Akteur,
Aktion, Ziel und Detail.
- **Sitzungsbasierte Authentifizierung** mit CSRF-Schutz: jede mutierende
Anfrage (POST/PUT/DELETE) benötigt einen gültigen Session-Cookie plus
den Header `X-CSRF-Token`.
- Optional HTTPS über `--tls-cert` / `--tls-key`.
## Installation
### 1. Aus dem Quellcode bauen
```bash
go build -o wireguard-ui-multi ./cmd/wireguard-ui-multi
```
### 2. Installationsskript ausführen (als root)
```bash
sudo ./scripts/install.sh
```
Das Skript ist idempotent und:
- kopiert die Binary nach `/usr/local/bin/wireguard-ui-multi`
- legt `/etc/wireguard-ui-multi`, `/var/lib/wireguard-ui-multi` und
`/etc/wireguard-manager/hooks` an
- installiert die systemd-Unit nach
`/etc/systemd/system/wireguard-ui-multi.service`
- setzt `chmod 0700` auf das Datenverzeichnis (dort liegt die SQLite-DB mit
Passwort-Hashes)
**Wichtig:** Das Skript startet den Dienst nicht automatisch. Danach manuell
aktivieren:
```bash
sudo systemctl enable --now wireguard-ui-multi.service
sudo systemctl status wireguard-ui-multi.service
sudo journalctl -u wireguard-ui-multi.service -f
```
## Konfiguration
Die Anwendung wird über Kommandozeilen-Flags konfiguriert (siehe
`cmd/wireguard-ui-multi/main.go`):
| Flag | Default | Bedeutung |
|----------------|-------------------------------------------------------|-------------------------------------------------------|
| `--listen` | `:8443` | Listen-Adresse des Webservers |
| `--db` | `/var/lib/wireguard-ui-multi/wireguard-ui-multi.db` | Pfad zur SQLite-Datenbankdatei |
| `--config-dir` | `/etc/wireguard` | Zielverzeichnis für generierte `wg-quick`-Configs |
| `--hooks-dir` | `/etc/wireguard-manager/hooks` | Verzeichnis mit optionalen Hook-Skripten |
| `--lan-iface` | `eth0` | LAN-Interface für die vorgeschlagenen nftables-Forward-Regeln |
| `--tls-cert` | (leer) | Pfad zum TLS-Zertifikat (aktiviert HTTPS zusammen mit `--tls-key`) |
| `--tls-key` | (leer) | Pfad zum TLS-Private-Key |
Die in `systemd/wireguard-ui-multi.service` hinterlegte `ExecStart`-Zeile
setzt `--db`, `--config-dir` und `--hooks-dir` bereits passend zur
Installationsstruktur.
### Erststart / Admin-Passwort
Beim allerersten Start (leere `users`-Tabelle) wird automatisch ein
`admin`-Benutzer mit einem zufällig erzeugten 32-stelligen Hex-Passwort
angelegt. Das Klartext-Passwort wird **genau einmal** auf `stderr`
ausgegeben (z. B. sichtbar via `journalctl -u wireguard-ui-multi.service`)
und danach nur noch als bcrypt-Hash in der Datenbank gespeichert. Nach dem
ersten Login sollte das Passwort umgehend geändert werden.
## LXC / Proxmox Hinweise
WireGuard benötigt Zugriff auf das `wireguard`-Kernelmodul des Hosts sowie
`CAP_NET_ADMIN` und Zugriff auf `/dev/net/tun` im Container:
- Auf dem **Proxmox-Host** muss das `wireguard`-Kernelmodul geladen sein
(`modprobe wireguard`; bei Bedarf `/etc/modules` ergänzen).
- Der LXC-Container sollte entweder **privilegiert** betrieben werden, oder
als unprivilegierter Container mit gezielten Lockerungen
(`lxc.cap.drop` ohne `net_admin`, `lxc.cgroup2.devices.allow: c 10:200 rwm`
für `/dev/net/tun`) konfiguriert werden. In der Praxis ist ein
privilegierter Container für WireGuard-Hosting deutlich unkomplizierter.
- `/dev/net/tun` muss im Container vorhanden und beschreibbar sein
(`ls -l /dev/net/tun`); ggf. per Bind-Mount/`lxc.mount.entry` durchreichen.
- Die systemd-Unit läuft als `root` mit `AmbientCapabilities=CAP_NET_ADMIN`,
weil sie `wg-quick`, `systemctl` und `nft` aufruft — diese Tools benötigen
in der Praxis root-Rechte im Container.
- Läuft `nftables` bereits als eigener Dienst im Container/Host, sollte der
von `wireguard-ui-multi` vorgeschlagene Ruleset (siehe unten) manuell in
die bestehende Regelbasis integriert statt blind angewendet werden, um
Konflikte mit vorhandenen Tabellen/Chains zu vermeiden.
## Server- & Peer-Verwaltung
**Server anlegen** (UI oder `POST /api/servers`): Name, Interface-Name
(z. B. `wg-home`), Listen-Port, Adressbereich (z. B. `10.20.22.0/24`), DNS,
MTU angeben. Private/Public Key werden serverseitig automatisch erzeugt.
**Server starten/stoppen/neuladen**: über die Dashboard-Buttons oder
`POST /api/servers/{id}/start|stop|reload`. Start schreibt zunächst die
`wg-quick`-Config nach `/etc/wireguard/<interface>.conf` und ruft dann
`wg-quick up <interface>` auf; Reload nutzt `wg syncconf` für einen
Hot-Reload ohne Tunnelabbruch.
**Peer hinzufügen** (UI oder `POST /api/server/{id}/peer`): Name, optional
E-Mail/Beschreibung und Ablaufdatum angeben — Schlüsselpaar und Preshared
Key werden automatisch generiert.
**Config/QR-Code abrufen**: `GET /api/server/{id}/peer/{peerid}/config`
liefert die fertige `.conf`-Datei zum Download, `GET
/api/server/{id}/peer/{peerid}/qrcode` liefert denselben Inhalt als
PNG-QR-Code zum Scannen mit der WireGuard-App.
### REST-API-Übersicht
```
POST /api/login
POST /api/logout
GET /api/servers
POST /api/servers
GET /api/servers/{id}
PUT /api/servers/{id}
DELETE /api/servers/{id}
POST /api/servers/{id}/start
POST /api/servers/{id}/stop
POST /api/servers/{id}/reload
GET /api/servers/{id}/config
GET /api/server/{id}/peers
POST /api/server/{id}/peer
DELETE /api/server/{id}/peer/{peerid}
GET /api/server/{id}/peer/{peerid}/config
GET /api/server/{id}/peer/{peerid}/qrcode
```
Alle Endpunkte außer `/api/login` erfordern einen gültigen Session-Cookie;
mutierende Methoden (POST/PUT/DELETE) benötigen zusätzlich den Header
`X-CSRF-Token` mit dem beim Login ausgegebenen Token.
## Backup / Restore
Ein automatisiertes Backup-/Restore-Werkzeug ist aktuell **nicht**
implementiert. Für ein manuelles Backup genügt es, folgende Pfade zu
sichern:
- die SQLite-Datenbank: `/var/lib/wireguard-ui-multi/wireguard-ui-multi.db`
(enthält Server, Peers, Keys, Audit Log, Benutzer)
- die generierten Interface-Configs: `/etc/wireguard/*.conf`
- ggf. eigene Hook-Skripte: `/etc/wireguard-manager/hooks/`
Beispiel:
```bash
sudo tar czf wireguard-ui-multi-backup-$(date +%F).tar.gz \
/var/lib/wireguard-ui-multi/wireguard-ui-multi.db \
/etc/wireguard/*.conf \
/etc/wireguard-manager/hooks
```
**Restore**: Dienst stoppen, Archiv an denselben Pfaden entpacken,
Berechtigungen prüfen (`chmod 0700` auf das Datenverzeichnis) und Dienst
wieder starten:
```bash
sudo systemctl stop wireguard-ui-multi.service
sudo tar xzf wireguard-ui-multi-backup-YYYY-MM-DD.tar.gz -C /
sudo systemctl start wireguard-ui-multi.service
```
## Migration von einer bestehenden wireguard-ui-Installation
Für den Umstieg von einer klassischen Single-Interface-Installation
(`/etc/wireguard/wg0.conf`) ist ein Migrationswerkzeug vorgesehen, das eine
bestehende `wg0.conf` einliest und als ersten verwalteten Server samt seiner
Peers importiert. Damit lässt sich eine vorhandene WireGuard-Instanz
übernehmen, ohne bestehende Clients neu konfigurieren zu müssen. Details zum
genauen Ablauf und den Aufrufoptionen siehe die Implementierung im
`wireguard`-Package des Repos, sobald verfügbar; grundsätzlich gilt: vor der
Migration ein Backup der bestehenden `wg0.conf` anlegen.
## Sicherheitshinweise
- **Private Keys werden nie im Frontend/JSON angezeigt** — sie werden
ausschließlich serverseitig in generierten `.conf`-Dateien bzw.
QR-Codes für einzelne Peers ausgeliefert.
- **HTTPS verwenden**: entweder direkt über `--tls-cert`/`--tls-key`, oder
die Anwendung hinter einem Reverse Proxy (nginx, Caddy, Traefik) mit
TLS-Terminierung betreiben. Ohne TLS gibt der Dienst beim Start eine
deutliche Warnung aus.
- **Standard-Admin-Passwort sofort ändern**: das beim Erststart einmalig
ausgegebene zufällige Passwort sollte direkt nach dem ersten Login
geändert werden.
- Mutierende API-Aufrufe erfordern einen gültigen Session-Cookie **und**
den CSRF-Header `X-CSRF-Token` — Clients/Skripte, die die API direkt
ansprechen, müssen sich zunächst über `/api/login` anmelden und den
zurückgegebenen Token mitführen.
- Die Datenverzeichnisse (`/var/lib/wireguard-ui-multi`) sollten
restriktive Berechtigungen (`0700`) behalten, da dort Schlüsselmaterial
und Passwort-Hashes liegen.