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 3 years ago
parent a8dcda9c9a
commit e0e677a8f6

@ -74,7 +74,7 @@ func readResolvConf() (OSConfig, error) {
if strings.HasPrefix(line, "search") {
domain := strings.TrimPrefix(line, "search")
domain = strings.TrimSpace(domain)
config.Domains = append(config.Domains, domain)
config.SearchDomains = append(config.SearchDomains, domain)
continue
}
}
@ -117,7 +117,7 @@ func newDirectManager() directManager {
func (m directManager) SetDNS(config OSConfig) error {
// Write the tsConf file.
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 {
return err
}

@ -66,8 +66,7 @@ func (m *Manager) Set(cfg Config) error {
Routes: map[string][]netaddr.IPPort{},
}
osCfg := OSConfig{
Domains: cfg.SearchDomains,
Primary: true,
SearchDomains: cfg.SearchDomains,
}
// We must proxy through quad-100 if MagicDNS hosts are in
// 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"
// resolver and the rest to the primary.
if cfg.Primary {
if len(cfg.MatchDomains) == 0 {
if err := m.setSplitDNS(nil, nil); err != nil {
return err
}
if err := m.setPrimaryDNS(cfg.Nameservers, cfg.Domains); err != nil {
if err := m.setPrimaryDNS(cfg.Nameservers, cfg.SearchDomains); err != nil {
return err
}
} else if !m.nrptWorks {
return errors.New("cannot set per-domain resolvers on Windows 7")
} else {
if err := m.setSplitDNS(cfg.Nameservers, cfg.Domains); err != nil {
if err := m.setSplitDNS(cfg.Nameservers, cfg.MatchDomains); err != nil {
return err
}
// Still set search domains on the interface, since NRPT only
// 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
}
}
@ -297,9 +297,7 @@ func (m windowsManager) SupportsSplitDNS() bool {
}
func (m windowsManager) Close() error {
return m.SetDNS(OSConfig{
Primary: true,
})
return m.SetDNS(OSConfig{})
}
// getBasePrimaryResolver returns a guess of the non-Tailscale primary

@ -138,7 +138,7 @@ func (m nmManager) SetDNS(config OSConfig) error {
ipv4Map := settings["ipv4"]
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.
if len(dnsv4) == 0 {
ipv4Map["dns-priority"] = dbus.MakeVariant(100)
@ -166,7 +166,7 @@ func (m nmManager) SetDNS(config OSConfig) error {
// Finally, set the actual DNS config.
ipv6Map["dns"] = dbus.MakeVariant(dnsv6)
ipv6Map["dns-search"] = dbus.MakeVariant(config.Domains)
ipv6Map["dns-search"] = dbus.MakeVariant(config.SearchDomains)
if len(dnsv6) == 0 {
ipv6Map["dns-priority"] = dbus.MakeVariant(100)
} else {

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

@ -117,7 +117,7 @@ const resolvconfConfigName = "tun-tailscale.inet"
func (m resolvconfManager) SetDNS(config OSConfig) error {
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
switch m.impl {

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

Loading…
Cancel
Save