net/dns: add a local Windows hosts-update control

Allow TS_DEBUG_DISABLE_HOSTS_FILE_UPDATES to opt out of Windows hosts entries locally, using the existing tailscaled-env.txt configuration mechanism. Keep the control-plane node attribute authoritative and preserve upstream behavior when the local option is unset or false.

Cover defaults, local opt-out, nil control knobs, and policy precedence with Windows tests. This change is limited to DNS configuration; no route changes or upstream route-fix cherry-pick are included.

Updates tailscale/tailscale#14327

Signed-off-by: Caleb Crome <caleb.crome@flyzipline.com>
This commit is contained in:
Caleb Crome authored and Nick Khyl committed 2026-10-01 15:37:30 -07:00
1 parent d33279d752
commit 12e898010c
2 files changed
+44 -1

No files matched your search

+38
View File
@@ -0,0 +1,38 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package dns
import (
"testing"
"tailscale.com/control/controlknobs"
"tailscale.com/envknob"
)
func TestDisableHostsFileUpdatesLocal(t *testing.T) {
for _, tt := range []struct {
name, local string
policy, nilKnobs, want bool
}{
{"default", "", false, false, false},
{"local", "true", false, false, true},
{"localWithNilKnobs", "true", false, true, true},
{"defaultWithNilKnobs", "", false, true, false},
{"explicitFalse", "false", false, false, false},
{"policy", "", true, false, true},
{"localFalseCannotOverridePolicy", "false", true, false, true},
} {
t.Run(tt.name, func(t *testing.T) {
envknob.SetenvForTest(t, "TS_DEBUG_DISABLE_HOSTS_FILE_UPDATES", tt.local)
m := &windowsManager{}
if !tt.nilKnobs {
m.knobs = new(controlknobs.Knobs)
m.knobs.DisableHostsFileUpdates.Store(tt.policy)
}
if got := m.disableHostsFileUpdates(); got != tt.want {
t.Errorf("disableHostsFileUpdates() = %v, want %v", got, tt.want)
}
})
}
}
+6 -1
View File
@@ -42,6 +42,11 @@ const (
var configureWSL = envknob.RegisterBool("TS_DEBUG_CONFIGURE_WSL")
// disableHostsFileUpdatesLocal allows local diagnosis of expensive Windows
// DNS Client hosts-file reloads without changing the tailnet policy.
// On Windows, set it in %ProgramData%\Tailscale\tailscaled-env.txt and restart.
var disableHostsFileUpdatesLocal = envknob.RegisterBool("TS_DEBUG_DISABLE_HOSTS_FILE_UPDATES")
type windowsManager struct {
logf logger.Logf
guid string
@@ -396,7 +401,7 @@ func (m *windowsManager) disableLocalDNSOverrideViaNRPT() bool {
}
func (m *windowsManager) disableHostsFileUpdates() bool {
return m.knobs != nil && m.knobs.DisableHostsFileUpdates.Load()
return disableHostsFileUpdatesLocal() || (m.knobs != nil && m.knobs.DisableHostsFileUpdates.Load())
}
func (m *windowsManager) SetDNS(cfg OSConfig) error {