wgengine: move DNS configuration out of wgengine/router.

Signed-off-by: David Anderson <danderson@tailscale.com>
crawshaw/localapi404
David Anderson 4 years ago committed by Dave Anderson
parent 7183e1f052
commit 4c61ebacf4

@ -350,6 +350,13 @@ func tryEngine(logf logger.Logf, linkMon *monitor.Mon, name string) (e wgengine.
return nil, false, err return nil, false, err
} }
conf.Router = r conf.Router = r
tunname, err := dev.Name()
if err != nil {
r.Close()
dev.Close()
return nil, false, err
}
conf.DNS = dns.NewOSConfigurator(logf, tunname)
} }
e, err = wgengine.NewUserspaceEngine(logf, conf) e, err = wgengine.NewUserspaceEngine(logf, conf)
if err != nil { if err != nil {

@ -9,7 +9,6 @@ import (
"testing" "testing"
"inet.af/netaddr" "inet.af/netaddr"
"tailscale.com/net/dns"
"tailscale.com/wgengine/router" "tailscale.com/wgengine/router"
"tailscale.com/wgengine/wgcfg" "tailscale.com/wgengine/wgcfg"
) )
@ -45,9 +44,9 @@ func getVal() []interface{} {
}, },
}, },
&router.Config{ &router.Config{
DNS: dns.OSConfig{ Routes: []netaddr.IPPrefix{
Nameservers: []netaddr.IP{netaddr.IPv4(8, 8, 8, 8)}, netaddr.MustParseIPPrefix("1.2.3.0/24"),
Domains: []string{"tailscale.net"}, netaddr.MustParseIPPrefix("1234::/64"),
}, },
}, },
map[string]string{ map[string]string{

@ -33,11 +33,11 @@ type Manager struct {
} }
// NewManagers created a new manager from the given config. // NewManagers created a new manager from the given config.
func NewManager(logf logger.Logf, interfaceName string) *Manager { func NewManager(logf logger.Logf, oscfg OSConfigurator) *Manager {
logf = logger.WithPrefix(logf, "dns: ") logf = logger.WithPrefix(logf, "dns: ")
m := &Manager{ m := &Manager{
logf: logf, logf: logf,
impl: newManager(logf, interfaceName), impl: oscfg,
} }
m.logf("using %T", m.impl) m.logf("using %T", m.impl)
@ -81,7 +81,8 @@ func (m *Manager) Down() error {
// in case the Tailscale daemon terminated without closing the router. // in case the Tailscale daemon terminated without closing the router.
// No other state needs to be instantiated before this runs. // No other state needs to be instantiated before this runs.
func Cleanup(logf logger.Logf, interfaceName string) { func Cleanup(logf logger.Logf, interfaceName string) {
dns := NewManager(logf, interfaceName) oscfg := NewOSConfigurator(logf, interfaceName)
dns := NewManager(logf, oscfg)
if err := dns.Down(); err != nil { if err := dns.Down(); err != nil {
logf("dns down: %v", err) logf("dns down: %v", err)
} }

@ -8,9 +8,9 @@ package dns
import "tailscale.com/types/logger" import "tailscale.com/types/logger"
func newManager(logger.Logf, string) OSConfigurator { func NewOSConfigurator(logger.Logf, string) OSConfigurator {
// TODO(dmytro): on darwin, we should use a macOS-specific method such as scutil. // TODO(dmytro): on darwin, we should use a macOS-specific method such as scutil.
// This is currently not implemented. Editing /etc/resolv.conf does not work, // This is currently not implemented. Editing /etc/resolv.conf does not work,
// as most applications use the system resolver, which disregards it. // as most applications use the system resolver, which disregards it.
return newNoopManager() return NewNoopManager()
} }

@ -6,7 +6,7 @@ package dns
import "tailscale.com/types/logger" import "tailscale.com/types/logger"
func newManager(logf logger.Logf, _ string) OSConfigurator { func NewOSConfigurator(logf logger.Logf, _ string) OSConfigurator {
switch { switch {
case isResolvconfActive(): case isResolvconfActive():
return newResolvconfManager(logf) return newResolvconfManager(logf)

@ -6,7 +6,7 @@ package dns
import "tailscale.com/types/logger" import "tailscale.com/types/logger"
func newManager(logf logger.Logf, interfaceName string) OSConfigurator { func NewOSConfigurator(logf logger.Logf, interfaceName string) OSConfigurator {
switch { switch {
// TODO: rework NetworkManager and resolved support. // TODO: rework NetworkManager and resolved support.
// case isResolvedActive(): // case isResolvedActive():

@ -6,6 +6,6 @@ package dns
import "tailscale.com/types/logger" import "tailscale.com/types/logger"
func newManager(logger.Logf, string) OSConfigurator { func NewOSConfigurator(logger.Logf, string) OSConfigurator {
return newDirectManager() return newDirectManager()
} }

@ -25,7 +25,7 @@ type windowsManager struct {
guid string guid string
} }
func newManager(logf logger.Logf, interfaceName string) OSConfigurator { func NewOSConfigurator(logf logger.Logf, interfaceName string) OSConfigurator {
return windowsManager{ return windowsManager{
logf: logf, logf: logf,
guid: interfaceName, guid: interfaceName,

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !linux,!freebsd,!openbsd,!windows
package dns package dns
type noopManager struct{} type noopManager struct{}
@ -12,6 +10,6 @@ func (m noopManager) Set(OSConfig) error { return nil }
func (m noopManager) RoutingMode() RoutingMode { return RoutingModeNone } func (m noopManager) RoutingMode() RoutingMode { return RoutingModeNone }
func (m noopManager) Close() error { return nil } func (m noopManager) Close() error { return nil }
func newNoopManager() noopManager { func NewNoopManager() noopManager {
return noopManager{} return noopManager{}
} }

@ -9,7 +9,6 @@ package router
import ( import (
"github.com/tailscale/wireguard-go/tun" "github.com/tailscale/wireguard-go/tun"
"inet.af/netaddr" "inet.af/netaddr"
"tailscale.com/net/dns"
"tailscale.com/types/logger" "tailscale.com/types/logger"
"tailscale.com/types/preftype" "tailscale.com/types/preftype"
) )
@ -58,11 +57,7 @@ type Config struct {
// this node has chosen to use. // this node has chosen to use.
Routes []netaddr.IPPrefix Routes []netaddr.IPPrefix
// Set internally by wgengine, must not be set elsewhere.
DNS dns.OSConfig
// Linux-only things below, ignored on other platforms. // Linux-only things below, ignored on other platforms.
SubnetRoutes []netaddr.IPPrefix // subnets being advertised to other Tailscale nodes SubnetRoutes []netaddr.IPPrefix // subnets being advertised to other Tailscale nodes
SNATSubnetRoutes bool // SNAT traffic to local subnets SNATSubnetRoutes bool // SNAT traffic to local subnets
NetfilterMode preftype.NetfilterMode // how much to manage netfilter rules NetfilterMode preftype.NetfilterMode // how much to manage netfilter rules

@ -18,7 +18,6 @@ import (
"github.com/go-multierror/multierror" "github.com/go-multierror/multierror"
"github.com/tailscale/wireguard-go/tun" "github.com/tailscale/wireguard-go/tun"
"inet.af/netaddr" "inet.af/netaddr"
"tailscale.com/net/dns"
"tailscale.com/net/tsaddr" "tailscale.com/net/tsaddr"
"tailscale.com/types/logger" "tailscale.com/types/logger"
"tailscale.com/types/preftype" "tailscale.com/types/preftype"
@ -102,8 +101,6 @@ type linuxRouter struct {
v6Available bool v6Available bool
v6NATAvailable bool v6NATAvailable bool
dns *dns.Manager
ipt4 netfilterRunner ipt4 netfilterRunner
ipt6 netfilterRunner ipt6 netfilterRunner
cmd commandRunner cmd commandRunner
@ -158,7 +155,6 @@ func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, netfilter4, ne
ipt4: netfilter4, ipt4: netfilter4,
ipt6: netfilter6, ipt6: netfilter6,
cmd: cmd, cmd: cmd,
dns: dns.NewManager(logf, tunname),
}, nil }, nil
} }
@ -180,9 +176,6 @@ func (r *linuxRouter) Up() error {
} }
func (r *linuxRouter) Close() error { func (r *linuxRouter) Close() error {
if err := r.dns.Down(); err != nil {
return fmt.Errorf("dns down: %w", err)
}
if err := r.downInterface(); err != nil { if err := r.downInterface(); err != nil {
return err return err
} }
@ -206,10 +199,6 @@ func (r *linuxRouter) Set(cfg *Config) error {
cfg = &shutdownConfig cfg = &shutdownConfig
} }
if err := r.dns.Set(cfg.DNS); err != nil {
errs = append(errs, fmt.Errorf("dns set: %w", err))
}
if err := r.setNetfilterMode(cfg.NetfilterMode); err != nil { if err := r.setNetfilterMode(cfg.NetfilterMode); err != nil {
errs = append(errs, err) errs = append(errs, err)
} }

@ -12,7 +12,6 @@ import (
"github.com/tailscale/wireguard-go/tun" "github.com/tailscale/wireguard-go/tun"
"inet.af/netaddr" "inet.af/netaddr"
"tailscale.com/net/dns"
"tailscale.com/types/logger" "tailscale.com/types/logger"
) )
@ -26,8 +25,6 @@ type openbsdRouter struct {
local4 netaddr.IPPrefix local4 netaddr.IPPrefix
local6 netaddr.IPPrefix local6 netaddr.IPPrefix
routes map[netaddr.IPPrefix]struct{} routes map[netaddr.IPPrefix]struct{}
dns *dns.Manager
} }
func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) { func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
@ -39,7 +36,6 @@ func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
return &openbsdRouter{ return &openbsdRouter{
logf: logf, logf: logf,
tunname: tunname, tunname: tunname,
dns: dns.NewManager(logf, tunname),
}, nil }, nil
} }
@ -210,17 +206,10 @@ func (r *openbsdRouter) Set(cfg *Config) error {
r.local6 = localAddr6 r.local6 = localAddr6
r.routes = newRoutes r.routes = newRoutes
if err := r.dns.Set(cfg.DNS); err != nil {
errq = fmt.Errorf("dns set: %v", err)
}
return errq return errq
} }
func (r *openbsdRouter) Close() error { func (r *openbsdRouter) Close() error {
if err := r.dns.Down(); err != nil {
return fmt.Errorf("dns down: %v", err)
}
cleanup(r.logf, r.tunname) cleanup(r.logf, r.tunname)
return nil return nil
} }

@ -14,7 +14,6 @@ import (
"github.com/tailscale/wireguard-go/tun" "github.com/tailscale/wireguard-go/tun"
"inet.af/netaddr" "inet.af/netaddr"
"tailscale.com/net/dns"
"tailscale.com/types/logger" "tailscale.com/types/logger"
"tailscale.com/version" "tailscale.com/version"
) )
@ -24,8 +23,6 @@ type userspaceBSDRouter struct {
tunname string tunname string
local []netaddr.IPPrefix local []netaddr.IPPrefix
routes map[netaddr.IPPrefix]struct{} routes map[netaddr.IPPrefix]struct{}
dns *dns.Manager
} }
func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device) (Router, error) { func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
@ -37,7 +34,6 @@ func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device) (Router, error)
return &userspaceBSDRouter{ return &userspaceBSDRouter{
logf: logf, logf: logf,
tunname: tunname, tunname: tunname,
dns: dns.NewManager(logf, tunname),
}, nil }, nil
} }
@ -183,18 +179,9 @@ func (r *userspaceBSDRouter) Set(cfg *Config) (reterr error) {
} }
r.routes = newRoutes r.routes = newRoutes
if err := r.dns.Set(cfg.DNS); err != nil {
r.logf("DNS set: %v", err)
setErr(err)
}
return errq return errq
} }
func (r *userspaceBSDRouter) Close() error { func (r *userspaceBSDRouter) Close() error {
if err := r.dns.Down(); err != nil {
r.logf("dns down: %v", err)
}
// No interface cleanup is necessary during normal shutdown.
return nil return nil
} }

@ -29,7 +29,6 @@ type winRouter struct {
logf func(fmt string, args ...interface{}) logf func(fmt string, args ...interface{})
nativeTun *tun.NativeTun nativeTun *tun.NativeTun
routeChangeCallback *winipcfg.RouteChangeCallback routeChangeCallback *winipcfg.RouteChangeCallback
dns *dns.Manager
firewall *firewallTweaker firewall *firewallTweaker
// firewallSubproc is a subprocess that runs a tweaked version of // firewallSubproc is a subprocess that runs a tweaked version of
@ -53,7 +52,6 @@ func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
return &winRouter{ return &winRouter{
logf: logf, logf: logf,
nativeTun: nativeTun, nativeTun: nativeTun,
dns: dns.NewManager(logf, guid.String()),
firewall: &firewallTweaker{ firewall: &firewallTweaker{
logf: logger.WithPrefix(logf, "firewall: "), logf: logger.WithPrefix(logf, "firewall: "),
tunGUID: *guid, tunGUID: *guid,
@ -92,10 +90,6 @@ func (r *winRouter) Set(cfg *Config) error {
return err return err
} }
if err := r.dns.Set(cfg.DNS); err != nil {
return fmt.Errorf("dns set: %w", err)
}
// Flush DNS on router config change to clear cached DNS entries (solves #1430) // Flush DNS on router config change to clear cached DNS entries (solves #1430)
if err := dns.Flush(); err != nil { if err := dns.Flush(); err != nil {
r.logf("flushdns error: %v", err) r.logf("flushdns error: %v", err)
@ -116,9 +110,6 @@ func hasDefaultRoute(routes []netaddr.IPPrefix) bool {
func (r *winRouter) Close() error { func (r *winRouter) Close() error {
r.firewall.clear() r.firewall.clear()
if err := r.dns.Down(); err != nil {
return fmt.Errorf("dns down: %w", err)
}
if r.routeChangeCallback != nil { if r.routeChangeCallback != nil {
r.routeChangeCallback.Unregister() r.routeChangeCallback.Unregister()
} }

@ -84,6 +84,7 @@ type userspaceEngine struct {
tundev *tstun.Wrapper tundev *tstun.Wrapper
wgdev *device.Device wgdev *device.Device
router router.Router router router.Router
dns *dns.Manager
resolver *resolver.Resolver resolver *resolver.Resolver
magicConn *magicsock.Conn magicConn *magicsock.Conn
linkMon *monitor.Mon linkMon *monitor.Mon
@ -143,6 +144,10 @@ type Config struct {
// If nil, a fake Router that does nothing is used. // If nil, a fake Router that does nothing is used.
Router router.Router Router router.Router
// DNS interfaces the Engine to the OS DNS resolver configuration.
// If nil, a fake OSConfigurator that does nothing is used.
DNS dns.OSConfigurator
// LinkMonitor optionally provides an existing link monitor to re-use. // LinkMonitor optionally provides an existing link monitor to re-use.
// If nil, a new link monitor is created. // If nil, a new link monitor is created.
LinkMonitor *monitor.Mon LinkMonitor *monitor.Mon
@ -193,6 +198,10 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
logf("[v1] using fake (no-op) OS network configurator") logf("[v1] using fake (no-op) OS network configurator")
conf.Router = router.NewFake(logf) conf.Router = router.NewFake(logf)
} }
if conf.DNS == nil {
logf("[v1] using fake (no-op) DNS configurator")
conf.DNS = dns.NewNoopManager()
}
tsTUNDev := tstun.Wrap(logf, conf.Tun) tsTUNDev := tstun.Wrap(logf, conf.Tun)
closePool.add(tsTUNDev) closePool.add(tsTUNDev)
@ -204,6 +213,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
waitCh: make(chan struct{}), waitCh: make(chan struct{}),
tundev: tsTUNDev, tundev: tsTUNDev,
router: conf.Router, router: conf.Router,
dns: dns.NewManager(logf, conf.DNS),
pingers: make(map[wgkey.Key]*pinger), pingers: make(map[wgkey.Key]*pinger),
} }
e.isLocalAddr.Store(genLocalAddrFunc(nil)) e.isLocalAddr.Store(genLocalAddrFunc(nil))
@ -990,25 +1000,26 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config,
LocalDomains: dnsCfg.AuthoritativeSuffixes, LocalDomains: dnsCfg.AuthoritativeSuffixes,
Routes: map[string][]netaddr.IPPort{}, Routes: map[string][]netaddr.IPPort{},
} }
osCfg := dns.OSConfig{
Domains: dnsCfg.SearchDomains,
}
// 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.
mustProxy := len(dnsCfg.Hosts) > 0 || len(dnsCfg.Routes) > 0 mustProxy := len(dnsCfg.Hosts) > 0 || len(dnsCfg.Routes) > 0
routerCfg.DNS = dns.OSConfig{
Domains: dnsCfg.SearchDomains,
}
if mustProxy { if mustProxy {
routerCfg.DNS.Nameservers = []netaddr.IP{tsaddr.TailscaleServiceIP()} osCfg.Nameservers = []netaddr.IP{tsaddr.TailscaleServiceIP()}
resolverCfg.Routes["."] = dnsCfg.DefaultResolvers resolverCfg.Routes["."] = dnsCfg.DefaultResolvers
for suffix, resolvers := range dnsCfg.Routes { for suffix, resolvers := range dnsCfg.Routes {
resolverCfg.Routes[suffix] = resolvers resolverCfg.Routes[suffix] = resolvers
} }
} else { } else {
for _, resolver := range dnsCfg.DefaultResolvers { for _, resolver := range dnsCfg.DefaultResolvers {
routerCfg.DNS.Nameservers = append(routerCfg.DNS.Nameservers, resolver.IP) osCfg.Nameservers = append(osCfg.Nameservers, resolver.IP)
} }
} }
routerCfg.DNS.Domains = dnsCfg.SearchDomains osCfg.Domains = dnsCfg.SearchDomains
e.resolver.SetConfig(resolverCfg) // TODO: check error and propagate to health pkg e.resolver.SetConfig(resolverCfg) // TODO: check error and propagate to health pkg
e.dns.Set(osCfg) // TODO: check error and propagate to health pkg
e.logf("wgengine: Reconfig: configuring router") e.logf("wgengine: Reconfig: configuring router")
err := e.router.Set(routerCfg) err := e.router.Set(routerCfg)
health.SetRouterHealth(err) health.SetRouterHealth(err)

Loading…
Cancel
Save