mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-16 18:08:40 +00:00
ipn/ipnlocal: refresh node key without blocking if cap enabled (#10529)
Updates tailscale/corp#16016 Signed-off-by: James Sanderson <jsanderson@tailscale.com> Co-authored-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
parent
3a9450bc06
commit
10c595d962
@ -64,6 +64,11 @@ type Knobs struct {
|
||||
// LinuxForceNfTables is whether the node should use nftables for Linux
|
||||
// netfiltering, unless overridden by the user.
|
||||
LinuxForceNfTables atomic.Bool
|
||||
|
||||
// SeamlessKeyRenewal is whether to enable the alpha functionality of
|
||||
// renewing node keys without breaking connections.
|
||||
// http://go/seamless-key-renewal
|
||||
SeamlessKeyRenewal atomic.Bool
|
||||
}
|
||||
|
||||
// UpdateFromNodeAttributes updates k (if non-nil) based on the provided self
|
||||
@ -89,6 +94,7 @@ func (k *Knobs) UpdateFromNodeAttributes(selfNodeAttrs []tailcfg.NodeCapability,
|
||||
silentDisco = has(tailcfg.NodeAttrSilentDisco)
|
||||
forceIPTables = has(tailcfg.NodeAttrLinuxMustUseIPTables)
|
||||
forceNfTables = has(tailcfg.NodeAttrLinuxMustUseNfTables)
|
||||
seamlessKeyRenewal = has(tailcfg.NodeAttrSeamlessKeyRenewal)
|
||||
)
|
||||
|
||||
if has(tailcfg.NodeAttrOneCGNATEnable) {
|
||||
@ -109,6 +115,7 @@ func (k *Knobs) UpdateFromNodeAttributes(selfNodeAttrs []tailcfg.NodeCapability,
|
||||
k.SilentDisco.Store(silentDisco)
|
||||
k.LinuxForceIPTables.Store(forceIPTables)
|
||||
k.LinuxForceNfTables.Store(forceNfTables)
|
||||
k.SeamlessKeyRenewal.Store(seamlessKeyRenewal)
|
||||
}
|
||||
|
||||
// AsDebugJSON returns k as something that can be marshalled with json.Marshal
|
||||
@ -130,5 +137,6 @@ func (k *Knobs) AsDebugJSON() map[string]any {
|
||||
"SilentDisco": k.SilentDisco.Load(),
|
||||
"LinuxForceIPTables": k.LinuxForceIPTables.Load(),
|
||||
"LinuxForceNfTables": k.LinuxForceNfTables.Load(),
|
||||
"SeamlessKeyRenewal": k.SeamlessKeyRenewal.Load(),
|
||||
}
|
||||
}
|
||||
|
@ -1074,9 +1074,11 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control
|
||||
b.blockEngineUpdates(false)
|
||||
}
|
||||
|
||||
if st.LoginFinished() && wasBlocked {
|
||||
// Auth completed, unblock the engine
|
||||
b.blockEngineUpdates(false)
|
||||
if st.LoginFinished() && (wasBlocked || b.seamlessRenewalEnabled()) {
|
||||
if wasBlocked {
|
||||
// Auth completed, unblock the engine
|
||||
b.blockEngineUpdates(false)
|
||||
}
|
||||
b.authReconfig()
|
||||
b.send(ipn.Notify{LoginFinished: &empty.Message{}})
|
||||
}
|
||||
@ -1108,7 +1110,7 @@ func (b *LocalBackend) SetControlClientStatus(c controlclient.Client, st control
|
||||
b.authURL = st.URL
|
||||
b.authURLSticky = st.URL
|
||||
}
|
||||
if wasBlocked && st.LoginFinished() {
|
||||
if (wasBlocked || b.seamlessRenewalEnabled()) && st.LoginFinished() {
|
||||
// Interactive login finished successfully (URL visited).
|
||||
// After an interactive login, the user always wants
|
||||
// WantRunning.
|
||||
@ -2456,8 +2458,10 @@ func (b *LocalBackend) popBrowserAuthNow() {
|
||||
|
||||
b.logf("popBrowserAuthNow: url=%v", url != "")
|
||||
|
||||
b.blockEngineUpdates(true)
|
||||
b.stopEngineAndWait()
|
||||
if !b.seamlessRenewalEnabled() {
|
||||
b.blockEngineUpdates(true)
|
||||
b.stopEngineAndWait()
|
||||
}
|
||||
b.tellClientToBrowseToURL(url)
|
||||
if b.State() == ipn.Running {
|
||||
b.enterState(ipn.Starting)
|
||||
@ -4176,6 +4180,9 @@ func (b *LocalBackend) enterStateLockedOnEntry(newState ipn.State) {
|
||||
switch newState {
|
||||
case ipn.NeedsLogin:
|
||||
systemd.Status("Needs login: %s", authURL)
|
||||
if b.seamlessRenewalEnabled() {
|
||||
break
|
||||
}
|
||||
b.blockEngineUpdates(true)
|
||||
fallthrough
|
||||
case ipn.Stopped:
|
||||
@ -5801,6 +5808,14 @@ func (b *LocalBackend) AdvertiseRoute(ipp netip.Prefix) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// seamlessRenewalEnabled reports whether seamless key renewals are enabled
|
||||
// (i.e. we saw our self node with the SeamlessKeyRenewal attr in a netmap).
|
||||
// This enables beta functionality of renewing node keys without breaking
|
||||
// connections.
|
||||
func (b *LocalBackend) seamlessRenewalEnabled() bool {
|
||||
return b.ControlKnobs().SeamlessKeyRenewal.Load()
|
||||
}
|
||||
|
||||
var (
|
||||
disallowedAddrs = []netip.Addr{
|
||||
netip.MustParseAddr("::1"),
|
||||
|
@ -124,7 +124,8 @@ type CapabilityVersion int
|
||||
// - 81: 2023-11-17: MapResponse.PacketFilters (incremental packet filter updates)
|
||||
// - 82: 2023-12-01: Client understands NodeAttrLinuxMustUseIPTables, NodeAttrLinuxMustUseNfTables, c2n /netfilter-kind
|
||||
// - 83: 2023-12-18: Client understands DefaultAutoUpdate
|
||||
const CurrentCapabilityVersion CapabilityVersion = 83
|
||||
// - 84: 2024-01-04: Client understands SeamlessKeyRenewal
|
||||
const CurrentCapabilityVersion CapabilityVersion = 84
|
||||
|
||||
type StableID string
|
||||
|
||||
@ -2190,6 +2191,10 @@ const (
|
||||
// netfilter management.
|
||||
// This cannot be set simultaneously with NodeAttrLinuxMustUseIPTables.
|
||||
NodeAttrLinuxMustUseNfTables NodeCapability = "linux-netfilter?v=nftables"
|
||||
|
||||
// NodeAttrSeamlessKeyRenewal makes clients enable beta functionality
|
||||
// of renewing node keys without breaking connections.
|
||||
NodeAttrSeamlessKeyRenewal NodeCapability = "seamless-key-renewal"
|
||||
)
|
||||
|
||||
// SetDNSRequest is a request to add a DNS record.
|
||||
|
Loading…
x
Reference in New Issue
Block a user