all: add support for pfsense

This commit is contained in:
Cuong Manh Le
2023-05-29 23:16:23 +07:00
committed by Cuong Manh Le
parent 8fda856e24
commit b143e46eb0
6 changed files with 83 additions and 9 deletions

View File

@@ -312,7 +312,7 @@ func initCLI() {
{s.Start, true},
}
if doTasks(tasks) {
if err := router.PostInstall(); err != nil {
if err := router.PostInstall(svcConfig); err != nil {
mainLog.Warn().Err(err).Msg("post installation failed, please check system/service log for details error")
return
}
@@ -468,7 +468,7 @@ NOTE: Uninstalling will set DNS to values provided by DHCP.`,
}
prog.resetDNS()
mainLog.Debug().Msg("Router cleanup")
if err := router.Cleanup(); err != nil {
if err := router.Cleanup(svcConfig); err != nil {
mainLog.Warn().Err(err).Msg("could not cleanup router")
}
mainLog.Notice().Msg("Service uninstalled")

View File

@@ -1,3 +1,5 @@
//go:build linux || freebsd
package main
import (

View File

@@ -1,4 +1,4 @@
//go:build !linux
//go:build !linux && !freebsd
package main

View File

@@ -28,6 +28,7 @@ var clientInfoFiles = map[string]readClientInfoFunc{
"/tmp/var/lib/misc/dnsmasq.leases": dnsmasqReadClientInfoFile, // Tomato
"/run/dnsmasq-dhcp.leases": dnsmasqReadClientInfoFile, // EdgeOS
"/run/dhcpd.leases": iscDHCPReadClientInfoFile, // EdgeOS
"/var/dhcpd/var/db/dhcpd.leases": iscDHCPReadClientInfoFile, // Pfsense
}
func (r *router) watchClientInfoTable() {

View File

@@ -0,0 +1,56 @@
package router
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"github.com/kardianos/service"
)
const (
rcPath = "/usr/local/etc/rc.d"
unboundRcPath = rcPath + "/unbound"
)
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)
}
}
// 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)
}
}
return nil
}
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)
}
return nil
}
func postInstallPfsense(svc *service.Config) error {
// pfsense need ".sh" extension for script to be run at boot.
// See: https://docs.netgate.com/pfsense/en/latest/development/boot-commands.html#shell-script-option
oldname := filepath.Join(rcPath, svc.Name)
newname := filepath.Join(rcPath, svc.Name+".sh")
_ = os.Remove(newname)
if err := os.Symlink(oldname, newname); err != nil {
return fmt.Errorf("os.Symlink: %w", err)
}
return nil
}

View File

@@ -22,6 +22,7 @@ const (
Synology = "synology"
Tomato = "tomato"
EdgeOS = "edgeos"
Pfsense = "pfsense"
)
// ErrNotSupported reports the current router is not supported error.
@@ -39,7 +40,7 @@ type router struct {
// IsSupported reports whether the given platform is supported by ctrld.
func IsSupported(platform string) bool {
switch platform {
case EdgeOS, DDWrt, Merlin, OpenWrt, Synology, Tomato, Ubios:
case EdgeOS, DDWrt, Merlin, OpenWrt, Pfsense, Synology, Tomato, Ubios:
return true
}
return false
@@ -47,7 +48,7 @@ func IsSupported(platform string) bool {
// SupportedPlatforms return all platforms that can be configured to run with ctrld.
func SupportedPlatforms() []string {
return []string{EdgeOS, DDWrt, Merlin, OpenWrt, Synology, Tomato, Ubios}
return []string{EdgeOS, DDWrt, Merlin, OpenWrt, Pfsense, Synology, Tomato, Ubios}
}
var configureFunc = map[string]func() error{
@@ -55,6 +56,7 @@ var configureFunc = map[string]func() error{
DDWrt: setupDDWrt,
Merlin: setupMerlin,
OpenWrt: setupOpenWrt,
Pfsense: setupPfsense,
Synology: setupSynology,
Tomato: setupTomato,
Ubios: setupUbiOS,
@@ -64,7 +66,7 @@ var configureFunc = map[string]func() error{
func Configure(c *ctrld.Config) error {
name := Name()
switch name {
case EdgeOS, DDWrt, Merlin, OpenWrt, Synology, Tomato, Ubios:
case EdgeOS, DDWrt, Merlin, OpenWrt, Pfsense, Synology, Tomato, Ubios:
if c.HasUpstreamSendClientInfo() {
r := routerPlatform.Load()
r.sendClientInfo = true
@@ -99,7 +101,7 @@ func ConfigureService(sc *service.Config) error {
}
case OpenWrt:
sc.Option["SysvScript"] = openWrtScript
case EdgeOS, Merlin, Synology, Tomato, Ubios:
case EdgeOS, Merlin, Pfsense, Synology, Tomato, Ubios:
}
return nil
}
@@ -118,7 +120,7 @@ func PreStart() (err error) {
}
// PostInstall performs task after installing ctrld on router.
func PostInstall() error {
func PostInstall(svc *service.Config) error {
name := Name()
switch name {
case EdgeOS:
@@ -129,6 +131,8 @@ func PostInstall() error {
return postInstallMerlin()
case OpenWrt:
return postInstallOpenWrt()
case Pfsense:
return postInstallPfsense(svc)
case Synology:
return postInstallSynology()
case Tomato:
@@ -140,7 +144,7 @@ func PostInstall() error {
}
// Cleanup cleans ctrld setup on the router.
func Cleanup() error {
func Cleanup(svc *service.Config) error {
name := Name()
switch name {
case EdgeOS:
@@ -151,6 +155,8 @@ func Cleanup() error {
return cleanupMerlin()
case OpenWrt:
return cleanupOpenWrt()
case Pfsense:
return cleanupPfsense(svc)
case Synology:
return cleanupSynology()
case Tomato:
@@ -167,6 +173,8 @@ func ListenAddress() string {
switch name {
case EdgeOS, DDWrt, Merlin, OpenWrt, Synology, Tomato, Ubios:
return "127.0.0.1:5354"
case Pfsense:
// On pfsense, we run ctrld as DNS resolver.
}
return ""
}
@@ -200,6 +208,8 @@ func distroName() string {
return EdgeOS
case haveFile("/etc/ubnt/init/vyatta-router"):
return EdgeOS // For 2.x
case isPfsense():
return Pfsense
}
return ""
}
@@ -223,3 +233,8 @@ func unameU() []byte {
out, _ := exec.Command("uname", "-u").Output()
return out
}
func isPfsense() bool {
b, err := os.ReadFile("/etc/platform")
return err == nil && bytes.HasPrefix(b, []byte("pfSense"))
}