summaryrefslogtreecommitdiffhomepage
path: root/control/controlknobs
diff options
context:
space:
mode:
authorAlex Chan <alexc@tailscale.com>2025-09-11 13:11:41 +0100
committerAlex Chan <alex@alexwlchan.net>2025-09-18 09:59:46 +0100
commitcd153aa644dd861602e386e71df20a61733b56a8 (patch)
tree77d45fd2f6b47076766f9104231be4425831a32d /control/controlknobs
parent1c9aaa444da163bf0597cef09a100a4e7a0221b8 (diff)
downloadtailscale-cd153aa644dd861602e386e71df20a61733b56a8.tar.xz
tailscale-cd153aa644dd861602e386e71df20a61733b56a8.zip
control, ipn, tailcfg: enable seamless key renewal by default
Previously, seamless key renewal was an opt-in feature. Customers had to set a `seamless-key-renewal` node attribute in their policy file. This patch enables seamless key renewal by default for all clients. It includes a `disable-seamless-key-renewal` node attribute we can set in Control, so we can manage the rollout and disable the feature for clients with known bugs. This new attribute makes the feature opt-out. Updates tailscale/corp#31479 Signed-off-by: Alex Chan <alexc@tailscale.com>
Diffstat (limited to 'control/controlknobs')
-rw-r--r--control/controlknobs/controlknobs.go22
1 files changed, 19 insertions, 3 deletions
diff --git a/control/controlknobs/controlknobs.go b/control/controlknobs/controlknobs.go
index 2578744ca..09c16b8b1 100644
--- a/control/controlknobs/controlknobs.go
+++ b/control/controlknobs/controlknobs.go
@@ -62,8 +62,9 @@ type Knobs struct {
// netfiltering, unless overridden by the user.
LinuxForceNfTables atomic.Bool
- // SeamlessKeyRenewal is whether to enable the alpha functionality of
- // renewing node keys without breaking connections.
+ // SeamlessKeyRenewal is whether to renew node keys without breaking connections.
+ // This is enabled by default in 1.90 and later, but we but we can remotely disable
+ // it from the control plane if there's a problem.
// http://go/seamless-key-renewal
SeamlessKeyRenewal atomic.Bool
@@ -128,6 +129,7 @@ func (k *Knobs) UpdateFromNodeAttributes(capMap tailcfg.NodeCapMap) {
forceIPTables = has(tailcfg.NodeAttrLinuxMustUseIPTables)
forceNfTables = has(tailcfg.NodeAttrLinuxMustUseNfTables)
seamlessKeyRenewal = has(tailcfg.NodeAttrSeamlessKeyRenewal)
+ disableSeamlessKeyRenewal = has(tailcfg.NodeAttrDisableSeamlessKeyRenewal)
probeUDPLifetime = has(tailcfg.NodeAttrProbeUDPLifetime)
appCStoreRoutes = has(tailcfg.NodeAttrStoreAppCRoutes)
userDialUseRoutes = has(tailcfg.NodeAttrUserDialUseRoutes)
@@ -154,7 +156,6 @@ func (k *Knobs) UpdateFromNodeAttributes(capMap tailcfg.NodeCapMap) {
k.SilentDisco.Store(silentDisco)
k.LinuxForceIPTables.Store(forceIPTables)
k.LinuxForceNfTables.Store(forceNfTables)
- k.SeamlessKeyRenewal.Store(seamlessKeyRenewal)
k.ProbeUDPLifetime.Store(probeUDPLifetime)
k.AppCStoreRoutes.Store(appCStoreRoutes)
k.UserDialUseRoutes.Store(userDialUseRoutes)
@@ -162,6 +163,21 @@ func (k *Knobs) UpdateFromNodeAttributes(capMap tailcfg.NodeCapMap) {
k.DisableLocalDNSOverrideViaNRPT.Store(disableLocalDNSOverrideViaNRPT)
k.DisableCaptivePortalDetection.Store(disableCaptivePortalDetection)
k.DisableSkipStatusQueue.Store(disableSkipStatusQueue)
+
+ // If both attributes are present, then "enable" should win. This reflects
+ // the history of seamless key renewal.
+ //
+ // Before 1.90, seamless was a private alpha, opt-in feature. Devices would
+ // only seamless do if customers opted in using the seamless renewal attr.
+ //
+ // In 1.90 and later, seamless is the default behaviour, and devices will use
+ // seamless unless explicitly told not to by control (e.g. if we discover
+ // a bug and want clients to use the prior behaviour).
+ //
+ // If a customer has opted in to the pre-1.90 seamless implementation, we
+ // don't want to switch it off for them -- we only want to switch it off for
+ // devices that haven't opted in.
+ k.SeamlessKeyRenewal.Store(seamlessKeyRenewal || !disableSeamlessKeyRenewal)
}
// AsDebugJSON returns k as something that can be marshalled with json.Marshal