ipn/ipnlocal: unconfigure wgengine when switching profiles

LocalBackend transitions to ipn.NoState when switching to a different (or new) profile.
When this happens, we should unconfigure wgengine to clear routes, DNS configuration,
firewall rules that block all traffic except to the exit node, etc.

In this PR, we update (*LocalBackend).enterStateLockedOnEntry to do just that.

Fixes #15316
Updates tailscale/corp#23967

Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
Nick Khyl
2025-03-14 15:17:26 -05:00
committed by Nick Khyl
parent a8c3490614
commit 272854df41
3 changed files with 494 additions and 12 deletions
+4 -4
View File
@@ -5707,13 +5707,15 @@ func (b *LocalBackend) enterStateLockedOnEntry(newState ipn.State, unlock unlock
}
b.blockEngineUpdates(true)
fallthrough
case ipn.Stopped:
case ipn.Stopped, ipn.NoState:
// Unconfigure the engine if it has stopped (WantRunning is set to false)
// or if we've switched to a different profile and the state is unknown.
err := b.e.Reconfig(&wgcfg.Config{}, &router.Config{}, &dns.Config{})
if err != nil {
b.logf("Reconfig(down): %v", err)
}
if authURL == "" {
if newState == ipn.Stopped && authURL == "" {
systemd.Status("Stopped; run 'tailscale up' to log in")
}
case ipn.Starting, ipn.NeedsMachineAuth:
@@ -5727,8 +5729,6 @@ func (b *LocalBackend) enterStateLockedOnEntry(newState ipn.State, unlock unlock
addrStrs = append(addrStrs, p.Addr().String())
}
systemd.Status("Connected; %s; %s", activeLogin, strings.Join(addrStrs, " "))
case ipn.NoState:
// Do nothing.
default:
b.logf("[unexpected] unknown newState %#v", newState)
}