mirror of
https://github.com/juanfont/headscale.git
synced 2025-08-05 13:49:57 +02:00
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
This commit is contained in:
parent
7891378f57
commit
3367193782
@ -43,6 +43,8 @@ Note that if an exit route is approved (0.0.0.0/0 or ::/0), both IPv4 and IPv6 w
|
|||||||
- It is now possible to inspect running goroutines and take profiles
|
- It is now possible to inspect running goroutines and take profiles
|
||||||
- View of config, policy, filter, ssh policy per node, connected nodes and
|
- View of config, policy, filter, ssh policy per node, connected nodes and
|
||||||
DERPmap
|
DERPmap
|
||||||
|
- Restore support for "Override local DNS"
|
||||||
|
[#2438](https://github.com/juanfont/headscale/pull/2438)
|
||||||
|
|
||||||
## 0.25.1 (2025-02-25)
|
## 0.25.1 (2025-02-25)
|
||||||
|
|
||||||
|
@ -274,6 +274,10 @@ dns:
|
|||||||
# `hostname.base_domain` (e.g., _myhost.example.com_).
|
# `hostname.base_domain` (e.g., _myhost.example.com_).
|
||||||
base_domain: example.com
|
base_domain: example.com
|
||||||
|
|
||||||
|
# Whether to use the local DNS settings of a node (default) or override the
|
||||||
|
# local DNS settings and force the use of Headscale's DNS configuration.
|
||||||
|
override_local_dns: false
|
||||||
|
|
||||||
# List of DNS servers to expose to clients.
|
# List of DNS servers to expose to clients.
|
||||||
nameservers:
|
nameservers:
|
||||||
global:
|
global:
|
||||||
|
@ -102,6 +102,7 @@ type Config struct {
|
|||||||
type DNSConfig struct {
|
type DNSConfig struct {
|
||||||
MagicDNS bool `mapstructure:"magic_dns"`
|
MagicDNS bool `mapstructure:"magic_dns"`
|
||||||
BaseDomain string `mapstructure:"base_domain"`
|
BaseDomain string `mapstructure:"base_domain"`
|
||||||
|
OverrideLocalDNS bool `mapstructure:"override_local_dns"`
|
||||||
Nameservers Nameservers
|
Nameservers Nameservers
|
||||||
SearchDomains []string `mapstructure:"search_domains"`
|
SearchDomains []string `mapstructure:"search_domains"`
|
||||||
ExtraRecords []tailcfg.DNSRecord `mapstructure:"extra_records"`
|
ExtraRecords []tailcfg.DNSRecord `mapstructure:"extra_records"`
|
||||||
@ -287,6 +288,7 @@ func LoadConfig(path string, isFile bool) error {
|
|||||||
|
|
||||||
viper.SetDefault("dns.magic_dns", true)
|
viper.SetDefault("dns.magic_dns", true)
|
||||||
viper.SetDefault("dns.base_domain", "")
|
viper.SetDefault("dns.base_domain", "")
|
||||||
|
viper.SetDefault("dns.override_local_dns", false)
|
||||||
viper.SetDefault("dns.nameservers.global", []string{})
|
viper.SetDefault("dns.nameservers.global", []string{})
|
||||||
viper.SetDefault("dns.nameservers.split", map[string]string{})
|
viper.SetDefault("dns.nameservers.split", map[string]string{})
|
||||||
viper.SetDefault("dns.search_domains", []string{})
|
viper.SetDefault("dns.search_domains", []string{})
|
||||||
@ -351,9 +353,9 @@ func validateServerConfig() error {
|
|||||||
depr.fatalIfNewKeyIsNotUsed("policy.path", "acl_policy_path")
|
depr.fatalIfNewKeyIsNotUsed("policy.path", "acl_policy_path")
|
||||||
|
|
||||||
// Move dns_config -> dns
|
// Move dns_config -> dns
|
||||||
depr.warn("dns_config.override_local_dns")
|
|
||||||
depr.fatalIfNewKeyIsNotUsed("dns.magic_dns", "dns_config.magic_dns")
|
depr.fatalIfNewKeyIsNotUsed("dns.magic_dns", "dns_config.magic_dns")
|
||||||
depr.fatalIfNewKeyIsNotUsed("dns.base_domain", "dns_config.base_domain")
|
depr.fatalIfNewKeyIsNotUsed("dns.base_domain", "dns_config.base_domain")
|
||||||
|
depr.fatalIfNewKeyIsNotUsed("dns.override_local_dns", "dns_config.override_local_dns")
|
||||||
depr.fatalIfNewKeyIsNotUsed("dns.nameservers.global", "dns_config.nameservers")
|
depr.fatalIfNewKeyIsNotUsed("dns.nameservers.global", "dns_config.nameservers")
|
||||||
depr.fatalIfNewKeyIsNotUsed("dns.nameservers.split", "dns_config.restricted_nameservers")
|
depr.fatalIfNewKeyIsNotUsed("dns.nameservers.split", "dns_config.restricted_nameservers")
|
||||||
depr.fatalIfNewKeyIsNotUsed("dns.search_domains", "dns_config.domains")
|
depr.fatalIfNewKeyIsNotUsed("dns.search_domains", "dns_config.domains")
|
||||||
@ -616,6 +618,7 @@ func dns() (DNSConfig, error) {
|
|||||||
|
|
||||||
dns.MagicDNS = viper.GetBool("dns.magic_dns")
|
dns.MagicDNS = viper.GetBool("dns.magic_dns")
|
||||||
dns.BaseDomain = viper.GetString("dns.base_domain")
|
dns.BaseDomain = viper.GetString("dns.base_domain")
|
||||||
|
dns.OverrideLocalDNS = viper.GetBool("dns.override_local_dns")
|
||||||
dns.Nameservers.Global = viper.GetStringSlice("dns.nameservers.global")
|
dns.Nameservers.Global = viper.GetStringSlice("dns.nameservers.global")
|
||||||
dns.Nameservers.Split = viper.GetStringMapStringSlice("dns.nameservers.split")
|
dns.Nameservers.Split = viper.GetStringMapStringSlice("dns.nameservers.split")
|
||||||
dns.SearchDomains = viper.GetStringSlice("dns.search_domains")
|
dns.SearchDomains = viper.GetStringSlice("dns.search_domains")
|
||||||
@ -721,7 +724,11 @@ func dnsToTailcfgDNS(dns DNSConfig) *tailcfg.DNSConfig {
|
|||||||
|
|
||||||
cfg.Proxied = dns.MagicDNS
|
cfg.Proxied = dns.MagicDNS
|
||||||
cfg.ExtraRecords = dns.ExtraRecords
|
cfg.ExtraRecords = dns.ExtraRecords
|
||||||
|
if dns.OverrideLocalDNS {
|
||||||
cfg.Resolvers = dns.globalResolvers()
|
cfg.Resolvers = dns.globalResolvers()
|
||||||
|
} else {
|
||||||
|
cfg.FallbackResolvers = dns.globalResolvers()
|
||||||
|
}
|
||||||
|
|
||||||
routes := dns.splitResolvers()
|
routes := dns.splitResolvers()
|
||||||
cfg.Routes = routes
|
cfg.Routes = routes
|
||||||
|
@ -36,6 +36,7 @@ func TestReadConfig(t *testing.T) {
|
|||||||
want: DNSConfig{
|
want: DNSConfig{
|
||||||
MagicDNS: true,
|
MagicDNS: true,
|
||||||
BaseDomain: "example.com",
|
BaseDomain: "example.com",
|
||||||
|
OverrideLocalDNS: false,
|
||||||
Nameservers: Nameservers{
|
Nameservers: Nameservers{
|
||||||
Global: []string{
|
Global: []string{
|
||||||
"1.1.1.1",
|
"1.1.1.1",
|
||||||
@ -70,7 +71,7 @@ func TestReadConfig(t *testing.T) {
|
|||||||
want: &tailcfg.DNSConfig{
|
want: &tailcfg.DNSConfig{
|
||||||
Proxied: true,
|
Proxied: true,
|
||||||
Domains: []string{"example.com", "test.com", "bar.com"},
|
Domains: []string{"example.com", "test.com", "bar.com"},
|
||||||
Resolvers: []*dnstype.Resolver{
|
FallbackResolvers: []*dnstype.Resolver{
|
||||||
{Addr: "1.1.1.1"},
|
{Addr: "1.1.1.1"},
|
||||||
{Addr: "1.0.0.1"},
|
{Addr: "1.0.0.1"},
|
||||||
{Addr: "2606:4700:4700::1111"},
|
{Addr: "2606:4700:4700::1111"},
|
||||||
@ -101,6 +102,7 @@ func TestReadConfig(t *testing.T) {
|
|||||||
want: DNSConfig{
|
want: DNSConfig{
|
||||||
MagicDNS: false,
|
MagicDNS: false,
|
||||||
BaseDomain: "example.com",
|
BaseDomain: "example.com",
|
||||||
|
OverrideLocalDNS: false,
|
||||||
Nameservers: Nameservers{
|
Nameservers: Nameservers{
|
||||||
Global: []string{
|
Global: []string{
|
||||||
"1.1.1.1",
|
"1.1.1.1",
|
||||||
@ -135,7 +137,7 @@ func TestReadConfig(t *testing.T) {
|
|||||||
want: &tailcfg.DNSConfig{
|
want: &tailcfg.DNSConfig{
|
||||||
Proxied: false,
|
Proxied: false,
|
||||||
Domains: []string{"example.com", "test.com", "bar.com"},
|
Domains: []string{"example.com", "test.com", "bar.com"},
|
||||||
Resolvers: []*dnstype.Resolver{
|
FallbackResolvers: []*dnstype.Resolver{
|
||||||
{Addr: "1.1.1.1"},
|
{Addr: "1.1.1.1"},
|
||||||
{Addr: "1.0.0.1"},
|
{Addr: "1.0.0.1"},
|
||||||
{Addr: "2606:4700:4700::1111"},
|
{Addr: "2606:4700:4700::1111"},
|
||||||
@ -254,6 +256,7 @@ func TestReadConfigFromEnv(t *testing.T) {
|
|||||||
configEnv: map[string]string{
|
configEnv: map[string]string{
|
||||||
"HEADSCALE_DNS_MAGIC_DNS": "true",
|
"HEADSCALE_DNS_MAGIC_DNS": "true",
|
||||||
"HEADSCALE_DNS_BASE_DOMAIN": "example.com",
|
"HEADSCALE_DNS_BASE_DOMAIN": "example.com",
|
||||||
|
"HEADSCALE_DNS_OVERRIDE_LOCAL_DNS": "false",
|
||||||
"HEADSCALE_DNS_NAMESERVERS_GLOBAL": `1.1.1.1 8.8.8.8`,
|
"HEADSCALE_DNS_NAMESERVERS_GLOBAL": `1.1.1.1 8.8.8.8`,
|
||||||
"HEADSCALE_DNS_SEARCH_DOMAINS": "test.com bar.com",
|
"HEADSCALE_DNS_SEARCH_DOMAINS": "test.com bar.com",
|
||||||
|
|
||||||
@ -274,6 +277,7 @@ func TestReadConfigFromEnv(t *testing.T) {
|
|||||||
want: DNSConfig{
|
want: DNSConfig{
|
||||||
MagicDNS: true,
|
MagicDNS: true,
|
||||||
BaseDomain: "example.com",
|
BaseDomain: "example.com",
|
||||||
|
OverrideLocalDNS: false,
|
||||||
Nameservers: Nameservers{
|
Nameservers: Nameservers{
|
||||||
Global: []string{"1.1.1.1", "8.8.8.8"},
|
Global: []string{"1.1.1.1", "8.8.8.8"},
|
||||||
Split: map[string][]string{
|
Split: map[string][]string{
|
||||||
|
1
hscontrol/types/testdata/dns_full.yaml
vendored
1
hscontrol/types/testdata/dns_full.yaml
vendored
@ -7,6 +7,7 @@ dns:
|
|||||||
magic_dns: true
|
magic_dns: true
|
||||||
base_domain: example.com
|
base_domain: example.com
|
||||||
|
|
||||||
|
override_local_dns: false
|
||||||
nameservers:
|
nameservers:
|
||||||
global:
|
global:
|
||||||
- 1.1.1.1
|
- 1.1.1.1
|
||||||
|
@ -7,6 +7,7 @@ dns:
|
|||||||
magic_dns: false
|
magic_dns: false
|
||||||
base_domain: example.com
|
base_domain: example.com
|
||||||
|
|
||||||
|
override_local_dns: false
|
||||||
nameservers:
|
nameservers:
|
||||||
global:
|
global:
|
||||||
- 1.1.1.1
|
- 1.1.1.1
|
||||||
|
@ -23,6 +23,7 @@ func DefaultConfigEnv() map[string]string {
|
|||||||
"HEADSCALE_PREFIXES_V6": "fd7a:115c:a1e0::/48",
|
"HEADSCALE_PREFIXES_V6": "fd7a:115c:a1e0::/48",
|
||||||
"HEADSCALE_DNS_BASE_DOMAIN": "headscale.net",
|
"HEADSCALE_DNS_BASE_DOMAIN": "headscale.net",
|
||||||
"HEADSCALE_DNS_MAGIC_DNS": "true",
|
"HEADSCALE_DNS_MAGIC_DNS": "true",
|
||||||
|
"HEADSCALE_DNS_OVERRIDE_LOCAL_DNS": "false",
|
||||||
"HEADSCALE_DNS_NAMESERVERS_GLOBAL": "127.0.0.11 1.1.1.1",
|
"HEADSCALE_DNS_NAMESERVERS_GLOBAL": "127.0.0.11 1.1.1.1",
|
||||||
"HEADSCALE_PRIVATE_KEY_PATH": "/tmp/private.key",
|
"HEADSCALE_PRIVATE_KEY_PATH": "/tmp/private.key",
|
||||||
"HEADSCALE_NOISE_PRIVATE_KEY_PATH": "/tmp/noise_private.key",
|
"HEADSCALE_NOISE_PRIVATE_KEY_PATH": "/tmp/noise_private.key",
|
||||||
|
Loading…
Reference in New Issue
Block a user