Merge pull request #183 from juanfont/split-dns

Add support for Split DNS (Restricted Nameservers)
This commit is contained in:
Juan Font 2021-10-20 10:53:52 +02:00 committed by GitHub
commit 03d97c3872
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 16 deletions

5
app.go
View file

@ -113,7 +113,10 @@ func NewHeadscale(cfg Config) (*Headscale, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
h.cfg.DNSConfig.Routes = make(map[string][]dnstype.Resolver) // we might have routes already from Split DNS
if h.cfg.DNSConfig.Routes == nil {
h.cfg.DNSConfig.Routes = make(map[string][]dnstype.Resolver)
}
for _, d := range magicDNSDomains { for _, d := range magicDNSDomains {
h.cfg.DNSConfig.Routes[d.WithoutTrailingDot()] = nil h.cfg.DNSConfig.Routes[d.WithoutTrailingDot()] = nil
} }

View file

@ -104,6 +104,33 @@ func GetDNSConfig() (*tailcfg.DNSConfig, string) {
dnsConfig.Nameservers = nameservers dnsConfig.Nameservers = nameservers
dnsConfig.Resolvers = resolvers dnsConfig.Resolvers = resolvers
} }
if viper.IsSet("dns_config.restricted_nameservers") {
if len(dnsConfig.Nameservers) > 0 {
dnsConfig.Routes = make(map[string][]dnstype.Resolver)
restrictedDNS := viper.GetStringMapStringSlice("dns_config.restricted_nameservers")
for domain, restrictedNameservers := range restrictedDNS {
restrictedResolvers := make([]dnstype.Resolver, len(restrictedNameservers))
for index, nameserverStr := range restrictedNameservers {
nameserver, err := netaddr.ParseIP(nameserverStr)
if err != nil {
log.Error().
Str("func", "getDNSConfig").
Err(err).
Msgf("Could not parse restricted nameserver IP: %s", nameserverStr)
}
restrictedResolvers[index] = dnstype.Resolver{
Addr: nameserver.String(),
}
}
dnsConfig.Routes[domain] = restrictedResolvers
}
} else {
log.Warn().
Msg("Warning: dns_config.restricted_nameservers is set, but no nameservers are configured. Ignoring restricted_nameservers.")
}
}
if viper.IsSet("dns_config.domains") { if viper.IsSet("dns_config.domains") {
dnsConfig.Domains = viper.GetStringSlice("dns_config.domains") dnsConfig.Domains = viper.GetStringSlice("dns_config.domains")
} }

View file

@ -11,23 +11,29 @@ Long story short, you can define the DNS servers you want to use in your tailnet
## Configuration reference ## Configuration reference
The setup is done via the `config.json` file, under the `dns_config` key. The setup is done via the `config.yaml` file, under the `dns_config` key.
```json ```yaml
{ server_url: http://127.0.0.1:8001
"server_url": "http://127.0.0.1:8001", listen_addr: 0.0.0.0:8001
"listen_addr": "0.0.0.0:8001", private_key_path: private.key
"private_key_path": "private.key", dns_config:
//... nameservers:
"dns_config": { - 1.1.1.1
"nameservers": ["1.1.1.1", "8.8.8.8"], - 8.8.8.8
"domains": [], restricted_nameservers:
"magic_dns": true, foo.bar.com:
"base_domain": "example.com" - 1.1.1.1
} darp.headscale.net:
} - 1.1.1.1
- 8.8.8.8
domains: []
magic_dns: true
base_domain: example.com
``` ```
- `nameservers`: The list of DNS servers to use. - `nameservers`: The list of DNS servers to use.
- `domains`: Search domains to inject. - `domains`: Search domains to inject.
- `magic_dns`: Whether to use [MagicDNS](https://tailscale.com/kb/1081/magicdns/). Only works if there is at least a nameserver defined. - `magic_dns`: Whether to use [MagicDNS](https://tailscale.com/kb/1081/magicdns/). Only works if there is at least a nameserver defined.
- `base_domain`: Defines the base domain to create the hostnames for MagicDNS. `base_domain` must be a FQDNs, without the trailing dot. The FQDN of the hosts will be `hostname.namespace.base_domain` (e.g., _myhost.mynamespace.example.com_). - `base_domain`: Defines the base domain to create the hostnames for MagicDNS. `base_domain` must be a FQDNs, without the trailing dot. The FQDN of the hosts will be `hostname.namespace.base_domain` (e.g., _myhost.mynamespace.example.com_).
- `restricted_nameservers`: Split DNS (see https://tailscale.com/kb/1054/dns/), list of search domains and the DNS to query for each one.