mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-12 13:48:01 +00:00
ipn/ipnlocal: better enforce system policies
Previously, policies affected the default prefs for a new profile, but that does not affect existing profiles. This change ensures that policies are applied whenever preferences are loaded or changed, so a CLI or GUI client that does not respect the policies will still be overridden. Exit node IP is dropped from this PR as it was implemented elsewhere in #10172. Fixes tailscale/corp#15585 Change-Id: Ide4c3a4b00a64e43f506fa1fab70ef591407663f Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
This commit is contained in:

committed by
Adrian Dewhurst

parent
ac6f671c54
commit
af32d1c120
@@ -1119,6 +1119,9 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control
|
||||
if setExitNodeID(prefs, st.NetMap) {
|
||||
prefsChanged = true
|
||||
}
|
||||
if applySysPolicy(prefs) {
|
||||
prefsChanged = true
|
||||
}
|
||||
|
||||
// Until recently, we did not store the account's tailnet name. So check if this is the case,
|
||||
// and backfill it on incoming status update.
|
||||
@@ -1227,6 +1230,35 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control
|
||||
b.authReconfig()
|
||||
}
|
||||
|
||||
// applySysPolicy overwrites configured preferences with policies that may be
|
||||
// configured by the system administrator in an OS-specific way.
|
||||
func applySysPolicy(prefs *ipn.Prefs) (anyChange bool) {
|
||||
if controlURL, err := syspolicy.GetString(syspolicy.ControlURL, prefs.ControlURL); err == nil && prefs.ControlURL != controlURL {
|
||||
prefs.ControlURL = controlURL
|
||||
anyChange = true
|
||||
}
|
||||
|
||||
// Allow Incoming (used by the UI) is the negation of ShieldsUp (used by the
|
||||
// backend), so this has to convert between the two conventions.
|
||||
if shieldsUp, err := syspolicy.GetPreferenceOption(syspolicy.EnableIncomingConnections); err == nil {
|
||||
newVal := !shieldsUp.ShouldEnable(!prefs.ShieldsUp)
|
||||
if prefs.ShieldsUp != newVal {
|
||||
prefs.ShieldsUp = newVal
|
||||
anyChange = true
|
||||
}
|
||||
}
|
||||
|
||||
if forceDaemon, err := syspolicy.GetPreferenceOption(syspolicy.EnableServerMode); err == nil {
|
||||
newVal := forceDaemon.ShouldEnable(prefs.ForceDaemon)
|
||||
if prefs.ForceDaemon != newVal {
|
||||
prefs.ForceDaemon = newVal
|
||||
anyChange = true
|
||||
}
|
||||
}
|
||||
|
||||
return anyChange
|
||||
}
|
||||
|
||||
var _ controlclient.NetmapDeltaUpdater = (*LocalBackend)(nil)
|
||||
|
||||
// UpdateNetmapDelta implements controlclient.NetmapDeltaUpdater.
|
||||
@@ -3051,10 +3083,12 @@ func (b *LocalBackend) setPrefsLockedOnEntry(caller string, newp *ipn.Prefs) ipn
|
||||
if oldp.Valid() {
|
||||
newp.Persist = oldp.Persist().AsStruct() // caller isn't allowed to override this
|
||||
}
|
||||
// findExitNodeIDLocked returns whether it updated b.prefs, but
|
||||
// setExitNodeID returns whether it updated b.prefs, but
|
||||
// everything in this function treats b.prefs as completely new
|
||||
// anyway. No-op if no exit node resolution is needed.
|
||||
setExitNodeID(newp, netMap)
|
||||
// applySysPolicy does likewise so we can also ignore its return value.
|
||||
applySysPolicy(newp)
|
||||
// We do this to avoid holding the lock while doing everything else.
|
||||
|
||||
oldHi := b.hostinfo
|
||||
|
Reference in New Issue
Block a user