net/dns: make MagicDNS IPv6 registration opt-out now, not opt-in
This adds a new ControlKnob to make MagicDNS IPv6 registration (telling systemd/etc) opt-out rather than opt-in. Updates #15404 Change-Id: If008e1cb046b792c6aff7bb1d7c58638f7d650b1 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
a6390ca008
commit
a7a864419d
@@ -113,6 +113,14 @@ type Knobs struct {
|
|||||||
// resolver on Windows or when the host is domain-joined and its primary domain
|
// resolver on Windows or when the host is domain-joined and its primary domain
|
||||||
// takes precedence over MagicDNS. As of 2026-02-13, it is only used on Windows.
|
// takes precedence over MagicDNS. As of 2026-02-13, it is only used on Windows.
|
||||||
DisableHostsFileUpdates atomic.Bool
|
DisableHostsFileUpdates atomic.Bool
|
||||||
|
|
||||||
|
// ForceRegisterMagicDNSIPv4Only is whether the node should only register
|
||||||
|
// its IPv4 MagicDNS service IP and not its IPv6 one. The IPv6 one,
|
||||||
|
// tsaddr.TailscaleServiceIPv6String, still works in either case. This knob
|
||||||
|
// controls only whether we tell systemd/etc about the IPv6 one.
|
||||||
|
// See https://github.com/tailscale/tailscale/issues/15404.
|
||||||
|
// TODO(bradfitz): remove this a few releases after 2026-02-16.
|
||||||
|
ForceRegisterMagicDNSIPv4Only atomic.Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateFromNodeAttributes updates k (if non-nil) based on the provided self
|
// UpdateFromNodeAttributes updates k (if non-nil) based on the provided self
|
||||||
@@ -144,6 +152,7 @@ func (k *Knobs) UpdateFromNodeAttributes(capMap tailcfg.NodeCapMap) {
|
|||||||
disableCaptivePortalDetection = has(tailcfg.NodeAttrDisableCaptivePortalDetection)
|
disableCaptivePortalDetection = has(tailcfg.NodeAttrDisableCaptivePortalDetection)
|
||||||
disableSkipStatusQueue = has(tailcfg.NodeAttrDisableSkipStatusQueue)
|
disableSkipStatusQueue = has(tailcfg.NodeAttrDisableSkipStatusQueue)
|
||||||
disableHostsFileUpdates = has(tailcfg.NodeAttrDisableHostsFileUpdates)
|
disableHostsFileUpdates = has(tailcfg.NodeAttrDisableHostsFileUpdates)
|
||||||
|
forceRegisterMagicDNSIPv4Only = has(tailcfg.NodeAttrForceRegisterMagicDNSIPv4Only)
|
||||||
)
|
)
|
||||||
|
|
||||||
if has(tailcfg.NodeAttrOneCGNATEnable) {
|
if has(tailcfg.NodeAttrOneCGNATEnable) {
|
||||||
@@ -171,6 +180,7 @@ func (k *Knobs) UpdateFromNodeAttributes(capMap tailcfg.NodeCapMap) {
|
|||||||
k.DisableCaptivePortalDetection.Store(disableCaptivePortalDetection)
|
k.DisableCaptivePortalDetection.Store(disableCaptivePortalDetection)
|
||||||
k.DisableSkipStatusQueue.Store(disableSkipStatusQueue)
|
k.DisableSkipStatusQueue.Store(disableSkipStatusQueue)
|
||||||
k.DisableHostsFileUpdates.Store(disableHostsFileUpdates)
|
k.DisableHostsFileUpdates.Store(disableHostsFileUpdates)
|
||||||
|
k.ForceRegisterMagicDNSIPv4Only.Store(forceRegisterMagicDNSIPv4Only)
|
||||||
|
|
||||||
// If both attributes are present, then "enable" should win. This reflects
|
// If both attributes are present, then "enable" should win. This reflects
|
||||||
// the history of seamless key renewal.
|
// the history of seamless key renewal.
|
||||||
@@ -210,3 +220,9 @@ func (k *Knobs) AsDebugJSON() map[string]any {
|
|||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShouldForceRegisterMagicDNSIPv4Only reports the value of
|
||||||
|
// ForceRegisterMagicDNSIPv4Only, or false if k is nil.
|
||||||
|
func (k *Knobs) ShouldForceRegisterMagicDNSIPv4Only() bool {
|
||||||
|
return k != nil && k.ForceRegisterMagicDNSIPv4Only.Load()
|
||||||
|
}
|
||||||
|
|||||||
+3
-5
@@ -73,11 +73,9 @@ func (c *Config) serviceIPs(knobs *controlknobs.Knobs) []netip.Addr {
|
|||||||
return []netip.Addr{tsaddr.TailscaleServiceIPv6()}
|
return []netip.Addr{tsaddr.TailscaleServiceIPv6()}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bradfitz,mikeodr,raggi): include IPv6 here too; tailscale/tailscale#15404
|
// See https://github.com/tailscale/tailscale/issues/15404 for the background
|
||||||
// And add a controlknobs knob to disable dual stack.
|
// on the opt-in debug knob and the controlknob opt-out.
|
||||||
//
|
if magicDNSDualStack() || !knobs.ShouldForceRegisterMagicDNSIPv4Only() {
|
||||||
// For now, opt-in for testing.
|
|
||||||
if magicDNSDualStack() {
|
|
||||||
return []netip.Addr{
|
return []netip.Addr{
|
||||||
tsaddr.TailscaleServiceIP(),
|
tsaddr.TailscaleServiceIP(),
|
||||||
tsaddr.TailscaleServiceIPv6(),
|
tsaddr.TailscaleServiceIPv6(),
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
dns "golang.org/x/net/dns/dnsmessage"
|
dns "golang.org/x/net/dns/dnsmessage"
|
||||||
|
"tailscale.com/control/controlknobs"
|
||||||
"tailscale.com/health"
|
"tailscale.com/health"
|
||||||
"tailscale.com/net/netmon"
|
"tailscale.com/net/netmon"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
@@ -93,7 +94,8 @@ func TestDNSOverTCP(t *testing.T) {
|
|||||||
bus := eventbustest.NewBus(t)
|
bus := eventbustest.NewBus(t)
|
||||||
dialer := tsdial.NewDialer(netmon.NewStatic())
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
dialer.SetBus(bus)
|
dialer.SetBus(bus)
|
||||||
m := NewManager(t.Logf, &f, health.NewTracker(bus), dialer, nil, nil, "", bus)
|
cknobs := &controlknobs.Knobs{}
|
||||||
|
m := NewManager(t.Logf, &f, health.NewTracker(bus), dialer, nil, cknobs, "", bus)
|
||||||
m.resolver.TestOnlySetHook(f.SetResolver)
|
m.resolver.TestOnlySetHook(f.SetResolver)
|
||||||
m.Set(Config{
|
m.Set(Config{
|
||||||
Hosts: hosts(
|
Hosts: hosts(
|
||||||
|
|||||||
+61
-27
@@ -28,6 +28,7 @@ import (
|
|||||||
"tailscale.com/net/dns/publicdns"
|
"tailscale.com/net/dns/publicdns"
|
||||||
"tailscale.com/net/dns/resolver"
|
"tailscale.com/net/dns/resolver"
|
||||||
"tailscale.com/net/netmon"
|
"tailscale.com/net/netmon"
|
||||||
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
"tailscale.com/tstest"
|
"tailscale.com/tstest"
|
||||||
"tailscale.com/types/dnstype"
|
"tailscale.com/types/dnstype"
|
||||||
@@ -172,6 +173,8 @@ func TestCompileHostEntries(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var serviceAddr46 = []netip.Addr{tsaddr.TailscaleServiceIP(), tsaddr.TailscaleServiceIPv6()}
|
||||||
|
|
||||||
func TestManager(t *testing.T) {
|
func TestManager(t *testing.T) {
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
t.Skipf("test's assumptions break because of https://github.com/tailscale/corp/issues/1662")
|
t.Skipf("test's assumptions break because of https://github.com/tailscale/corp/issues/1662")
|
||||||
@@ -189,6 +192,7 @@ func TestManager(t *testing.T) {
|
|||||||
split bool
|
split bool
|
||||||
bs OSConfig
|
bs OSConfig
|
||||||
os OSConfig
|
os OSConfig
|
||||||
|
knobs *controlknobs.Knobs
|
||||||
rs resolver.Config
|
rs resolver.Config
|
||||||
goos string // empty means "linux"
|
goos string // empty means "linux"
|
||||||
}{
|
}{
|
||||||
@@ -231,7 +235,7 @@ func TestManager(t *testing.T) {
|
|||||||
"bar.tld.", "2.3.4.5"),
|
"bar.tld.", "2.3.4.5"),
|
||||||
},
|
},
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
Hosts: hosts(
|
Hosts: hosts(
|
||||||
@@ -317,7 +321,7 @@ func TestManager(t *testing.T) {
|
|||||||
"bradfitz.ts.com.", "2.3.4.5"),
|
"bradfitz.ts.com.", "2.3.4.5"),
|
||||||
},
|
},
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -340,7 +344,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: true,
|
split: true,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -359,7 +363,7 @@ func TestManager(t *testing.T) {
|
|||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -377,7 +381,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: true,
|
split: true,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -386,6 +390,33 @@ func TestManager(t *testing.T) {
|
|||||||
"corp.com.", "2.2.2.2"),
|
"corp.com.", "2.2.2.2"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "controlknob-disable-v6-registration",
|
||||||
|
in: Config{
|
||||||
|
DefaultResolvers: mustRes("1.1.1.1", "9.9.9.9"),
|
||||||
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
|
Routes: upstreams("ts.com", ""),
|
||||||
|
Hosts: hosts(
|
||||||
|
"dave.ts.com.", "1.2.3.4",
|
||||||
|
"bradfitz.ts.com.", "2.3.4.5"),
|
||||||
|
},
|
||||||
|
knobs: (func() *controlknobs.Knobs {
|
||||||
|
k := new(controlknobs.Knobs)
|
||||||
|
k.ForceRegisterMagicDNSIPv4Only.Store(true)
|
||||||
|
return k
|
||||||
|
})(),
|
||||||
|
os: OSConfig{
|
||||||
|
Nameservers: mustIPs("100.100.100.100"), // without IPv6
|
||||||
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
|
},
|
||||||
|
rs: resolver.Config{
|
||||||
|
Routes: upstreams(".", "1.1.1.1", "9.9.9.9"),
|
||||||
|
Hosts: hosts(
|
||||||
|
"dave.ts.com.", "1.2.3.4",
|
||||||
|
"bradfitz.ts.com.", "2.3.4.5"),
|
||||||
|
LocalDomains: fqdns("ts.com."),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "routes",
|
name: "routes",
|
||||||
in: Config{
|
in: Config{
|
||||||
@@ -397,7 +428,7 @@ func TestManager(t *testing.T) {
|
|||||||
SearchDomains: fqdns("coffee.shop"),
|
SearchDomains: fqdns("coffee.shop"),
|
||||||
},
|
},
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf", "coffee.shop"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf", "coffee.shop"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -432,7 +463,7 @@ func TestManager(t *testing.T) {
|
|||||||
SearchDomains: fqdns("coffee.shop"),
|
SearchDomains: fqdns("coffee.shop"),
|
||||||
},
|
},
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf", "coffee.shop"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf", "coffee.shop"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -452,7 +483,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: true,
|
split: true,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
MatchDomains: fqdns("bigco.net", "corp.com"),
|
MatchDomains: fqdns("bigco.net", "corp.com"),
|
||||||
},
|
},
|
||||||
@@ -477,7 +508,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: false,
|
split: false,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -502,7 +533,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: false,
|
split: false,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -527,7 +558,7 @@ func TestManager(t *testing.T) {
|
|||||||
SearchDomains: fqdns("coffee.shop"),
|
SearchDomains: fqdns("coffee.shop"),
|
||||||
},
|
},
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf", "coffee.shop"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf", "coffee.shop"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -549,7 +580,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: true,
|
split: true,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
MatchDomains: fqdns("ts.com"),
|
MatchDomains: fqdns("ts.com"),
|
||||||
},
|
},
|
||||||
@@ -575,7 +606,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: false,
|
split: false,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -601,7 +632,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: false,
|
split: false,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -627,7 +658,7 @@ func TestManager(t *testing.T) {
|
|||||||
SearchDomains: fqdns("coffee.shop"),
|
SearchDomains: fqdns("coffee.shop"),
|
||||||
},
|
},
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf", "coffee.shop"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf", "coffee.shop"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -653,7 +684,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: true,
|
split: true,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
MatchDomains: fqdns("corp.com", "ts.com"),
|
MatchDomains: fqdns("corp.com", "ts.com"),
|
||||||
},
|
},
|
||||||
@@ -683,7 +714,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: true,
|
split: true,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -715,7 +746,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: true,
|
split: true,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -740,7 +771,7 @@ func TestManager(t *testing.T) {
|
|||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
SearchDomains: fqdns("tailscale.com", "universe.tf"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -768,7 +799,7 @@ func TestManager(t *testing.T) {
|
|||||||
DefaultResolvers: mustRes("2a07:a8c0::c3:a884"),
|
DefaultResolvers: mustRes("2a07:a8c0::c3:a884"),
|
||||||
},
|
},
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
Routes: upstreams(".", "2a07:a8c0::c3:a884"),
|
Routes: upstreams(".", "2a07:a8c0::c3:a884"),
|
||||||
@@ -780,7 +811,7 @@ func TestManager(t *testing.T) {
|
|||||||
DefaultResolvers: mustRes("https://dns.nextdns.io/c3a884"),
|
DefaultResolvers: mustRes("https://dns.nextdns.io/c3a884"),
|
||||||
},
|
},
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
Routes: upstreams(".", "https://dns.nextdns.io/c3a884"),
|
Routes: upstreams(".", "https://dns.nextdns.io/c3a884"),
|
||||||
@@ -796,7 +827,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: true,
|
split: true,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("optimistic-display.ts.net"),
|
SearchDomains: fqdns("optimistic-display.ts.net"),
|
||||||
MatchDomains: fqdns("ts.net"),
|
MatchDomains: fqdns("ts.net"),
|
||||||
},
|
},
|
||||||
@@ -821,7 +852,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: true,
|
split: true,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("optimistic-display.ts.net"),
|
SearchDomains: fqdns("optimistic-display.ts.net"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -844,7 +875,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: true,
|
split: true,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("optimistic-display.ts.net"),
|
SearchDomains: fqdns("optimistic-display.ts.net"),
|
||||||
},
|
},
|
||||||
rs: resolver.Config{
|
rs: resolver.Config{
|
||||||
@@ -885,7 +916,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("ts.com", "universe.tf"),
|
SearchDomains: fqdns("ts.com", "universe.tf"),
|
||||||
MatchDomains: fqdns("corp.com", "ts.com"),
|
MatchDomains: fqdns("corp.com", "ts.com"),
|
||||||
},
|
},
|
||||||
@@ -912,7 +943,7 @@ func TestManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
split: true,
|
split: true,
|
||||||
os: OSConfig{
|
os: OSConfig{
|
||||||
Nameservers: mustIPs("100.100.100.100"),
|
Nameservers: serviceAddr46,
|
||||||
SearchDomains: fqdns("ts.com", "universe.tf"),
|
SearchDomains: fqdns("ts.com", "universe.tf"),
|
||||||
MatchDomains: fqdns("corp.com", "ts.com"),
|
MatchDomains: fqdns("corp.com", "ts.com"),
|
||||||
},
|
},
|
||||||
@@ -946,7 +977,10 @@ func TestManager(t *testing.T) {
|
|||||||
if goos == "" {
|
if goos == "" {
|
||||||
goos = "linux"
|
goos = "linux"
|
||||||
}
|
}
|
||||||
knobs := &controlknobs.Knobs{}
|
knobs := test.knobs
|
||||||
|
if knobs == nil {
|
||||||
|
knobs = &controlknobs.Knobs{}
|
||||||
|
}
|
||||||
bus := eventbustest.NewBus(t)
|
bus := eventbustest.NewBus(t)
|
||||||
dialer := tsdial.NewDialer(netmon.NewStatic())
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
dialer.SetBus(bus)
|
dialer.SetBus(bus)
|
||||||
|
|||||||
+8
-1
@@ -179,7 +179,8 @@ type CapabilityVersion int
|
|||||||
// - 130: 2025-10-06: client can send key.HardwareAttestationPublic and key.HardwareAttestationKeySignature in MapRequest
|
// - 130: 2025-10-06: client can send key.HardwareAttestationPublic and key.HardwareAttestationKeySignature in MapRequest
|
||||||
// - 131: 2025-11-25: client respects [NodeAttrDefaultAutoUpdate]
|
// - 131: 2025-11-25: client respects [NodeAttrDefaultAutoUpdate]
|
||||||
// - 132: 2026-02-13: client respects [NodeAttrDisableHostsFileUpdates]
|
// - 132: 2026-02-13: client respects [NodeAttrDisableHostsFileUpdates]
|
||||||
const CurrentCapabilityVersion CapabilityVersion = 132
|
// - 133: 2026-02-17: client understands [NodeAttrForceRegisterMagicDNSIPv4Only]; MagicDNS IPv6 registered w/ OS by default
|
||||||
|
const CurrentCapabilityVersion CapabilityVersion = 133
|
||||||
|
|
||||||
// ID is an integer ID for a user, node, or login allocated by the
|
// ID is an integer ID for a user, node, or login allocated by the
|
||||||
// control plane.
|
// control plane.
|
||||||
@@ -2748,6 +2749,12 @@ const (
|
|||||||
// primary domain takes precedence over MagicDNS. As of 2026-02-12, it is only
|
// primary domain takes precedence over MagicDNS. As of 2026-02-12, it is only
|
||||||
// used on Windows.
|
// used on Windows.
|
||||||
NodeAttrDisableHostsFileUpdates NodeCapability = "disable-hosts-file-updates"
|
NodeAttrDisableHostsFileUpdates NodeCapability = "disable-hosts-file-updates"
|
||||||
|
|
||||||
|
// NodeAttrForceRegisterMagicDNSIPv4Only forces the client to only register
|
||||||
|
// its MagicDNS IPv4 address with systemd/etc, and not both its IPv4 and IPv6 addresses.
|
||||||
|
// See https://github.com/tailscale/tailscale/issues/15404.
|
||||||
|
// TODO(bradfitz): remove this a few releases after 2026-02-16.
|
||||||
|
NodeAttrForceRegisterMagicDNSIPv4Only NodeCapability = "force-register-magicdns-ipv4-only"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetDNSRequest is a request to add a DNS record.
|
// SetDNSRequest is a request to add a DNS record.
|
||||||
|
|||||||
Reference in New Issue
Block a user