- WireGuard-Peer-Änderungen landeten nicht im laufenden Interface: /etc/wireguard/ ist root:root 700, os.Readlink schlug fehl → ensureWGQuickSymlink fiel immer in den Error-Pfad. Fix: Symlink via sudo /bin/ln -sf (sudoers-Entry in postinst ergänzt). - Site-to-Site-Masquerade: Roadwarrior-Clients (z. B. 192.168.99.3) konnten LANs hinter anderen Peers nicht erreichen, weil das remote Gateway die VPN-Client-IP nicht als Tunnel-Route kannte. Fix: auto masquerade in nftables postrouting_nat pro WireGuard-Server-Interface (oifname "wg7" ip saddr 192.168.99.0/24 masquerade). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
49 lines
1.7 KiB
Go
49 lines
1.7 KiB
Go
package wireguard
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
)
|
|
|
|
// wg-quick is managed via systemd unit instances (wg-quick@<iface>).
|
|
// Reload-via-syncconf would be cheaper (no link flap) but needs more
|
|
// per-change diffing — for v1 we restart the unit, which takes ~1s
|
|
// and re-establishes peers cleanly. The sudoers entry shipped in
|
|
// postinst whitelists exactly these three commands.
|
|
|
|
func startWGQuick(iface string) error {
|
|
cmd := exec.Command("sudo", "-n", "/usr/bin/systemctl", "start", "wg-quick@"+iface+".service")
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
return fmt.Errorf("systemctl start wg-quick@%s: %w: %s", iface, err, string(out))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func restartWGQuick(iface string) error {
|
|
cmd := exec.Command("sudo", "-n", "/usr/bin/systemctl", "restart", "wg-quick@"+iface+".service")
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
return fmt.Errorf("systemctl restart wg-quick@%s: %w: %s", iface, err, string(out))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func stopWGQuick(iface string) error {
|
|
cmd := exec.Command("sudo", "-n", "/usr/bin/systemctl", "stop", "wg-quick@"+iface+".service")
|
|
// Ignore failures — unit may not exist.
|
|
_ = cmd.Run()
|
|
return nil
|
|
}
|
|
|
|
// symlinkWGQuickConf creates (or atomically replaces) the symlink
|
|
// /etc/wireguard/<iface>.conf → target via sudo. /etc/wireguard/ is
|
|
// owned root:root 700 so the edgeguard user cannot write to it directly;
|
|
// the sudoers entry in postinst whitelists exactly this ln command.
|
|
func symlinkWGQuickConf(iface, target string) error {
|
|
link := "/etc/wireguard/" + iface + ".conf"
|
|
cmd := exec.Command("sudo", "-n", "/bin/ln", "-sf", target, link)
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
return fmt.Errorf("ln -sf %s %s: %w: %s", target, link, err, string(out))
|
|
}
|
|
return nil
|
|
}
|