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:
@@ -50,6 +50,20 @@ func (api *API) vpnAutoUDPPorts() []int {
|
||||
return []int{cfg.ListenPort}
|
||||
}
|
||||
|
||||
// vpnCIDR returns the VPN subnet CIDR (e.g. "10.8.0.0/24") when VPN is enabled
|
||||
// with LAN routing configured. Used to generate nftables masquerade rules.
|
||||
func (api *API) vpnCIDR() string {
|
||||
cfg, err := api.vpn.GetConfig()
|
||||
if err != nil || !cfg.Enabled || cfg.LanCIDR == "" {
|
||||
return ""
|
||||
}
|
||||
_, vpnNet, err := net.ParseCIDR(cfg.Address)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return vpnNet.String()
|
||||
}
|
||||
|
||||
// syncNftablesOnly regenerates and applies nftables rules from the current global config
|
||||
// without touching HAProxy. Called when firewall settings change independently.
|
||||
// Runs errors are logged only — the caller does not wait for completion.
|
||||
@@ -76,7 +90,8 @@ func (api *API) syncNftablesOnly(globalCfg *config.State) {
|
||||
extraTCP, extraUDP := config.SplitExtraPorts(nftCfg.ExtraPorts)
|
||||
extraUDP = append(extraUDP, api.vpnAutoUDPPorts()...)
|
||||
ports := api.haproxy.GetListenPorts(customRoutes)
|
||||
nftContent := api.nftables.Generate(ports, extraTCP, extraUDP, nftCfg.WANInterface)
|
||||
vpnCIDR := api.vpnCIDR()
|
||||
nftContent := api.nftables.Generate(ports, extraTCP, extraUDP, nftCfg.WANInterface, vpnCIDR)
|
||||
if err := api.nftables.WriteRules(nftContent); err != nil {
|
||||
slog.Error("failed to write nftables rules", "component", "nftables-sync", "error", err)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user