feat: WireGuard (server + client + peers + QR) + shared UI components
WireGuard --------- * Migration 0013: wireguard_interfaces (server|client mode, key envelope- encrypted) + wireguard_peers (per-server roster). Drop old empty 0005-Schema (Option-A peer_type, kein Iface-FK), neuer Aufbau mit zwei Tabellen + FK. * internal/services/secrets: Box mit AES-256-GCM, Master-Key in /var/lib/edgeguard/.master_key (lazy-create, 0600). Sealed/Open für PrivateKey + PSK. * internal/services/wireguard: KeyGen (Curve25519 mit clamping), PublicFromPrivate (für Import), InterfacesRepo, PeersRepo, Importer (parst /etc/wireguard/*.conf, server vs. client heuristisch nach ListenPort + Peer-Anzahl). * internal/wireguard: Renderer schreibt /etc/edgeguard/wireguard/<iface>.conf (0600), restartet wg-quick@<iface> via sudo (sudoers im postinst erweitert). Idempotent — re-render nur wenn content geändert. * internal/handlers/wireguard.go: REST CRUD für interfaces+peers, /generate-keypair, /peers/:id/config (text/plain wg-quick conf), /peers/:id/qr (PNG via go-qrcode). Auto-reload nach Mutation. * edgeguard-ctl wg-import [--path /etc/wireguard]: liest existierende conf-Files in die DB. Idempotent (überspringt vorhandene Iface-Namen). Shared UI components (proxy-lb-waf design pattern) -------------------------------------------------- * PageHeader: icon + title + subtitle + extras row, einheitlich oben auf jeder Page. * ActionButtons: Edit + Delete combo mit Popconfirm + Tooltip. * StatusDot: AntD Badge pattern statt "Yes/No" — schneller scanbar in dichten Tabellen. * DataTable: pageSizeOptions [20,50,100,200] + extraActions-Alias + optional renderMobileCard für Card-Liste auf < md Breakpoint. * enterprise.css: .page-header* + .datatable-toolbar Klassen. Frontend WireGuard ------------------ * /vpn/wireguard mit zwei Tabs (Server / Client) im neuen Pattern. * Server-Tab: Modal mit Generate-Keypair-Toggle, Peer-Roster im Drawer per Server. Pro Peer: QR-Code-Modal + .conf-Download. * Client-Tab: Upstream-Card im Modal, full-tunnel-Default (0.0.0.0/0,::/0), Keepalive 25. * i18n DE/EN für wg.* Block + common.* Erweiterung. Misc ---- * Sidebar: WireGuard unter Security-Sektion. * Nav-i18n: "Firewall (v2)" → "Firewall". * Version 1.0.8 → 1.0.11. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,8 @@
|
||||
"ipAddresses": "IP-Adressen",
|
||||
"ssl": "SSL-Zertifikate",
|
||||
"vpn": "VPN",
|
||||
"firewall": "Firewall (v2)",
|
||||
"wireguard": "WireGuard",
|
||||
"firewall": "Firewall",
|
||||
"cluster": "Cluster",
|
||||
"settings": "Einstellungen",
|
||||
"section": {
|
||||
@@ -278,6 +279,72 @@
|
||||
"applying": "Update läuft …",
|
||||
"started": "Update wurde gestartet — der Server wird in Kürze neu starten."
|
||||
},
|
||||
"wg": {
|
||||
"title": "WireGuard",
|
||||
"intro": "VPN-Tunnel über WireGuard. Server-Modus = wir lauschen für Peers; Client-Modus = wir verbinden zu einem festen Upstream. Privater Schlüssel liegt verschlüsselt in der DB.",
|
||||
"tabs": { "servers": "Server-Tunnel", "clients": "Client-Tunnel" },
|
||||
"serverIntro": "Server-Tunnel hosten ein Peer-Roster — z.B. Mitarbeiter-Geräte oder Niederlassungen. Pro Peer bekommt der Operator eine .conf zum Download (oder QR-Code für Mobile).",
|
||||
"clientIntro": "Client-Tunnel verbinden EdgeGuard zu einem fremden WireGuard-Server (z.B. HQ-Datacenter). Allowed-IPs steuert, welcher Traffic durch den Tunnel geroutet wird.",
|
||||
"iface": {
|
||||
"name": "Name",
|
||||
"namePattern": "wg gefolgt von Kleinbuchstaben/Ziffern/-, max. 15 Zeichen",
|
||||
"nameExtra": "Empfehlung: wg0, wg1, wg-hq …",
|
||||
"address": "Adresse (CIDR)",
|
||||
"addressExtra": "Tunnel-IP der Box, z.B. 10.99.0.1/24 für /24-Pool",
|
||||
"listenPort": "Listen-Port",
|
||||
"publicKey": "Public-Key",
|
||||
"privateKey": "Private-Key (paste)",
|
||||
"privateKeyExtra": "Nur ausfüllen wenn nicht generieren — base64 32 Byte. Wird verschlüsselt gespeichert.",
|
||||
"peerEndpoint": "Peer-Endpoint",
|
||||
"peerPublicKey": "Peer Public-Key",
|
||||
"peerPSK": "Pre-Shared-Key (PSK)",
|
||||
"peerPSKExtra": "Optional, zusätzliche Schicht",
|
||||
"allowedIPs": "Allowed IPs",
|
||||
"allowedIPsExtra": "Was durch den Tunnel geroutet wird. Default = full-tunnel.",
|
||||
"keepalive": "Persistent Keepalive (sec)",
|
||||
"mtu": "MTU",
|
||||
"zone": "Firewall-Zone",
|
||||
"description": "Beschreibung",
|
||||
"addServer": "Server-Tunnel hinzufügen",
|
||||
"editServer": "Server-Tunnel bearbeiten",
|
||||
"addClient": "Client-Tunnel hinzufügen",
|
||||
"editClient": "Client-Tunnel bearbeiten",
|
||||
"upstream": "Upstream-Peer",
|
||||
"deleteConfirm": "Tunnel {{name}} wirklich löschen? wg-quick wird gestoppt.",
|
||||
"keys": "Schlüssel",
|
||||
"generateExtra": "Wenn an: Server erzeugt ein neues Curve25519-Keypair beim Speichern.",
|
||||
"generateOn": "Server generiert",
|
||||
"generateOff": "Manuell paste",
|
||||
"editKeyWarning": "Achtung: neue Schlüssel = bestehende Peer-Configs ungültig. Nur ändern wenn explizit gewollt."
|
||||
},
|
||||
"peers": {
|
||||
"button": "Peers",
|
||||
"drawerTitle": "Peer-Roster"
|
||||
},
|
||||
"peer": {
|
||||
"name": "Name",
|
||||
"publicKey": "Public-Key",
|
||||
"publicKeyExtra": "Wird vom Peer-Gerät erzeugt; hier nur paste-bar wenn der Peer schon ein Key-Pair hat.",
|
||||
"allowedIPs": "Allowed IPs",
|
||||
"allowedIPsExtra": "Welche Tunnel-IPs darf dieser Peer benutzen. Typisch /32 = eine IP.",
|
||||
"keepalive": "Keepalive (sec)",
|
||||
"keepaliveExtra": "0 = aus. Empfohlen 25 hinter NAT.",
|
||||
"lastHandshake": "Letzter Handshake",
|
||||
"never": "nie",
|
||||
"description": "Beschreibung",
|
||||
"add": "Peer hinzufügen",
|
||||
"edit": "Peer bearbeiten",
|
||||
"deleteConfirm": "Peer {{name}} wirklich entfernen?",
|
||||
"keys": "Schlüssel",
|
||||
"generateExtra": "Wenn an: Server erzeugt für diesen Peer ein Keypair und kann die Config / QR-Code ausliefern. Wenn aus: nur den Public-Key paste-en — keine Config-Download möglich.",
|
||||
"pskExtra": "Wenn an: Server generiert einen 32-Byte PSK für diesen Peer.",
|
||||
"pskOn": "PSK generieren",
|
||||
"pskOff": "kein PSK",
|
||||
"downloadConf": "wg-quick.conf herunterladen",
|
||||
"qrTitle": "WireGuard-QR",
|
||||
"qrHint": "Mit der WireGuard-App (iOS/Android) scannen: \"Tunnel hinzufügen\" → \"QR-Code scannen\". Endpoint im Download-Conf bitte vor Verwendung anpassen."
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
"yes": "Ja",
|
||||
"no": "Nein",
|
||||
@@ -287,7 +354,16 @@
|
||||
"error": "Fehler",
|
||||
"edit": "Bearbeiten",
|
||||
"delete": "Löschen",
|
||||
"deleteConfirm": "Wirklich löschen?",
|
||||
"search": "Suchen …",
|
||||
"totalRows": "{{count}} Einträge"
|
||||
"totalRows": "{{count}} Einträge",
|
||||
"active": "Aktiv",
|
||||
"inactive": "Inaktiv",
|
||||
"noData": "Keine Einträge",
|
||||
"actions": "Aktionen",
|
||||
"add": "Hinzufügen",
|
||||
"download": "Download",
|
||||
"copy": "Kopieren",
|
||||
"copied": "Kopiert"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user