Update
This commit is contained in:
1 parent
3530afb854
commit
6903fcff27
2146 files changed
+112256
-190703
No files matched your search
+71
-8
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:generate go run tailscale.com/cmd/viewer --type=Config --clonefunc
|
||||
@@ -21,10 +21,15 @@ import (
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/types/dnstype"
|
||||
"tailscale.com/util/dnsname"
|
||||
"tailscale.com/util/set"
|
||||
)
|
||||
|
||||
// Config is a DNS configuration.
|
||||
type Config struct {
|
||||
// AcceptDNS true if [Prefs.CorpDNS] is enabled (or --accept-dns=true).
|
||||
// This should be used for error handling and health reporting
|
||||
// purposes only.
|
||||
AcceptDNS bool
|
||||
// DefaultResolvers are the DNS resolvers to use for DNS names
|
||||
// which aren't covered by more specific per-domain routes below.
|
||||
// If empty, the OS's default resolvers (the ones that predate
|
||||
@@ -48,9 +53,22 @@ type Config struct {
|
||||
// it to resolve, you also need to add appropriate routes to
|
||||
// Routes.
|
||||
Hosts map[dnsname.FQDN][]netip.Addr
|
||||
// SubdomainHosts is a set of FQDNs from Hosts that should also
|
||||
// resolve subdomain queries to the same IPs. For example, if
|
||||
// "node.tailnet.ts.net" is in SubdomainHosts, then queries for
|
||||
// "anything.node.tailnet.ts.net" will resolve to node's IPs.
|
||||
SubdomainHosts set.Set[dnsname.FQDN]
|
||||
// OnlyIPv6, if true, uses the IPv6 service IP (for MagicDNS)
|
||||
// instead of the IPv4 version (100.100.100.100).
|
||||
OnlyIPv6 bool
|
||||
// MagicDNSHostsUnrouted is whether MagicDNS host records are
|
||||
// served on demand via [resolver.MagicDNSHosts] (so are not
|
||||
// listed in Hosts) without being covered by any Routes entry;
|
||||
// that is, MagicDNS domain routing is off. It preserves the
|
||||
// effect the node records had when they were listed in Hosts:
|
||||
// hasHostsWithoutSplitDNSRoutes reports true, keeping quad-100
|
||||
// in the OS resolver path so the names still resolve.
|
||||
MagicDNSHostsUnrouted bool
|
||||
}
|
||||
|
||||
var magicDNSDualStack = envknob.RegisterBool("TS_DEBUG_MAGIC_DNS_DUAL_STACK")
|
||||
@@ -63,11 +81,9 @@ func (c *Config) serviceIPs(knobs *controlknobs.Knobs) []netip.Addr {
|
||||
return []netip.Addr{tsaddr.TailscaleServiceIPv6()}
|
||||
}
|
||||
|
||||
// TODO(bradfitz,mikeodr,raggi): include IPv6 here too; tailscale/tailscale#15404
|
||||
// And add a controlknobs knob to disable dual stack.
|
||||
//
|
||||
// For now, opt-in for testing.
|
||||
if magicDNSDualStack() {
|
||||
// See https://github.com/tailscale/tailscale/issues/15404 for the background
|
||||
// on the opt-in debug knob and the controlknob opt-out.
|
||||
if magicDNSDualStack() || !knobs.ShouldForceRegisterMagicDNSIPv4Only() {
|
||||
return []netip.Addr{
|
||||
tsaddr.TailscaleServiceIP(),
|
||||
tsaddr.TailscaleServiceIPv6(),
|
||||
@@ -119,8 +135,13 @@ func (c Config) hasDefaultIPResolversOnly() bool {
|
||||
// hasHostsWithoutSplitDNSRoutes reports whether c contains any Host entries
|
||||
// that aren't covered by a SplitDNS route suffix.
|
||||
func (c Config) hasHostsWithoutSplitDNSRoutes() bool {
|
||||
// TODO(bradfitz): this could be more efficient, but we imagine
|
||||
// the number of SplitDNS routes and/or hosts will be small.
|
||||
if c.MagicDNSHostsUnrouted {
|
||||
return true
|
||||
}
|
||||
// Hosts is small here on most platforms: per-node records are
|
||||
// served via [resolver.MagicDNSHosts] (accounted for above), so
|
||||
// only control's DNS.ExtraRecords remain. On Windows it still
|
||||
// carries every node's records for the hosts-file path.
|
||||
for host := range c.Hosts {
|
||||
if !c.hasSplitDNSRouteForHost(host) {
|
||||
return true
|
||||
@@ -129,6 +150,19 @@ func (c Config) hasHostsWithoutSplitDNSRoutes() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// requiresPrimaryResolver reports whether c can only be served correctly with
|
||||
// quad-100 installed as the OS's primary (catch-all) resolver, rather than
|
||||
// scoped to a set of match domains.
|
||||
//
|
||||
// That's the case when c has names quad-100 must answer that no route suffix
|
||||
// covers, so there is no suffix to scope to. dnsConfigForNetmap pairs every
|
||||
// ExtraRecord it emits with a route, so in practice this is the
|
||||
// MagicDNS-names-present but MagicDNS-domain-routing-off case
|
||||
// (MagicDNSHostsUnrouted).
|
||||
func (c Config) requiresPrimaryResolver() bool {
|
||||
return c.hasHostsWithoutSplitDNSRoutes()
|
||||
}
|
||||
|
||||
// hasSplitDNSRouteForHost reports whether c contains a SplitDNS route
|
||||
// that contains hosts.
|
||||
func (c Config) hasSplitDNSRouteForHost(host dnsname.FQDN) bool {
|
||||
@@ -140,6 +174,35 @@ func (c Config) hasSplitDNSRouteForHost(host dnsname.FQDN) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// hasHostsWithoutReverseRoutes reports whether any PTR record synthesized by
|
||||
// quad-100 from Hosts is outside the configured routes. Apple scoping must
|
||||
// preserve these answers as well as forward records.
|
||||
func (c Config) hasHostsWithoutReverseRoutes() bool {
|
||||
for _, ips := range c.Hosts {
|
||||
for _, ip := range ips {
|
||||
if !ip.IsValid() || !c.hasSplitDNSRouteForHost(reverseDNSName(ip)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// reverseDNSName returns the PTR query name for a valid IP address.
|
||||
func reverseDNSName(ip netip.Addr) dnsname.FQDN {
|
||||
if ip.Is4() {
|
||||
b := ip.As4()
|
||||
return dnsname.FQDN(fmt.Sprintf("%d.%d.%d.%d.in-addr.arpa.", b[3], b[2], b[1], b[0]))
|
||||
}
|
||||
b := ip.As16()
|
||||
const hex = "0123456789abcdef"
|
||||
name := make([]byte, 0, 64+len("ip6.arpa."))
|
||||
for i := len(b) - 1; i >= 0; i-- {
|
||||
name = append(name, hex[b[i]&0xf], '.', hex[b[i]>>4], '.')
|
||||
}
|
||||
return dnsname.FQDN(append(name, "ip6.arpa."...))
|
||||
}
|
||||
|
||||
func (c Config) hasDefaultResolvers() bool {
|
||||
return len(c.DefaultResolvers) > 0
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user