mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
cmd/ctrld: use NetworkManager to disable DNS manager
Currently, ctrld force NetworkManager ignore auto DNS setup from DHCP per connection. This does not work well, because an interface can be attached to many connections. So if `ctrld` started with a connection, then user connect to new one, the DNS configured by ctrld will be override. Instead, we can force NetworkManager not to manage DNS by: - Using dns=none - Set systemd-resolved=false So NetworkManager won't attempt to send DNS setup to systemd-resolved, leaving what ctrld set as-is.
This commit is contained in:
committed by
Cuong Manh Le
parent
1c2cd555bd
commit
eb0dd6235e
@@ -228,7 +228,6 @@ func initCLI() {
|
||||
{s.Start, true},
|
||||
}
|
||||
if doTasks(tasks) {
|
||||
disableAutoDNS(iface)
|
||||
prog.setDNS()
|
||||
mainLog.Info().Msg("Service started")
|
||||
}
|
||||
@@ -260,7 +259,6 @@ func initCLI() {
|
||||
}
|
||||
initLogging()
|
||||
if doTasks([]task{{s.Stop, true}}) {
|
||||
enableAutoDNS(iface)
|
||||
prog.resetDNS()
|
||||
mainLog.Info().Msg("Service stopped")
|
||||
}
|
||||
@@ -330,7 +328,6 @@ func initCLI() {
|
||||
}
|
||||
initLogging()
|
||||
if doTasks(tasks) {
|
||||
enableAutoDNS(iface)
|
||||
prog.resetDNS()
|
||||
mainLog.Info().Msg("Service uninstalled")
|
||||
return
|
||||
@@ -551,6 +548,10 @@ func processCDFlags() {
|
||||
}
|
||||
|
||||
if netIface, _ := netInterface(iface); netIface != nil {
|
||||
if err := restoreNetworkManager(); err != nil {
|
||||
logger.Error().Err(err).Msg("could not restore NetworkManager")
|
||||
return
|
||||
}
|
||||
logger.Debug().Str("iface", netIface.Name).Msg("Restoring DNS for interface")
|
||||
if err := resetDNS(netIface); err != nil {
|
||||
logger.Warn().Err(err).Msg("something went wrong while restoring DNS")
|
||||
@@ -558,6 +559,7 @@ func processCDFlags() {
|
||||
logger.Debug().Str("iface", netIface.Name).Msg("Restoring DNS successfully")
|
||||
}
|
||||
}
|
||||
|
||||
tasks := []task{{s.Uninstall, true}}
|
||||
if doTasks(tasks) {
|
||||
logger.Info().Msg("uninstalled service")
|
||||
|
||||
85
cmd/ctrld/network_manager.go
Normal file
85
cmd/ctrld/network_manager.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/go-systemd/v22/dbus"
|
||||
)
|
||||
|
||||
const (
|
||||
nmConfDir = "/etc/NetworkManager/conf.d"
|
||||
nmCtrldConfFilename = "99-ctrld.conf"
|
||||
nmCtrldConfContent = `[main]
|
||||
dns=none
|
||||
systemd-resolved=false
|
||||
`
|
||||
nmSystemdUnitName = "NetworkManager.service"
|
||||
systemdEnabledState = "enabled"
|
||||
)
|
||||
|
||||
var networkManagerCtrldConfFile = filepath.Join(nmConfDir, nmCtrldConfFilename)
|
||||
|
||||
func setupNetworkManager() error {
|
||||
if runtime.GOOS != "linux" {
|
||||
mainLog.Debug().Msg("skipping NetworkManager setup, not on Linux")
|
||||
return nil
|
||||
}
|
||||
if content, _ := os.ReadFile(nmCtrldConfContent); string(content) == nmCtrldConfContent {
|
||||
mainLog.Debug().Msg("NetworkManager already setup, nothing to do")
|
||||
return nil
|
||||
}
|
||||
err := os.WriteFile(networkManagerCtrldConfFile, []byte(nmCtrldConfContent), os.FileMode(0644))
|
||||
if os.IsNotExist(err) {
|
||||
mainLog.Debug().Msg("NetworkManager is not available")
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
mainLog.Debug().Err(err).Msg("could not write NetworkManager ctrld config file")
|
||||
return err
|
||||
}
|
||||
|
||||
reloadNetworkManager()
|
||||
mainLog.Debug().Msg("setup NetworkManager done")
|
||||
return nil
|
||||
}
|
||||
|
||||
func restoreNetworkManager() error {
|
||||
if runtime.GOOS != "linux" {
|
||||
mainLog.Debug().Msg("skipping NetworkManager restoring, not on Linux")
|
||||
return nil
|
||||
}
|
||||
err := os.Remove(networkManagerCtrldConfFile)
|
||||
if os.IsNotExist(err) {
|
||||
mainLog.Debug().Msg("NetworkManager is not available")
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
mainLog.Debug().Err(err).Msg("could not remove NetworkManager ctrld config file")
|
||||
return err
|
||||
}
|
||||
|
||||
reloadNetworkManager()
|
||||
mainLog.Debug().Msg("restore NetworkManager done")
|
||||
return nil
|
||||
}
|
||||
|
||||
func reloadNetworkManager() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
conn, err := dbus.NewSystemConnectionContext(ctx)
|
||||
if err != nil {
|
||||
mainLog.Error().Err(err).Msg("could not create new system connection")
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
waitCh := make(chan string)
|
||||
if _, err := conn.ReloadUnitContext(ctx, nmSystemdUnitName, "ignore-dependencies", waitCh); err != nil {
|
||||
mainLog.Debug().Err(err).Msg("could not reload NetworkManager")
|
||||
}
|
||||
<-waitCh
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"net/netip"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
@@ -175,25 +174,6 @@ func getDNSByNmcli(iface string) []string {
|
||||
return dns
|
||||
}
|
||||
|
||||
func getConnByNmcli(iface string) string {
|
||||
if iface == "auto" {
|
||||
iface = defaultIfaceName()
|
||||
}
|
||||
b, err := exec.Command("nmcli", "dev", "show", iface).Output()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
s := bufio.NewScanner(bytes.NewReader(b))
|
||||
for s.Scan() {
|
||||
line := s.Text()
|
||||
if _, connName, found := strings.Cut(line, "GENERAL.CONNECTION:"); found {
|
||||
return strings.TrimSpace(connName)
|
||||
}
|
||||
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func ignoringEINTR(fn func() error) error {
|
||||
for {
|
||||
err := fn()
|
||||
@@ -202,22 +182,3 @@ func ignoringEINTR(fn func() error) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func disableAutoDNS(iface string) {
|
||||
networkManagerIgnoreAutoDNS(iface, "yes")
|
||||
}
|
||||
|
||||
func enableAutoDNS(iface string) {
|
||||
networkManagerIgnoreAutoDNS(iface, "no")
|
||||
}
|
||||
|
||||
func networkManagerIgnoreAutoDNS(iface, answer string) {
|
||||
if runtime.GOOS != "linux" {
|
||||
return
|
||||
}
|
||||
if connName := getConnByNmcli(iface); connName != "" {
|
||||
mainLog.Debug().Msg("enable auto DNS from network manager")
|
||||
_ = exec.Command("nmcli", "con", "mod", connName, "ipv4.ignore-auto-dns", answer).Run()
|
||||
_ = exec.Command("nmcli", "con", "mod", connName, "ipv6.ignore-auto-dns", answer).Run()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,9 +60,3 @@ func resetDNS(iface *net.Interface) error {
|
||||
func currentDNS(_ *net.Interface) []string {
|
||||
return resolvconffile.NameServers("")
|
||||
}
|
||||
|
||||
func disableAutoDNS(iface string) {
|
||||
}
|
||||
|
||||
func enableAutoDNS(iface string) {
|
||||
}
|
||||
|
||||
@@ -104,9 +104,3 @@ func currentDNS(iface *net.Interface) []string {
|
||||
}
|
||||
return ns
|
||||
}
|
||||
|
||||
func disableAutoDNS(iface string) {
|
||||
}
|
||||
|
||||
func enableAutoDNS(iface string) {
|
||||
}
|
||||
|
||||
@@ -209,6 +209,10 @@ func (p *prog) setDNS() {
|
||||
logger.Error().Err(err).Msg("could not get interface")
|
||||
return
|
||||
}
|
||||
if err := setupNetworkManager(); err != nil {
|
||||
logger.Error().Err(err).Msg("could not patch NetworkManager")
|
||||
return
|
||||
}
|
||||
logger.Debug().Msg("setting DNS for interface")
|
||||
if err := setDNS(netIface, []string{cfg.Listener["0"].IP}); err != nil {
|
||||
logger.Error().Err(err).Msgf("could not set DNS for interface")
|
||||
@@ -230,6 +234,10 @@ func (p *prog) resetDNS() {
|
||||
logger.Error().Err(err).Msg("could not get interface")
|
||||
return
|
||||
}
|
||||
if err := restoreNetworkManager(); err != nil {
|
||||
logger.Error().Err(err).Msg("could not restore NetworkManager")
|
||||
return
|
||||
}
|
||||
logger.Debug().Msg("Restoring DNS for interface")
|
||||
if err := resetDNS(netIface); err != nil {
|
||||
logger.Error().Err(err).Msgf("could not reset DNS")
|
||||
|
||||
1
go.mod
1
go.mod
@@ -3,6 +3,7 @@ module github.com/Control-D-Inc/ctrld
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534
|
||||
github.com/go-playground/validator/v10 v10.11.1
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.1
|
||||
github.com/insomniacslk/dhcp v0.0.0-20211209223715-7d93572ebe8e
|
||||
|
||||
1
go.sum
1
go.sum
@@ -52,6 +52,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 h1:rtAn27wIbmOGUs7RIbVgPEjb31ehTVniDwPGXyMxm5U=
|
||||
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
|
||||
Reference in New Issue
Block a user