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,6 +12,7 @@
|
||||
"ipAddresses": "IP addresses",
|
||||
"ssl": "SSL certificates",
|
||||
"vpn": "VPN",
|
||||
"wireguard": "WireGuard",
|
||||
"firewall": "Firewall",
|
||||
"cluster": "Cluster",
|
||||
"settings": "Settings",
|
||||
@@ -278,6 +279,72 @@
|
||||
"applying": "Update in progress …",
|
||||
"started": "Update has started — the server will restart shortly."
|
||||
},
|
||||
"wg": {
|
||||
"title": "WireGuard",
|
||||
"intro": "WireGuard VPN tunnels. Server mode = we listen for peers; client mode = we dial out to a fixed upstream. Private keys are encrypted at rest.",
|
||||
"tabs": { "servers": "Server tunnels", "clients": "Client tunnels" },
|
||||
"serverIntro": "Server tunnels host a peer roster — typically employee devices or branch sites. Each peer can be downloaded as a wg-quick.conf or scanned as a QR code.",
|
||||
"clientIntro": "Client tunnels connect EdgeGuard to a remote WireGuard server (e.g. HQ datacenter). Allowed IPs control which traffic is routed through the tunnel.",
|
||||
"iface": {
|
||||
"name": "Name",
|
||||
"namePattern": "wg followed by lowercase letters/digits/-, max 15 chars",
|
||||
"nameExtra": "Suggested: wg0, wg1, wg-hq …",
|
||||
"address": "Address (CIDR)",
|
||||
"addressExtra": "Box's tunnel IP, e.g. 10.99.0.1/24 for a /24 pool",
|
||||
"listenPort": "Listen port",
|
||||
"publicKey": "Public key",
|
||||
"privateKey": "Private key (paste)",
|
||||
"privateKeyExtra": "Fill in only if not auto-generating — base64 32 bytes. Stored encrypted.",
|
||||
"peerEndpoint": "Peer endpoint",
|
||||
"peerPublicKey": "Peer public key",
|
||||
"peerPSK": "Pre-shared key (PSK)",
|
||||
"peerPSKExtra": "Optional extra layer",
|
||||
"allowedIPs": "Allowed IPs",
|
||||
"allowedIPsExtra": "What gets routed through the tunnel. Default = full tunnel.",
|
||||
"keepalive": "Persistent keepalive (sec)",
|
||||
"mtu": "MTU",
|
||||
"zone": "Firewall zone",
|
||||
"description": "Description",
|
||||
"addServer": "Add server tunnel",
|
||||
"editServer": "Edit server tunnel",
|
||||
"addClient": "Add client tunnel",
|
||||
"editClient": "Edit client tunnel",
|
||||
"upstream": "Upstream peer",
|
||||
"deleteConfirm": "Really delete tunnel {{name}}? wg-quick will be stopped.",
|
||||
"keys": "Keys",
|
||||
"generateExtra": "If on: server generates a fresh Curve25519 keypair on save.",
|
||||
"generateOn": "Server-generated",
|
||||
"generateOff": "Manual paste",
|
||||
"editKeyWarning": "Warning: new keys invalidate all existing peer configs. Only change if intentional."
|
||||
},
|
||||
"peers": {
|
||||
"button": "Peers",
|
||||
"drawerTitle": "Peer roster"
|
||||
},
|
||||
"peer": {
|
||||
"name": "Name",
|
||||
"publicKey": "Public key",
|
||||
"publicKeyExtra": "Generated by the peer device; only paste here if the peer already has a keypair.",
|
||||
"allowedIPs": "Allowed IPs",
|
||||
"allowedIPsExtra": "Which tunnel IPs this peer is allowed to use. Typically /32 = one IP.",
|
||||
"keepalive": "Keepalive (sec)",
|
||||
"keepaliveExtra": "0 = off. Recommended 25 behind NAT.",
|
||||
"lastHandshake": "Last handshake",
|
||||
"never": "never",
|
||||
"description": "Description",
|
||||
"add": "Add peer",
|
||||
"edit": "Edit peer",
|
||||
"deleteConfirm": "Really remove peer {{name}}?",
|
||||
"keys": "Keys",
|
||||
"generateExtra": "If on: server generates a keypair for this peer and can hand out the config / QR. If off: paste the peer's public key only — no config download.",
|
||||
"pskExtra": "If on: server generates a 32-byte PSK for this peer.",
|
||||
"pskOn": "Generate PSK",
|
||||
"pskOff": "no PSK",
|
||||
"downloadConf": "Download wg-quick.conf",
|
||||
"qrTitle": "WireGuard QR",
|
||||
"qrHint": "Scan with the WireGuard app (iOS/Android): \"Add tunnel\" → \"Scan QR code\". Replace the Endpoint placeholder in the downloaded conf before use."
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
@@ -287,7 +354,16 @@
|
||||
"error": "Error",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"deleteConfirm": "Really delete?",
|
||||
"search": "Search …",
|
||||
"totalRows": "{{count}} rows"
|
||||
"totalRows": "{{count}} rows",
|
||||
"active": "Active",
|
||||
"inactive": "Inactive",
|
||||
"noData": "No data",
|
||||
"actions": "Actions",
|
||||
"add": "Add",
|
||||
"download": "Download",
|
||||
"copy": "Copy",
|
||||
"copied": "Copied"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user