Normalize AllocatedIPs/ExtraAllowedIPs to network address before ip route replace

A client CIDR with nonzero host bits (e.g. 10.66.120.1/30 instead of the
network 10.66.120.0/30) is tolerated by wg's own AllowedIPs/setconf, which
just warns, but plain iproute2 rejects it with "Invalid prefix for given
prefix length" and aborts the whole PostUp chain, taking the interface
down on start. Added a routeNet template func that clears host bits via
net.ParseCIDR before generating each PostUp route line.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ATVUwTa4Pqwq26orW5BcDW
This commit is contained in:
sysops
2026-07-29 14:30:53 +02:00
co-authored by Claude Sonnet 5
parent 3e57de1b44
commit 1539c589a1
3 changed files with 237 additions and 2 deletions
+20 -1
View File
@@ -566,6 +566,23 @@ func GetSubnetRangesString() string {
return strings.TrimSpace(strB.String())
}
// routeNetworkCIDR normalizes a CIDR string to its network address (host
// bits cleared) for use in `ip route replace <cidr> dev %i` PostUp lines.
// wg's own AllowedIPs/setconf tolerates a CIDR with nonzero host bits (e.g.
// a peer address like 10.66.120.1/30 instead of the network 10.66.120.0/30)
// and just warns, but plain `ip route replace` rejects it outright with
// "Invalid prefix for given prefix length" and aborts the whole wg-quick
// up - taking down the interface over what should be a harmless data-entry
// quirk. Malformed input is passed through unchanged so the resulting
// PostUp line still fails loudly instead of silently mangling an address.
func routeNetworkCIDR(cidr string) string {
_, ipnet, err := net.ParseCIDR(cidr)
if err != nil {
return cidr
}
return ipnet.String()
}
// WriteWireGuardServerConfig to write Wireguard server config. e.g. wg0.conf
func WriteWireGuardServerConfig(tmplDir fs.FS, serverConfig model.Server, clientDataList []model.ClientData, usersList []model.User, globalSettings model.GlobalSetting) error {
var tmplWireguardConf string
@@ -596,7 +613,9 @@ func WriteWireGuardServerConfig(tmplDir fs.FS, serverConfig model.Server, client
}
// parse the template
t, err := template.New("wg_config").Parse(tmplWireguardConf)
t, err := template.New("wg_config").Funcs(template.FuncMap{
"routeNet": routeNetworkCIDR,
}).Parse(tmplWireguardConf)
if err != nil {
return err
}