From e158c90e34dcc27ed10f36dfd9ea599df93d7f7f Mon Sep 17 00:00:00 2001 From: Owen Date: Wed, 1 Jul 2026 15:34:12 -0400 Subject: [PATCH] Add the remote subnets to the sync --- newt/data.go | 5 +++++ newt/handlers.go | 50 +---------------------------------------- newt/tunnel.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ newt/types.go | 5 +++-- 4 files changed, 67 insertions(+), 51 deletions(-) diff --git a/newt/data.go b/newt/data.go index 807f202..311f7da 100644 --- a/newt/data.go +++ b/newt/data.go @@ -137,6 +137,11 @@ func (n *Newt) handleSync(msg websocket.WSMessage) { } } + // Sync remote exit node subnets + if n.dev != nil { + n.updateRemoteExitNodeSubnets(syncData.RemoteExitNodeSubnets) + } + // Sync health check targets if err := n.healthMonitor.SyncTargets(syncData.HealthCheckTargets); err != nil { logger.Error("Failed to sync health check targets: %v", err) diff --git a/newt/handlers.go b/newt/handlers.go index fb97ab4..b679a2f 100644 --- a/newt/handlers.go +++ b/newt/handlers.go @@ -405,55 +405,7 @@ func (n *Newt) registerHandlers(ctx context.Context) { return } - if n.config.UseNativeMainInterface && len(n.activeRemoteSubnets) > 0 { - toRemove := make([]string, 0) - newSet := make(map[string]bool, len(data.Subnets)) - for _, s := range data.Subnets { - newSet[s] = true - } - for _, s := range n.activeRemoteSubnets { - if !newSet[s] { - toRemove = append(toRemove, s) - } - } - if len(toRemove) > 0 { - if err := network.RemoveRoutes(toRemove); err != nil { - logger.Warn("Failed to remove old subnet routes: %v", err) - } - } - } - - if n.wgData.PublicKey != "" { - lines := fmt.Sprintf("public_key=%s\nreplace_allowed_ips=true\nallowed_ip=%s/32", - util.FixKey(n.wgData.PublicKey), n.wgData.ServerIP) - for _, s := range data.Subnets { - lines += "\nallowed_ip=" + s - } - if err := n.dev.IpcSet(lines); err != nil { - logger.Warn("Failed to update WireGuard AllowedIPs: %v", err) - } - } - - if n.config.UseNativeMainInterface && len(data.Subnets) > 0 { - existing := make(map[string]bool, len(n.activeRemoteSubnets)) - for _, s := range n.activeRemoteSubnets { - existing[s] = true - } - toAdd := make([]string, 0) - for _, s := range data.Subnets { - if !existing[s] { - toAdd = append(toAdd, s) - } - } - if len(toAdd) > 0 { - if err := network.AddRoutes(toAdd, n.config.NativeMainInterfaceName); err != nil { - logger.Warn("Failed to add new subnet routes: %v", err) - } - } - } - - n.activeRemoteSubnets = append([]string{}, data.Subnets...) - logger.Info("Updated remote exit node subnets: %d total", len(data.Subnets)) + n.updateRemoteExitNodeSubnets(data.Subnets) }) n.client.RegisterHandler("newt/wg/subnets/remove", func(msg websocket.WSMessage) { diff --git a/newt/tunnel.go b/newt/tunnel.go index 521d0cb..b396cce 100644 --- a/newt/tunnel.go +++ b/newt/tunnel.go @@ -1,10 +1,68 @@ package newt import ( + "fmt" + "github.com/fosrl/newt/logger" "github.com/fosrl/newt/network" + "github.com/fosrl/newt/util" ) +// updateRemoteExitNodeSubnets replaces the set of active remote exit node +// subnets with the given list, updating WireGuard AllowedIPs and native +// routes to match. +func (n *Newt) updateRemoteExitNodeSubnets(subnets []string) { + if n.config.UseNativeMainInterface && len(n.activeRemoteSubnets) > 0 { + toRemove := make([]string, 0) + newSet := make(map[string]bool, len(subnets)) + for _, s := range subnets { + newSet[s] = true + } + for _, s := range n.activeRemoteSubnets { + if !newSet[s] { + toRemove = append(toRemove, s) + } + } + if len(toRemove) > 0 { + if err := network.RemoveRoutes(toRemove); err != nil { + logger.Warn("Failed to remove old subnet routes: %v", err) + } + } + } + + if n.dev != nil && n.wgData.PublicKey != "" { + lines := fmt.Sprintf("public_key=%s\nreplace_allowed_ips=true\nallowed_ip=%s/32", + util.FixKey(n.wgData.PublicKey), n.wgData.ServerIP) + for _, s := range subnets { + lines += "\nallowed_ip=" + s + } + if err := n.dev.IpcSet(lines); err != nil { + logger.Warn("Failed to update WireGuard AllowedIPs: %v", err) + } + } + + if n.config.UseNativeMainInterface && len(subnets) > 0 { + existing := make(map[string]bool, len(n.activeRemoteSubnets)) + for _, s := range n.activeRemoteSubnets { + existing[s] = true + } + toAdd := make([]string, 0) + for _, s := range subnets { + if !existing[s] { + toAdd = append(toAdd, s) + } + } + if len(toAdd) > 0 { + if err := network.AddRoutes(toAdd, n.config.NativeMainInterfaceName); err != nil { + logger.Warn("Failed to add new subnet routes: %v", err) + } + } + } + + n.activeRemoteSubnets = append([]string{}, subnets...) + logger.Info("Updated remote exit node subnets: %d total", len(subnets)) +} + func (n *Newt) closeWgTunnel() { if n.pingStopChan != nil { close(n.pingStopChan) diff --git a/newt/types.go b/newt/types.go index b69ac4b..d2ff65c 100644 --- a/newt/types.go +++ b/newt/types.go @@ -62,6 +62,7 @@ type BlueprintResult struct { // Define the sync data structure type SyncData struct { - Targets TargetsByType `json:"targets"` - HealthCheckTargets []healthcheck.Config `json:"healthCheckTargets"` + Targets TargetsByType `json:"targets"` + HealthCheckTargets []healthcheck.Config `json:"healthCheckTargets"` + RemoteExitNodeSubnets []string `json:"remoteExitNodeSubnets"` }