net/dns: split out search domains and match domains in OSConfig.

It seems that all the setups that support split DNS understand
this distinction, and it's an important one when translating
high-level configuration.

Part of #953.

Signed-off-by: David Anderson <danderson@tailscale.com>
pull/1643/head
David Anderson 4 years ago
parent a8dcda9c9a
commit e0e677a8f6

@ -74,7 +74,7 @@ func readResolvConf() (OSConfig, error) {
if strings.HasPrefix(line, "search") { if strings.HasPrefix(line, "search") {
domain := strings.TrimPrefix(line, "search") domain := strings.TrimPrefix(line, "search")
domain = strings.TrimSpace(domain) domain = strings.TrimSpace(domain)
config.Domains = append(config.Domains, domain) config.SearchDomains = append(config.SearchDomains, domain)
continue continue
} }
} }
@ -117,7 +117,7 @@ func newDirectManager() directManager {
func (m directManager) SetDNS(config OSConfig) error { func (m directManager) SetDNS(config OSConfig) error {
// Write the tsConf file. // Write the tsConf file.
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
writeResolvConf(buf, config.Nameservers, config.Domains) writeResolvConf(buf, config.Nameservers, config.SearchDomains)
if err := atomicfile.WriteFile(tsConf, buf.Bytes(), 0644); err != nil { if err := atomicfile.WriteFile(tsConf, buf.Bytes(), 0644); err != nil {
return err return err
} }

@ -66,8 +66,7 @@ func (m *Manager) Set(cfg Config) error {
Routes: map[string][]netaddr.IPPort{}, Routes: map[string][]netaddr.IPPort{},
} }
osCfg := OSConfig{ osCfg := OSConfig{
Domains: cfg.SearchDomains, SearchDomains: cfg.SearchDomains,
Primary: true,
} }
// We must proxy through quad-100 if MagicDNS hosts are in // We must proxy through quad-100 if MagicDNS hosts are in
// use, or there are any per-domain routes. // use, or there are any per-domain routes.

@ -232,22 +232,22 @@ func (m windowsManager) SetDNS(cfg OSConfig) error {
// configuration only, routing one set of things to the "split" // configuration only, routing one set of things to the "split"
// resolver and the rest to the primary. // resolver and the rest to the primary.
if cfg.Primary { if len(cfg.MatchDomains) == 0 {
if err := m.setSplitDNS(nil, nil); err != nil { if err := m.setSplitDNS(nil, nil); err != nil {
return err return err
} }
if err := m.setPrimaryDNS(cfg.Nameservers, cfg.Domains); err != nil { if err := m.setPrimaryDNS(cfg.Nameservers, cfg.SearchDomains); err != nil {
return err return err
} }
} else if !m.nrptWorks { } else if !m.nrptWorks {
return errors.New("cannot set per-domain resolvers on Windows 7") return errors.New("cannot set per-domain resolvers on Windows 7")
} else { } else {
if err := m.setSplitDNS(cfg.Nameservers, cfg.Domains); err != nil { if err := m.setSplitDNS(cfg.Nameservers, cfg.MatchDomains); err != nil {
return err return err
} }
// Still set search domains on the interface, since NRPT only // Still set search domains on the interface, since NRPT only
// handles query routing and not search domain expansion. // handles query routing and not search domain expansion.
if err := m.setPrimaryDNS(nil, cfg.Domains); err != nil { if err := m.setPrimaryDNS(nil, cfg.SearchDomains); err != nil {
return err return err
} }
} }
@ -297,9 +297,7 @@ func (m windowsManager) SupportsSplitDNS() bool {
} }
func (m windowsManager) Close() error { func (m windowsManager) Close() error {
return m.SetDNS(OSConfig{ return m.SetDNS(OSConfig{})
Primary: true,
})
} }
// getBasePrimaryResolver returns a guess of the non-Tailscale primary // getBasePrimaryResolver returns a guess of the non-Tailscale primary

@ -138,7 +138,7 @@ func (m nmManager) SetDNS(config OSConfig) error {
ipv4Map := settings["ipv4"] ipv4Map := settings["ipv4"]
ipv4Map["dns"] = dbus.MakeVariant(dnsv4) ipv4Map["dns"] = dbus.MakeVariant(dnsv4)
ipv4Map["dns-search"] = dbus.MakeVariant(config.Domains) ipv4Map["dns-search"] = dbus.MakeVariant(config.SearchDomains)
// We should only request priority if we have nameservers to set. // We should only request priority if we have nameservers to set.
if len(dnsv4) == 0 { if len(dnsv4) == 0 {
ipv4Map["dns-priority"] = dbus.MakeVariant(100) ipv4Map["dns-priority"] = dbus.MakeVariant(100)
@ -166,7 +166,7 @@ func (m nmManager) SetDNS(config OSConfig) error {
// Finally, set the actual DNS config. // Finally, set the actual DNS config.
ipv6Map["dns"] = dbus.MakeVariant(dnsv6) ipv6Map["dns"] = dbus.MakeVariant(dnsv6)
ipv6Map["dns-search"] = dbus.MakeVariant(config.Domains) ipv6Map["dns-search"] = dbus.MakeVariant(config.SearchDomains)
if len(dnsv6) == 0 { if len(dnsv6) == 0 {
ipv6Map["dns-priority"] = dbus.MakeVariant(100) ipv6Map["dns-priority"] = dbus.MakeVariant(100)
} else { } else {

@ -25,13 +25,14 @@ type OSConfigurator interface {
type OSConfig struct { type OSConfig struct {
// Nameservers are the IP addresses of the nameservers to use. // Nameservers are the IP addresses of the nameservers to use.
Nameservers []netaddr.IP Nameservers []netaddr.IP
// Domains are the search domains to use. // SearchDomains are the domain suffixes to use when expanding
Domains []string // single-label name queries. SearchDomains is additive to
// Primary indicates whether to set Nameservers as the // whatever non-Tailscale search domains the OS has.
// primary/"default" resolvers for the system. SearchDomains []string
// If false, Nameservers will be set as resolvers for Domains // MatchDomains are the DNS suffixes for which Nameservers should
// only. // be used. If empty, Nameservers is installed as the "primary" resolver.
// Primary=false is only allowed for OSConfigurators that report // A non-empty MatchDomains requests a "split DNS" configuration
// SupportsSplitDNS. // from the OS, which will only work with OSConfigurators that
Primary bool // report SupportsSplitDNS()=true.
MatchDomains []string
} }

@ -117,7 +117,7 @@ const resolvconfConfigName = "tun-tailscale.inet"
func (m resolvconfManager) SetDNS(config OSConfig) error { func (m resolvconfManager) SetDNS(config OSConfig) error {
stdin := new(bytes.Buffer) stdin := new(bytes.Buffer)
writeResolvConf(stdin, config.Nameservers, config.Domains) // dns_direct.go writeResolvConf(stdin, config.Nameservers, config.SearchDomains) // dns_direct.go
var cmd *exec.Cmd var cmd *exec.Cmd
switch m.impl { switch m.impl {

@ -134,8 +134,8 @@ func (m resolvedManager) SetDNS(config OSConfig) error {
return fmt.Errorf("setLinkDNS: %w", err) return fmt.Errorf("setLinkDNS: %w", err)
} }
var linkDomains = make([]resolvedLinkDomain, len(config.Domains)) var linkDomains = make([]resolvedLinkDomain, len(config.SearchDomains))
for i, domain := range config.Domains { for i, domain := range config.SearchDomains {
linkDomains[i] = resolvedLinkDomain{ linkDomains[i] = resolvedLinkDomain{
Domain: domain, Domain: domain,
RoutingOnly: false, RoutingOnly: false,

Loading…
Cancel
Save