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
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…
Reference in New Issue