From 929de49c7b5b28e29d9b7fc39358ce66dab43c4d Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Wed, 7 Jun 2023 23:00:45 +0700 Subject: [PATCH] cmd/ctrld: only spawn DNS server for ntpd if necessary On some platforms, like pfsense, ntpd is not problem, so do not spawn the DNS server for it, which may conflict with default DNS server. While at it, also make sure that ctrld will be run at last on startup. --- cmd/ctrld/cli.go | 4 ++-- cmd/ctrld/dns_proxy.go | 7 +++++-- internal/router/pfsense.go | 42 +++++++++++++++++++++++--------------- internal/router/router.go | 4 +++- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/cmd/ctrld/cli.go b/cmd/ctrld/cli.go index aaa720f..8cfca02 100644 --- a/cmd/ctrld/cli.go +++ b/cmd/ctrld/cli.go @@ -165,11 +165,11 @@ func initCLI() { initLogging() if setupRouter { - s, _ := runDNSServerForNTPD() + s, errCh := runDNSServerForNTPD(router.ListenAddress()) if err := router.PreRun(); err != nil { mainLog.Fatal().Err(err).Msg("failed to perform router pre-start check") } - if err := s.Shutdown(); err != nil { + if err := s.Shutdown(); err != nil && errCh != nil { mainLog.Fatal().Err(err).Msg("failed to shutdown dns server for ntpd") } } diff --git a/cmd/ctrld/dns_proxy.go b/cmd/ctrld/dns_proxy.go index c7cc7a1..9f9fa30 100644 --- a/cmd/ctrld/dns_proxy.go +++ b/cmd/ctrld/dns_proxy.go @@ -473,10 +473,13 @@ func runDNSServer(addr, network string, handler dns.Handler) (*dns.Server, <-cha // runDNSServerForNTPD starts a DNS server listening on router.ListenAddress(). It must only be called when ctrld // running on router, before router.PreRun() to serve DNS request for NTP synchronization. The caller must call // s.Shutdown() explicitly when NTP is synced successfully. -func runDNSServerForNTPD() (*dns.Server, <-chan error) { +func runDNSServerForNTPD(addr string) (*dns.Server, <-chan error) { + if addr == "" { + return &dns.Server{}, nil + } dnsResolver := ctrld.NewBootstrapResolver() s := &dns.Server{ - Addr: router.ListenAddress(), + Addr: addr, Net: "udp", Handler: dns.HandlerFunc(func(w dns.ResponseWriter, m *dns.Msg) { mainLog.Debug().Msg("Serving query for ntpd") diff --git a/internal/router/pfsense.go b/internal/router/pfsense.go index bae3dc2..689cc7b 100644 --- a/internal/router/pfsense.go +++ b/internal/router/pfsense.go @@ -12,21 +12,15 @@ import ( const ( rcPath = "/usr/local/etc/rc.d" unboundRcPath = rcPath + "/unbound" + dnsmasqRcPath = rcPath + "/dnsmasq" ) func setupPfsense() error { // If Pfsense is in DNS Resolver mode, ensure no unbound processes running. - if _, err := exec.Command("service", "unbound", "onestatus").CombinedOutput(); err == nil { - if out, err := exec.Command("killall", "unbound").CombinedOutput(); err != nil { - return fmt.Errorf("could not killall unbound: %s: %w", string(out), err) - } - } + _ = exec.Command("killall", "unbound").Run() + // If Pfsense is in DNS Forwarder mode, ensure no dnsmasq processes running. - if _, err := exec.Command("service", "dnsmasq", "onestatus").CombinedOutput(); err == nil { - if out, err := exec.Command("killall", "dnsmasq").CombinedOutput(); err != nil { - return fmt.Errorf("could not killall unbound: %s: %w", string(out), err) - } - } + _ = exec.Command("killall", "dnsmasq") return nil } @@ -34,12 +28,9 @@ func cleanupPfsense(svc *service.Config) error { if err := os.Remove(filepath.Join(rcPath, svc.Name+".sh")); err != nil { return fmt.Errorf("os.Remove: %w", err) } - if out, err := exec.Command(unboundRcPath, "onerestart").CombinedOutput(); err != nil { - return fmt.Errorf("could not restart unbound: %s: %w", string(out), err) - } - if out, err := exec.Command(unboundRcPath, "onerestart").CombinedOutput(); err != nil { - return fmt.Errorf("could not restart unbound: %s: %w", string(out), err) - } + _ = exec.Command(unboundRcPath, "onerestart").Run() + _ = exec.Command(dnsmasqRcPath, "onerestart").Run() + return nil } @@ -54,3 +45,22 @@ func postInstallPfsense(svc *service.Config) error { } return nil } + +const pfsenseInitScript = `#!/bin/sh + +# PROVIDE: {{.Name}} +# REQUIRE: SERVERS +# REQUIRE: unbound dnsmasq securelevel +# KEYWORD: shutdown + +. /etc/rc.subr + +name="{{.Name}}" +{{.Name}}_env="IS_DAEMON=1" +pidfile="/var/run/${name}.pid" +command="/usr/sbin/daemon" +daemon_args="-P ${pidfile} -r -t \"${name}: daemon\"{{if .WorkingDirectory}} -c {{.WorkingDirectory}}{{end}}" +command_args="${daemon_args} {{.Path}}{{range .Arguments}} {{.}}{{end}}" + +run_rc_command "$1" +` diff --git a/internal/router/router.go b/internal/router/router.go index 2a36253..f9b8be8 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -105,7 +105,9 @@ func ConfigureService(sc *service.Config) error { } case OpenWrt: sc.Option["SysvScript"] = openWrtScript - case EdgeOS, Merlin, Pfsense, Synology, Tomato, Ubios: + case Pfsense: + sc.Option["SysvScript"] = pfsenseInitScript + case EdgeOS, Merlin, Synology, Tomato, Ubios: } return nil }