health, ipn/ipnlocal: when -no-logs-no-support is enabled, deny access to tailnets that have network logging enabled

We want users to have the freedom to start tailscaled with `-no-logs-no-support`,
but that is obviously in direct conflict with tailnets that have network logging
enabled.

When we detect that condition, we record the issue in health, notify the client,
set WantRunning=false, and bail.

We clear the item in health when a profile switch occurs, since it is a
per-tailnet condition that should not propagate across profiles.

Signed-off-by: Aaron Klotz <aaron@tailscale.com>
bradfitz/fix_ipn_cloner
Aaron Klotz 2 years ago
parent ad41cbd9d5
commit 659e7837c6

@ -48,6 +48,7 @@ var (
udp4Unbound bool udp4Unbound bool
controlHealth []string controlHealth []string
lastLoginErr error lastLoginErr error
localLogConfigErr error
) )
// Subsystem is the name of a subsystem whose health can be monitored. // Subsystem is the name of a subsystem whose health can be monitored.
@ -193,6 +194,13 @@ func SetDNSManagerHealth(err error) { setErr(SysDNSManager, err) }
// DNSOSHealth returns the net/dns.OSConfigurator error state. // DNSOSHealth returns the net/dns.OSConfigurator error state.
func DNSOSHealth() error { return get(SysDNSOS) } func DNSOSHealth() error { return get(SysDNSOS) }
// SetLocalLogConfigHealth sets the error state of this client's local log configuration.
func SetLocalLogConfigHealth(err error) {
mu.Lock()
defer mu.Unlock()
localLogConfigErr = err
}
func RegisterDebugHandler(typ string, h http.Handler) { func RegisterDebugHandler(typ string, h http.Handler) {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
@ -397,6 +405,9 @@ func overallErrorLocked() error {
if !anyInterfaceUp { if !anyInterfaceUp {
return errors.New("network down") return errors.New("network down")
} }
if localLogConfigErr != nil {
return localLogConfigErr
}
if !ipnWantRunning { if !ipnWantRunning {
return fmt.Errorf("state=%v, wantRunning=%v", ipnState, ipnWantRunning) return fmt.Errorf("state=%v, wantRunning=%v", ipnState, ipnWantRunning)
} }

@ -908,6 +908,21 @@ func (b *LocalBackend) setClientStatus(st controlclient.Status) {
} }
if st.NetMap != nil { if st.NetMap != nil {
if envknob.NoLogsNoSupport() && hasCapability(st.NetMap, tailcfg.CapabilityDataPlaneAuditLogs) {
msg := "tailnet requires logging to be enabled. Remove -no-logs-no-support from tailscaled command line."
health.SetLocalLogConfigHealth(errors.New(msg))
// Connecting to this tailnet without logging is forbidden; boot us outta here.
b.mu.Lock()
prefs.WantRunning = false
p := prefs.View()
if err := b.pm.SetPrefs(p); err != nil {
b.logf("Failed to save new controlclient state: %v", err)
}
b.mu.Unlock()
np := stripKeysFromPrefs(p)
b.send(ipn.Notify{ErrMessage: &msg, Prefs: &np})
return
}
if netMap != nil { if netMap != nil {
diff := st.NetMap.ConciseDiffFrom(netMap) diff := st.NetMap.ConciseDiffFrom(netMap)
if strings.TrimSpace(diff) == "" { if strings.TrimSpace(diff) == "" {
@ -4418,6 +4433,7 @@ func (b *LocalBackend) resetForProfileChangeLockedOnEntry() error {
b.lastServeConfJSON = mem.B(nil) b.lastServeConfJSON = mem.B(nil)
b.serveConfig = ipn.ServeConfigView{} b.serveConfig = ipn.ServeConfigView{}
b.enterStateLockedOnEntry(ipn.NoState) // Reset state. b.enterStateLockedOnEntry(ipn.NoState) // Reset state.
health.SetLocalLogConfigHealth(nil)
return b.Start(ipn.Options{}) return b.Start(ipn.Options{})
} }

Loading…
Cancel
Save