mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-07-04 01:07:49 +02:00
all: preserve search domains settings
So bare hostname will be resolved as expected when ctrld is running.
This commit is contained in:
committed by
Cuong Manh Le
parent
00e9d2bdd3
commit
62f73bcaa2
@@ -47,6 +47,9 @@ func setDnsIgnoreUnusableInterface(iface *net.Interface, nameservers []string) e
|
|||||||
// networksetup -setdnsservers Wi-Fi 8.8.8.8 1.1.1.1
|
// networksetup -setdnsservers Wi-Fi 8.8.8.8 1.1.1.1
|
||||||
// TODO(cuonglm): use system API
|
// TODO(cuonglm): use system API
|
||||||
func setDNS(iface *net.Interface, nameservers []string) error {
|
func setDNS(iface *net.Interface, nameservers []string) error {
|
||||||
|
// Note that networksetup won't modify search domains settings,
|
||||||
|
// This assignment is just a placeholder to silent linter.
|
||||||
|
_ = searchDomains
|
||||||
cmd := "networksetup"
|
cmd := "networksetup"
|
||||||
args := []string{"-setdnsservers", iface.Name}
|
args := []string{"-setdnsservers", iface.Name}
|
||||||
args = append(args, nameservers...)
|
args = append(args, nameservers...)
|
||||||
@@ -88,7 +91,7 @@ func restoreDNS(iface *net.Interface) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func currentDNS(_ *net.Interface) []string {
|
func currentDNS(_ *net.Interface) []string {
|
||||||
return resolvconffile.NameServers("")
|
return resolvconffile.NameServers()
|
||||||
}
|
}
|
||||||
|
|
||||||
// currentStaticDNS returns the current static DNS settings of given interface.
|
// currentStaticDNS returns the current static DNS settings of given interface.
|
||||||
|
|||||||
+13
-2
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"tailscale.com/control/controlknobs"
|
"tailscale.com/control/controlknobs"
|
||||||
"tailscale.com/health"
|
"tailscale.com/health"
|
||||||
|
"tailscale.com/util/dnsname"
|
||||||
|
|
||||||
"github.com/Control-D-Inc/ctrld/internal/dns"
|
"github.com/Control-D-Inc/ctrld/internal/dns"
|
||||||
"github.com/Control-D-Inc/ctrld/internal/resolvconffile"
|
"github.com/Control-D-Inc/ctrld/internal/resolvconffile"
|
||||||
@@ -50,7 +51,17 @@ func setDNS(iface *net.Interface, nameservers []string) error {
|
|||||||
ns = append(ns, netip.MustParseAddr(nameserver))
|
ns = append(ns, netip.MustParseAddr(nameserver))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.SetDNS(dns.OSConfig{Nameservers: ns}); err != nil {
|
osConfig := dns.OSConfig{
|
||||||
|
Nameservers: ns,
|
||||||
|
SearchDomains: []dnsname.FQDN{},
|
||||||
|
}
|
||||||
|
if sds, err := searchDomains(); err == nil {
|
||||||
|
osConfig.SearchDomains = sds
|
||||||
|
} else {
|
||||||
|
mainLog.Load().Debug().Err(err).Msg("failed to get search domains list")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := r.SetDNS(osConfig); err != nil {
|
||||||
mainLog.Load().Error().Err(err).Msg("failed to set DNS")
|
mainLog.Load().Error().Err(err).Msg("failed to set DNS")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -83,7 +94,7 @@ func restoreDNS(iface *net.Interface) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func currentDNS(_ *net.Interface) []string {
|
func currentDNS(_ *net.Interface) []string {
|
||||||
return resolvconffile.NameServers("")
|
return resolvconffile.NameServers()
|
||||||
}
|
}
|
||||||
|
|
||||||
// currentStaticDNS returns the current static DNS settings of given interface.
|
// currentStaticDNS returns the current static DNS settings of given interface.
|
||||||
|
|||||||
+7
-1
@@ -71,6 +71,11 @@ func setDNS(iface *net.Interface, nameservers []string) error {
|
|||||||
Nameservers: ns,
|
Nameservers: ns,
|
||||||
SearchDomains: []dnsname.FQDN{},
|
SearchDomains: []dnsname.FQDN{},
|
||||||
}
|
}
|
||||||
|
if sds, err := searchDomains(); err == nil {
|
||||||
|
osConfig.SearchDomains = sds
|
||||||
|
} else {
|
||||||
|
mainLog.Load().Debug().Err(err).Msg("failed to get search domains list")
|
||||||
|
}
|
||||||
trySystemdResolve := false
|
trySystemdResolve := false
|
||||||
if err := r.SetDNS(osConfig); err != nil {
|
if err := r.SetDNS(osConfig); err != nil {
|
||||||
if strings.Contains(err.Error(), "Rejected send message") &&
|
if strings.Contains(err.Error(), "Rejected send message") &&
|
||||||
@@ -196,7 +201,8 @@ func restoreDNS(iface *net.Interface) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func currentDNS(iface *net.Interface) []string {
|
func currentDNS(iface *net.Interface) []string {
|
||||||
for _, fn := range []getDNS{getDNSByResolvectl, getDNSBySystemdResolved, getDNSByNmcli, resolvconffile.NameServers} {
|
resolvconfFunc := func(_ string) []string { return resolvconffile.NameServers() }
|
||||||
|
for _, fn := range []getDNS{getDNSByResolvectl, getDNSBySystemdResolved, getDNSByNmcli, resolvconfFunc} {
|
||||||
if ns := fn(iface.Name); len(ns) > 0 {
|
if ns := fn(iface.Name); len(ns) > 0 {
|
||||||
return ns
|
return ns
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,6 +100,10 @@ func setDNS(iface *net.Interface, nameservers []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note that Windows won't modify the current search domains if passing nil to luid.SetDNS function.
|
||||||
|
// searchDomains is still implemented for Windows just in case Windows API changes in future versions.
|
||||||
|
_ = searchDomains
|
||||||
|
|
||||||
if len(serversV4) == 0 && len(serversV6) == 0 {
|
if len(serversV4) == 0 && len(serversV6) == 0 {
|
||||||
return errors.New("invalid DNS nameservers")
|
return errors.New("invalid DNS nameservers")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
//go:build unix
|
||||||
|
|
||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"tailscale.com/util/dnsname"
|
||||||
|
|
||||||
|
"github.com/Control-D-Inc/ctrld/internal/resolvconffile"
|
||||||
|
)
|
||||||
|
|
||||||
|
// searchDomains returns the current search domains config.
|
||||||
|
func searchDomains() ([]dnsname.FQDN, error) {
|
||||||
|
return resolvconffile.SearchDomains()
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
||||||
|
"tailscale.com/util/dnsname"
|
||||||
|
)
|
||||||
|
|
||||||
|
// searchDomains returns the current search domains config.
|
||||||
|
func searchDomains() ([]dnsname.FQDN, error) {
|
||||||
|
flags := winipcfg.GAAFlagIncludeGateways |
|
||||||
|
winipcfg.GAAFlagIncludePrefix
|
||||||
|
|
||||||
|
aas, err := winipcfg.GetAdaptersAddresses(syscall.AF_UNSPEC, flags)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("winipcfg.GetAdaptersAddresses: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var sds []dnsname.FQDN
|
||||||
|
for _, aa := range aas {
|
||||||
|
if aa.OperStatus != winipcfg.IfOperStatusUp {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip if software loopback or other non-physical types
|
||||||
|
// This is to avoid the "Loopback Pseudo-Interface 1" issue we see on windows
|
||||||
|
if aa.IfType == winipcfg.IfTypeSoftwareLoopback {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for a := aa.FirstDNSSuffix; a != nil; a = a.Next {
|
||||||
|
d, err := dnsname.ToFQDN(a.String())
|
||||||
|
if err != nil {
|
||||||
|
mainLog.Load().Debug().Err(err).Msgf("failed to parse domain: %s", a.String())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sds = append(sds, d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sds, nil
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
|
|
||||||
"tailscale.com/net/dns/resolvconffile"
|
"tailscale.com/net/dns/resolvconffile"
|
||||||
|
"tailscale.com/util/dnsname"
|
||||||
)
|
)
|
||||||
|
|
||||||
const resolvconfPath = "/etc/resolv.conf"
|
const resolvconfPath = "/etc/resolv.conf"
|
||||||
@@ -22,7 +23,7 @@ func NameServersWithPort() []string {
|
|||||||
return ns
|
return ns
|
||||||
}
|
}
|
||||||
|
|
||||||
func NameServers(_ string) []string {
|
func NameServers() []string {
|
||||||
c, err := resolvconffile.ParseFile(resolvconfPath)
|
c, err := resolvconffile.ParseFile(resolvconfPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -33,3 +34,12 @@ func NameServers(_ string) []string {
|
|||||||
}
|
}
|
||||||
return ns
|
return ns
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SearchDomains returns the current search domains config in /etc/resolv.conf file.
|
||||||
|
func SearchDomains() ([]dnsname.FQDN, error) {
|
||||||
|
c, err := resolvconffile.ParseFile(resolvconfPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c.SearchDomains, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNameServers(t *testing.T) {
|
func TestNameServers(t *testing.T) {
|
||||||
ns := NameServers("")
|
ns := NameServers()
|
||||||
require.NotNil(t, ns)
|
require.NotNil(t, ns)
|
||||||
t.Log(ns)
|
t.Log(ns)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
// currentNameserversFromResolvconf returns the current nameservers set from /etc/resolv.conf file.
|
// currentNameserversFromResolvconf returns the current nameservers set from /etc/resolv.conf file.
|
||||||
func currentNameserversFromResolvconf() []string {
|
func currentNameserversFromResolvconf() []string {
|
||||||
return resolvconffile.NameServers("")
|
return resolvconffile.NameServers()
|
||||||
}
|
}
|
||||||
|
|
||||||
// dnsFromResolvConf reads usable nameservers from /etc/resolv.conf file.
|
// dnsFromResolvConf reads usable nameservers from /etc/resolv.conf file.
|
||||||
@@ -34,7 +34,7 @@ func dnsFromResolvConf() []string {
|
|||||||
time.Sleep(retryInterval)
|
time.Sleep(retryInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
nss := resolvconffile.NameServers("")
|
nss := resolvconffile.NameServers()
|
||||||
var localDNS []string
|
var localDNS []string
|
||||||
seen := make(map[string]bool)
|
seen := make(map[string]bool)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user