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 }