summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--control/controlclient/map.go19
-rw-r--r--ipn/ipnlocal/local.go19
2 files changed, 25 insertions, 13 deletions
diff --git a/control/controlclient/map.go b/control/controlclient/map.go
index 2468226d1..b3f559a56 100644
--- a/control/controlclient/map.go
+++ b/control/controlclient/map.go
@@ -93,6 +93,16 @@ type mapSession struct {
lastTKAInfo *tailcfg.TKAInfo
lastNetmapSummary string // from NetworkMap.VeryConcise
lastMaxExpiry time.Duration
+
+ // breakPeersForFlowLogs is whether we've detected a situation
+ // that's incompatible with flow logs: the tailnet admin has enabled
+ // network flow logs, but the local machine has been configured to
+ // not log. In this case, to be conservative, we drop all peers
+ // but keep the map poll connection open. This way, the admin can
+ // still get back into the machine later if they first disable flow
+ // logs. But we otherwise disable connectivity over Tailscale.
+ // See https://github.com/tailscale/tailscale/issues/11793
+ breakPeersForFlowLogs bool
}
// newMapSession returns a mostly unconfigured new mapSession.
@@ -181,6 +191,8 @@ func (ms *mapSession) HandleNonKeepAliveMapResponse(ctx context.Context, resp *t
}
}
ms.controlKnobs.UpdateFromNodeAttributes(resp.Node.CapMap)
+
+ ms.breakPeersForFlowLogs = envknob.NoLogsNoSupport() && resp.Node.CapMap.Contains(tailcfg.CapabilityDataPlaneAuditLogs)
}
// Call Node.InitDisplayNames on any changed nodes.
@@ -219,6 +231,9 @@ func (ms *mapSession) HandleNonKeepAliveMapResponse(ctx context.Context, resp *t
}
func (ms *mapSession) tryHandleIncrementally(res *tailcfg.MapResponse) bool {
+ if ms.breakPeersForFlowLogs {
+ return false
+ }
if ms.controlKnobs != nil && ms.controlKnobs.DisableDeltaUpdates.Load() {
return false
}
@@ -805,6 +820,10 @@ func (ms *mapSession) netmap() *netmap.NetworkMap {
MaxKeyDuration: ms.lastMaxExpiry,
}
+ if ms.breakPeersForFlowLogs {
+ nm.Peers = nil
+ }
+
if ms.lastTKAInfo != nil && ms.lastTKAInfo.Head != "" {
if err := nm.TKAHead.UnmarshalText([]byte(ms.lastTKAInfo.Head)); err != nil {
ms.logf("error unmarshalling TKAHead: %v", err)
diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go
index 4c57502aa..f9bb3bb3d 100644
--- a/ipn/ipnlocal/local.go
+++ b/ipn/ipnlocal/local.go
@@ -1013,6 +1013,8 @@ func (b *LocalBackend) peerCapsLocked(src netip.Addr) tailcfg.PeerCapMap {
return nil
}
+var noLogsNoSupportNotifyOnce sync.Once
+
// SetControlClientStatus is the callback invoked by the control client whenever it posts a new status.
// Among other things, this is where we update the netmap, packet filters, DNS and DERP maps.
func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st controlclient.Status) {
@@ -1216,20 +1218,11 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control
if st.NetMap != nil {
if envknob.NoLogsNoSupport() && st.NetMap.HasCap(tailcfg.CapabilityDataPlaneAuditLogs) {
- msg := "tailnet requires logging to be enabled. Remove --no-logs-no-support from tailscaled command line."
+ msg := "tailnet requires logging to be enabled. Remove --no-logs-no-support from the 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, ipn.NetworkProfile{
- MagicDNSName: st.NetMap.MagicDNSSuffix(),
- DomainName: st.NetMap.DomainName(),
- }); err != nil {
- b.logf("Failed to save new controlclient state: %v", err)
- }
- b.mu.Unlock()
- b.send(ipn.Notify{ErrMessage: &msg, Prefs: &p})
+ noLogsNoSupportNotifyOnce.Do(func() {
+ b.send(ipn.Notify{ErrMessage: ptr.To(msg)})
+ })
return
}
if netMap != nil {