Просмотр исходного кода

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 <[email protected]>
Aaron Klotz 3 лет назад
Родитель
Сommit
659e7837c6
2 измененных файлов с 27 добавлено и 0 удалено
  1. 11 0
      health/health.go
  2. 16 0
      ipn/ipnlocal/local.go

+ 11 - 0
health/health.go

@@ -48,6 +48,7 @@ var (
 	udp4Unbound             bool
 	controlHealth           []string
 	lastLoginErr            error
+	localLogConfigErr       error
 )
 
 // 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.
 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) {
 	mu.Lock()
 	defer mu.Unlock()
@@ -397,6 +405,9 @@ func overallErrorLocked() error {
 	if !anyInterfaceUp {
 		return errors.New("network down")
 	}
+	if localLogConfigErr != nil {
+		return localLogConfigErr
+	}
 	if !ipnWantRunning {
 		return fmt.Errorf("state=%v, wantRunning=%v", ipnState, ipnWantRunning)
 	}

+ 16 - 0
ipn/ipnlocal/local.go

@@ -908,6 +908,21 @@ func (b *LocalBackend) setClientStatus(st controlclient.Status) {
 	}
 
 	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 {
 			diff := st.NetMap.ConciseDiffFrom(netMap)
 			if strings.TrimSpace(diff) == "" {
@@ -4418,6 +4433,7 @@ func (b *LocalBackend) resetForProfileChangeLockedOnEntry() error {
 	b.lastServeConfJSON = mem.B(nil)
 	b.serveConfig = ipn.ServeConfigView{}
 	b.enterStateLockedOnEntry(ipn.NoState) // Reset state.
+	health.SetLocalLogConfigHealth(nil)
 	return b.Start(ipn.Options{})
 }