fix(wireguard): Tunnel reißt nie ab + Client-Endpoint auto-befüllt — v1.2.100

Zwei Bugs, die WireGuard-Verbindungen verhinderten/abrissen:
1) Client-Config-Endpoint war hartkodierter Platzhalter REPLACE_WITH_PUBLIC_HOST → neue Clients bauten nie einen Tunnel auf (Host löst nicht auf). Jetzt: WireguardHandler.PublicHost (aus setup.json FQDN, main.go) → Endpoint = <fqdn>:<port>. Platzhalter nur noch als Fallback wenn FQDN unbekannt.
2) Renderer machte bei JEDER Config-Änderung 'systemctl restart wg-quick@<iface>' → voller Link-Flap, alle Peers droppen (verstößt gegen 'wireguard darf nie abbrechen'). Jetzt: laufendes Interface → 'wg-quick strip | wg syncconf' (Peers/Listen-Port live, KEIN Abbruch); nur erstmaliges Hochfahren via systemctl start; restart nur noch als Fallback mit WARN. interfaceExists() via 'ip link show'. Neue sudoers: wg syncconf *, wg-quick strip *.
Ein edgeguard-api-Restart (Deploy) fasst wg-quick@<iface> nicht an → Tunnel bleibt während Deploy bestehen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Debian
2026-06-06 20:51:52 +02:00
parent 7611572062
commit 91e51890dd
6 changed files with 80 additions and 13 deletions

View File

@@ -32,6 +32,10 @@ type WireguardHandler struct {
Audit *audit.Repo
NodeID string
Reloader func(ctx context.Context) error
// PublicHost ist der öffentliche Host (FQDN/IP), den Clients als
// WireGuard-Endpoint anwählen. Wird in heruntergeladene Peer-Configs
// geschrieben (statt eines Platzhalters). Leer → Platzhalter (Fallback).
PublicHost string
}
func NewWireguardHandler(
@@ -45,6 +49,12 @@ func NewWireguardHandler(
return &WireguardHandler{Ifaces: ifaces, Peers: peers, Box: box, Audit: a, NodeID: nodeID, Reloader: reloader}
}
// WithPublicHost setzt den öffentlichen Endpoint-Host für Peer-Configs.
func (h *WireguardHandler) WithPublicHost(host string) *WireguardHandler {
h.PublicHost = strings.TrimSpace(host)
return h
}
func (h *WireguardHandler) reload(ctx context.Context, op string) {
if h.Reloader == nil {
return
@@ -702,11 +712,15 @@ func (h *WireguardHandler) peerConfigText(ctx context.Context, peerID int64) (st
clientAllowedIPs += ", " + strings.TrimSpace(*ifc.ClientRoutes)
}
fmt.Fprintf(&b, "AllowedIPs = %s\n", clientAllowedIPs)
// Endpoint — the operator's public host:port that peers dial.
// We don't know this here (could be a CNAME or behind a load
// balancer); leave a placeholder the operator must fill in.
// Endpoint — der öffentliche Host:Port, den Clients anwählen. Standard
// ist der FQDN dieser Node (PublicHost, aus setup.json). Nur wenn der
// nicht ermittelbar ist, bleibt ein Platzhalter den der Operator füllt.
if ifc.ListenPort != nil {
fmt.Fprintf(&b, "Endpoint = REPLACE_WITH_PUBLIC_HOST:%d\n", *ifc.ListenPort)
host := h.PublicHost
if host == "" {
host = "REPLACE_WITH_PUBLIC_HOST"
}
fmt.Fprintf(&b, "Endpoint = %s:%d\n", host, *ifc.ListenPort)
}
if p.Keepalive != nil && *p.Keepalive > 0 {
fmt.Fprintf(&b, "PersistentKeepalive = %d\n", *p.Keepalive)