fix: Move VPN masquerade rules from iptables PostUp to nftables

iptables-nft rules added by WireGuard's PostUp were being flushed by
Docker on startup, breaking VPN LAN routing until the next reboot.
The nftables inet wild-central table survives Docker restarts.
This commit is contained in:
2026-10-23 13:32:41 +00:00
parent 1176c7715a
commit d35d0854cb
4 changed files with 76 additions and 20 deletions

View File

@@ -460,16 +460,9 @@ func (m *Manager) renderWgConfig(cfg *Config, srv *secrets, peers []*Peer) strin
// DNS is intentionally omitted from the server config — it belongs only in
// the client peer config (GeneratePeerConfigText). Setting it here would
// cause wg-quick to reconfigure the server's own DNS resolver.
// When LAN CIDR is configured: allow forwarding between wg0 and LAN, and masquerade.
// Uses iptables (iptables-nft on modern systems) for reliable PostUp/PreDown syntax.
if cfg.LanCIDR != "" {
_, vpnNet, _ := net.ParseCIDR(cfg.Address)
if vpnNet != nil {
vpnCIDR := vpnNet.String()
fmt.Fprintf(&sb, "PostUp = iptables -I FORWARD -i wg0 -j ACCEPT; iptables -I FORWARD -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -A POSTROUTING -s %s ! -d %s -j MASQUERADE\n", vpnCIDR, vpnCIDR)
fmt.Fprintf(&sb, "PreDown = iptables -D FORWARD -i wg0 -j ACCEPT 2>/dev/null; iptables -D FORWARD -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null; iptables -t nat -D POSTROUTING -s %s ! -d %s -j MASQUERADE 2>/dev/null; true\n", vpnCIDR, vpnCIDR)
}
}
// VPN forwarding and masquerade rules are managed in the nftables table
// (inet wild-central) rather than iptables PostUp/PreDown, so they survive
// Docker restarts which flush the iptables-nft compatibility tables.
for _, p := range peers {
sb.WriteString("\n[Peer]\n")
fmt.Fprintf(&sb, "# %s\n", p.Name)