mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
all: add firewalla support
This commit is contained in:
committed by
Cuong Manh Le
parent
03781d4cec
commit
350d8355b1
@@ -21,16 +21,17 @@ type readClientInfoFunc func(name string) error
|
||||
|
||||
// clientInfoFiles specifies client info files and how to read them on supported platforms.
|
||||
var clientInfoFiles = map[string]readClientInfoFunc{
|
||||
"/tmp/dnsmasq.leases": dnsmasqReadClientInfoFile, // ddwrt
|
||||
"/tmp/dhcp.leases": dnsmasqReadClientInfoFile, // openwrt
|
||||
"/var/lib/misc/dnsmasq.leases": dnsmasqReadClientInfoFile, // merlin
|
||||
"/mnt/data/udapi-config/dnsmasq.lease": dnsmasqReadClientInfoFile, // UDM Pro
|
||||
"/data/udapi-config/dnsmasq.lease": dnsmasqReadClientInfoFile, // UDR
|
||||
"/etc/dhcpd/dhcpd-leases.log": dnsmasqReadClientInfoFile, // Synology
|
||||
"/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
|
||||
"/tmp/dnsmasq.leases": dnsmasqReadClientInfoFile, // ddwrt
|
||||
"/tmp/dhcp.leases": dnsmasqReadClientInfoFile, // openwrt
|
||||
"/var/lib/misc/dnsmasq.leases": dnsmasqReadClientInfoFile, // merlin
|
||||
"/mnt/data/udapi-config/dnsmasq.lease": dnsmasqReadClientInfoFile, // UDM Pro
|
||||
"/data/udapi-config/dnsmasq.lease": dnsmasqReadClientInfoFile, // UDR
|
||||
"/etc/dhcpd/dhcpd-leases.log": dnsmasqReadClientInfoFile, // Synology
|
||||
"/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
|
||||
"/home/pi/.router/run/dhcp/dnsmasq.leases": dnsmasqReadClientInfoFile, // Firewalla
|
||||
}
|
||||
|
||||
// watchClientInfoTable watches changes happens in dnsmasq/dhcpd
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
@@ -49,8 +50,10 @@ func dnsMasqConf() (string, error) {
|
||||
var sb strings.Builder
|
||||
var tmplText string
|
||||
switch Name() {
|
||||
case EdgeOS, DDWrt, OpenWrt, Ubios, Synology, Tomato:
|
||||
case DDWrt, EdgeOS, OpenWrt, Ubios, Synology, Tomato:
|
||||
tmplText = dnsMasqConfigContentTmpl
|
||||
case Firewalla:
|
||||
tmplText = dnsMasqConfigContentTmpl + fmt.Sprintf("listen-address=127.0.0.1\n")
|
||||
case Merlin:
|
||||
tmplText = merlinDNSMasqPostConfTmpl
|
||||
}
|
||||
@@ -68,10 +71,12 @@ func dnsMasqConf() (string, error) {
|
||||
|
||||
func restartDNSMasq() error {
|
||||
switch Name() {
|
||||
case EdgeOS:
|
||||
return edgeOSRestartDNSMasq()
|
||||
case DDWrt:
|
||||
return ddwrtRestartDNSMasq()
|
||||
case EdgeOS:
|
||||
return edgeOSRestartDNSMasq()
|
||||
case Firewalla:
|
||||
return firewallaRestartDNSMasq()
|
||||
case Merlin:
|
||||
return merlinRestartDNSMasq()
|
||||
case OpenWrt:
|
||||
|
||||
103
internal/router/firewalla.go
Normal file
103
internal/router/firewalla.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
firewallaDNSMasqConfigPath = "/home/pi/.firewalla/config/dnsmasq_local"
|
||||
firewallaDNSMasqBackupConfigPath = "/home/pi/.firewalla/config/dnsmasq_local.bak"
|
||||
firewallaConfigPostMainDir = "/home/pi/.firewalla/config/post_main.d"
|
||||
firewallaCtrldInitScriptPath = "/home/pi/.firewalla/config/post_main.d/start_ctrld.sh"
|
||||
)
|
||||
|
||||
func setupFirewalla() error {
|
||||
fi, err := os.Stat(firewallaDNSMasqConfigPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("setupFirewalla: get current config directory: %w", err)
|
||||
}
|
||||
|
||||
_ = os.RemoveAll(firewallaDNSMasqBackupConfigPath)
|
||||
|
||||
// Creating a backup.
|
||||
if err := os.Rename(firewallaDNSMasqConfigPath, firewallaDNSMasqBackupConfigPath); err != nil {
|
||||
return fmt.Errorf("setupFirewalla: backup current config: %w", err)
|
||||
}
|
||||
|
||||
// Creating our own config.
|
||||
if err := os.MkdirAll(firewallaDNSMasqConfigPath, fi.Mode()); err != nil {
|
||||
return fmt.Errorf("setupFirewalla: creating config dir: %w", err)
|
||||
}
|
||||
|
||||
// Adding ctrld listener as the only upstream.
|
||||
dnsMasqConfigContent, err := dnsMasqConf()
|
||||
if err != nil {
|
||||
return fmt.Errorf("setupFirewalla: generating dnsmasq config: %w", err)
|
||||
}
|
||||
ctrldConfPath := filepath.Join(firewallaDNSMasqConfigPath, "ctrld")
|
||||
if err := os.WriteFile(ctrldConfPath, []byte(dnsMasqConfigContent), 0600); err != nil {
|
||||
return fmt.Errorf("setupFirewalla: writing ctrld config: %w", err)
|
||||
}
|
||||
|
||||
// Restart dnsmasq service.
|
||||
if err := restartDNSMasq(); err != nil {
|
||||
return fmt.Errorf("setupFirewalla: restartDNSMasq: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func cleanupFirewalla() error {
|
||||
// Do nothing if there's no backup config.
|
||||
if _, err := os.Stat(firewallaDNSMasqBackupConfigPath); err != nil && os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Removing current config.
|
||||
if err := os.RemoveAll(firewallaDNSMasqConfigPath); err != nil {
|
||||
return fmt.Errorf("cleanupFirewalla: removing ctrld config: %w", err)
|
||||
}
|
||||
|
||||
// Restoring backup.
|
||||
if err := os.Rename(firewallaDNSMasqBackupConfigPath, firewallaDNSMasqConfigPath); err != nil {
|
||||
return fmt.Errorf("cleanupFirewalla: restoring backup config: %w", err)
|
||||
}
|
||||
|
||||
// Restart dnsmasq service.
|
||||
if err := restartDNSMasq(); err != nil {
|
||||
return fmt.Errorf("cleaupFirewalla: restartDNSMasq: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func postInstallFirewalla() error {
|
||||
// Writing startup script.
|
||||
if err := writeFirewallStartupScript(); err != nil {
|
||||
return fmt.Errorf("postInstallFirewalla: writing startup script: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func firewallaRestartDNSMasq() error {
|
||||
return exec.Command("systemctl", "restart", "firerouter_dns").Run()
|
||||
}
|
||||
|
||||
func writeFirewallStartupScript() error {
|
||||
if err := os.MkdirAll(firewallaConfigPostMainDir, 0775); err != nil {
|
||||
return err
|
||||
}
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// This is called when "ctrld start ..." runs, so recording
|
||||
// the same command line arguments to use in startup script.
|
||||
argStr := strings.Join(os.Args[1:], " ")
|
||||
script := fmt.Sprintf("#!/bin/bash\n\nsudo %q %s\n", exe, argStr)
|
||||
return os.WriteFile(firewallaCtrldInitScriptPath, []byte(script), 0755)
|
||||
}
|
||||
@@ -19,14 +19,15 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
OpenWrt = "openwrt"
|
||||
DDWrt = "ddwrt"
|
||||
Merlin = "merlin"
|
||||
Ubios = "ubios"
|
||||
Synology = "synology"
|
||||
Tomato = "tomato"
|
||||
EdgeOS = "edgeos"
|
||||
Pfsense = "pfsense"
|
||||
DDWrt = "ddwrt"
|
||||
EdgeOS = "edgeos"
|
||||
Firewalla = "firewalla"
|
||||
Merlin = "merlin"
|
||||
OpenWrt = "openwrt"
|
||||
Pfsense = "pfsense"
|
||||
Synology = "synology"
|
||||
Tomato = "tomato"
|
||||
Ubios = "ubios"
|
||||
)
|
||||
|
||||
// ErrNotSupported reports the current router is not supported error.
|
||||
@@ -44,7 +45,15 @@ 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, Pfsense, Synology, Tomato, Ubios:
|
||||
case DDWrt,
|
||||
EdgeOS,
|
||||
Firewalla,
|
||||
Merlin,
|
||||
OpenWrt,
|
||||
Pfsense,
|
||||
Synology,
|
||||
Tomato,
|
||||
Ubios:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -52,25 +61,44 @@ 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, Pfsense, Synology, Tomato, Ubios}
|
||||
return []string{
|
||||
DDWrt,
|
||||
EdgeOS,
|
||||
Firewalla,
|
||||
Merlin,
|
||||
OpenWrt,
|
||||
Pfsense,
|
||||
Synology,
|
||||
Tomato,
|
||||
Ubios,
|
||||
}
|
||||
}
|
||||
|
||||
var configureFunc = map[string]func() error{
|
||||
EdgeOS: setupEdgeOS,
|
||||
DDWrt: setupDDWrt,
|
||||
Merlin: setupMerlin,
|
||||
OpenWrt: setupOpenWrt,
|
||||
Pfsense: setupPfsense,
|
||||
Synology: setupSynology,
|
||||
Tomato: setupTomato,
|
||||
Ubios: setupUbiOS,
|
||||
DDWrt: setupDDWrt,
|
||||
EdgeOS: setupEdgeOS,
|
||||
Firewalla: setupFirewalla,
|
||||
Merlin: setupMerlin,
|
||||
OpenWrt: setupOpenWrt,
|
||||
Pfsense: setupPfsense,
|
||||
Synology: setupSynology,
|
||||
Tomato: setupTomato,
|
||||
Ubios: setupUbiOS,
|
||||
}
|
||||
|
||||
// Configure configures things for running ctrld on the router.
|
||||
func Configure(c *ctrld.Config) error {
|
||||
name := Name()
|
||||
switch name {
|
||||
case EdgeOS, DDWrt, Merlin, OpenWrt, Pfsense, Synology, Tomato, Ubios:
|
||||
case DDWrt,
|
||||
EdgeOS,
|
||||
Firewalla,
|
||||
Merlin,
|
||||
OpenWrt,
|
||||
Pfsense,
|
||||
Synology,
|
||||
Tomato,
|
||||
Ubios:
|
||||
if c.HasUpstreamSendClientInfo() {
|
||||
r := routerPlatform.Load()
|
||||
r.sendClientInfo = true
|
||||
@@ -107,7 +135,7 @@ func ConfigureService(sc *service.Config) error {
|
||||
sc.Option["SysvScript"] = openWrtScript
|
||||
case Pfsense:
|
||||
sc.Option["SysvScript"] = pfsenseInitScript
|
||||
case EdgeOS, Merlin, Synology, Tomato, Ubios:
|
||||
case EdgeOS, Firewalla, Merlin, Synology, Tomato, Ubios:
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -138,10 +166,12 @@ func PreRun() (err error) {
|
||||
func PostInstall(svc *service.Config) error {
|
||||
name := Name()
|
||||
switch name {
|
||||
case EdgeOS:
|
||||
return postInstallEdgeOS()
|
||||
case DDWrt:
|
||||
return postInstallDDWrt()
|
||||
case EdgeOS:
|
||||
return postInstallEdgeOS()
|
||||
case Firewalla:
|
||||
return postInstallFirewalla()
|
||||
case Merlin:
|
||||
return postInstallMerlin()
|
||||
case OpenWrt:
|
||||
@@ -162,10 +192,12 @@ func PostInstall(svc *service.Config) error {
|
||||
func Cleanup(svc *service.Config) error {
|
||||
name := Name()
|
||||
switch name {
|
||||
case EdgeOS:
|
||||
return cleanupEdgeOS()
|
||||
case DDWrt:
|
||||
return cleanupDDWrt()
|
||||
case EdgeOS:
|
||||
return cleanupEdgeOS()
|
||||
case Firewalla:
|
||||
return cleanupFirewalla()
|
||||
case Merlin:
|
||||
return cleanupMerlin()
|
||||
case OpenWrt:
|
||||
@@ -186,7 +218,7 @@ func Cleanup(svc *service.Config) error {
|
||||
func ListenAddress() string {
|
||||
name := Name()
|
||||
switch name {
|
||||
case EdgeOS, DDWrt, Merlin, OpenWrt, Synology, Tomato, Ubios:
|
||||
case DDWrt, Firewalla, Merlin, OpenWrt, Synology, Tomato, Ubios:
|
||||
return "127.0.0.1:5354"
|
||||
case Pfsense:
|
||||
// On pfsense, we run ctrld as DNS resolver.
|
||||
@@ -227,6 +259,8 @@ func distroName() string {
|
||||
return EdgeOS // For 2.x
|
||||
case isPfsense():
|
||||
return Pfsense
|
||||
case haveFile("/etc/firewalla_release"):
|
||||
return Firewalla
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user