Skip to content

Commit c837a54

Browse files
nblockkradalby
authored andcommitted
Restore support for "Override local DNS"
Tailscale allows to override the local DNS settings of a node via "Override local DNS" [1]. Restore this flag with the same config setting name `dns.override_local_dns` but disable it by default to align it with Tailscale's default behaviour. Tested with Tailscale 1.80.2 and systemd-resolved on Debian 12. With `dns.override_local_dns: false`: ``` Link 12 (tailscale0) Current Scopes: DNS Protocols: -DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported DNS Servers: 100.100.100.100 DNS Domain: tn.example.com ~0.e.1.a.c.5.1.1.a.7.d.f.ip6.arpa [snip] ``` With `dns.override_local_dns: true`: ``` Link 12 (tailscale0) Current Scopes: DNS Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported DNS Servers: 100.100.100.100 DNS Domain: tn.example.com ~. ``` [1] https://tailscale.com/kb/1054/dns#override-local-dns Fixes: #2256
1 parent 0fbe392 commit c837a54

File tree

7 files changed

+24
-4
lines changed

7 files changed

+24
-4
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ The new policy can be used by setting the environment variable
9292
- node FQDNs in the netmap will now contain a dot (".") at the end. This aligns
9393
with behaviour of tailscale.com
9494
[#2503](https://github.com/juanfont/headscale/pull/2503)
95+
- Restore support for "Override local DNS"
96+
[#2438](https://github.com/juanfont/headscale/pull/2438)
9597

9698
## 0.25.1 (2025-02-25)
9799

config-example.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,10 @@ dns:
270270
# `hostname.base_domain` (e.g., _myhost.example.com_).
271271
base_domain: example.com
272272

273+
# Whether to use the local DNS settings of a node (default) or override the
274+
# local DNS settings and force the use of Headscale's DNS configuration.
275+
override_local_dns: false
276+
273277
# List of DNS servers to expose to clients.
274278
nameservers:
275279
global:

hscontrol/types/config.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ type Config struct {
102102
type DNSConfig struct {
103103
MagicDNS bool `mapstructure:"magic_dns"`
104104
BaseDomain string `mapstructure:"base_domain"`
105+
OverrideLocalDNS bool `mapstructure:"override_local_dns"`
105106
Nameservers Nameservers
106107
SearchDomains []string `mapstructure:"search_domains"`
107108
ExtraRecords []tailcfg.DNSRecord `mapstructure:"extra_records"`
@@ -287,6 +288,7 @@ func LoadConfig(path string, isFile bool) error {
287288

288289
viper.SetDefault("dns.magic_dns", true)
289290
viper.SetDefault("dns.base_domain", "")
291+
viper.SetDefault("dns.override_local_dns", false)
290292
viper.SetDefault("dns.nameservers.global", []string{})
291293
viper.SetDefault("dns.nameservers.split", map[string]string{})
292294
viper.SetDefault("dns.search_domains", []string{})
@@ -351,9 +353,9 @@ func validateServerConfig() error {
351353
depr.fatalIfNewKeyIsNotUsed("policy.path", "acl_policy_path")
352354

353355
// Move dns_config -> dns
354-
depr.warn("dns_config.override_local_dns")
355356
depr.fatalIfNewKeyIsNotUsed("dns.magic_dns", "dns_config.magic_dns")
356357
depr.fatalIfNewKeyIsNotUsed("dns.base_domain", "dns_config.base_domain")
358+
depr.fatalIfNewKeyIsNotUsed("dns.override_local_dns", "dns_config.override_local_dns")
357359
depr.fatalIfNewKeyIsNotUsed("dns.nameservers.global", "dns_config.nameservers")
358360
depr.fatalIfNewKeyIsNotUsed("dns.nameservers.split", "dns_config.restricted_nameservers")
359361
depr.fatalIfNewKeyIsNotUsed("dns.search_domains", "dns_config.domains")
@@ -616,6 +618,7 @@ func dns() (DNSConfig, error) {
616618

617619
dns.MagicDNS = viper.GetBool("dns.magic_dns")
618620
dns.BaseDomain = viper.GetString("dns.base_domain")
621+
dns.OverrideLocalDNS = viper.GetBool("dns.override_local_dns")
619622
dns.Nameservers.Global = viper.GetStringSlice("dns.nameservers.global")
620623
dns.Nameservers.Split = viper.GetStringMapStringSlice("dns.nameservers.split")
621624
dns.SearchDomains = viper.GetStringSlice("dns.search_domains")
@@ -721,7 +724,11 @@ func dnsToTailcfgDNS(dns DNSConfig) *tailcfg.DNSConfig {
721724

722725
cfg.Proxied = dns.MagicDNS
723726
cfg.ExtraRecords = dns.ExtraRecords
724-
cfg.Resolvers = dns.globalResolvers()
727+
if dns.OverrideLocalDNS {
728+
cfg.Resolvers = dns.globalResolvers()
729+
} else {
730+
cfg.FallbackResolvers = dns.globalResolvers()
731+
}
725732

726733
routes := dns.splitResolvers()
727734
cfg.Routes = routes

hscontrol/types/config_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ func TestReadConfig(t *testing.T) {
3636
want: DNSConfig{
3737
MagicDNS: true,
3838
BaseDomain: "example.com",
39+
OverrideLocalDNS: false,
3940
Nameservers: Nameservers{
4041
Global: []string{
4142
"1.1.1.1",
@@ -70,7 +71,7 @@ func TestReadConfig(t *testing.T) {
7071
want: &tailcfg.DNSConfig{
7172
Proxied: true,
7273
Domains: []string{"example.com", "test.com", "bar.com"},
73-
Resolvers: []*dnstype.Resolver{
74+
FallbackResolvers: []*dnstype.Resolver{
7475
{Addr: "1.1.1.1"},
7576
{Addr: "1.0.0.1"},
7677
{Addr: "2606:4700:4700::1111"},
@@ -101,6 +102,7 @@ func TestReadConfig(t *testing.T) {
101102
want: DNSConfig{
102103
MagicDNS: false,
103104
BaseDomain: "example.com",
105+
OverrideLocalDNS: false,
104106
Nameservers: Nameservers{
105107
Global: []string{
106108
"1.1.1.1",
@@ -135,7 +137,7 @@ func TestReadConfig(t *testing.T) {
135137
want: &tailcfg.DNSConfig{
136138
Proxied: false,
137139
Domains: []string{"example.com", "test.com", "bar.com"},
138-
Resolvers: []*dnstype.Resolver{
140+
FallbackResolvers: []*dnstype.Resolver{
139141
{Addr: "1.1.1.1"},
140142
{Addr: "1.0.0.1"},
141143
{Addr: "2606:4700:4700::1111"},
@@ -254,6 +256,7 @@ func TestReadConfigFromEnv(t *testing.T) {
254256
configEnv: map[string]string{
255257
"HEADSCALE_DNS_MAGIC_DNS": "true",
256258
"HEADSCALE_DNS_BASE_DOMAIN": "example.com",
259+
"HEADSCALE_DNS_OVERRIDE_LOCAL_DNS": "false",
257260
"HEADSCALE_DNS_NAMESERVERS_GLOBAL": `1.1.1.1 8.8.8.8`,
258261
"HEADSCALE_DNS_SEARCH_DOMAINS": "test.com bar.com",
259262

@@ -274,6 +277,7 @@ func TestReadConfigFromEnv(t *testing.T) {
274277
want: DNSConfig{
275278
MagicDNS: true,
276279
BaseDomain: "example.com",
280+
OverrideLocalDNS: false,
277281
Nameservers: Nameservers{
278282
Global: []string{"1.1.1.1", "8.8.8.8"},
279283
Split: map[string][]string{

hscontrol/types/testdata/dns_full.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ dns:
77
magic_dns: true
88
base_domain: example.com
99

10+
override_local_dns: false
1011
nameservers:
1112
global:
1213
- 1.1.1.1

hscontrol/types/testdata/dns_full_no_magic.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ dns:
77
magic_dns: false
88
base_domain: example.com
99

10+
override_local_dns: false
1011
nameservers:
1112
global:
1213
- 1.1.1.1

integration/hsic/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ func DefaultConfigEnv() map[string]string {
2323
"HEADSCALE_PREFIXES_V6": "fd7a:115c:a1e0::/48",
2424
"HEADSCALE_DNS_BASE_DOMAIN": "headscale.net",
2525
"HEADSCALE_DNS_MAGIC_DNS": "true",
26+
"HEADSCALE_DNS_OVERRIDE_LOCAL_DNS": "false",
2627
"HEADSCALE_DNS_NAMESERVERS_GLOBAL": "127.0.0.11 1.1.1.1",
2728
"HEADSCALE_PRIVATE_KEY_PATH": "/tmp/private.key",
2829
"HEADSCALE_NOISE_PRIVATE_KEY_PATH": "/tmp/noise_private.key",

0 commit comments

Comments
 (0)