From 59dc74ffbbbfe404b414b00dd6043af9133ecd23 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Tue, 25 Jul 2023 20:28:30 +0000 Subject: [PATCH] internal: record correct interfaces for queries from router on Firewalla --- internal/clientinfo/dhcp.go | 23 +++++++++++-- internal/router/dnsmasq/dnsmasq.go | 52 ++++++++++++++++++------------ internal/router/router.go | 10 ++++++ 3 files changed, 62 insertions(+), 23 deletions(-) diff --git a/internal/clientinfo/dhcp.go b/internal/clientinfo/dhcp.go index bcad26a..ad423bd 100644 --- a/internal/clientinfo/dhcp.go +++ b/internal/clientinfo/dhcp.go @@ -11,11 +11,12 @@ import ( "strings" "sync" - "github.com/Control-D-Inc/ctrld" + "github.com/fsnotify/fsnotify" "tailscale.com/net/interfaces" "tailscale.com/util/lineread" - "github.com/fsnotify/fsnotify" + "github.com/Control-D-Inc/ctrld" + "github.com/Control-D-Inc/ctrld/internal/router" ) type dhcp struct { @@ -279,4 +280,22 @@ func (d *dhcp) addSelf() { } } }) + for _, netIface := range router.SelfInterfaces() { + mac := netIface.HardwareAddr.String() + if mac == "" { + return + } + d.mac2name.Store(mac, hostname) + addrs, _ := netIface.Addrs() + for _, addr := range addrs { + ipNet, ok := addr.(*net.IPNet) + if !ok { + continue + } + ip := ipNet.IP + d.mac.LoadOrStore(ip.String(), mac) + d.ip.LoadOrStore(mac, ip.String()) + d.ip2name.Store(ip.String(), hostname) + } + } } diff --git a/internal/router/dnsmasq/dnsmasq.go b/internal/router/dnsmasq/dnsmasq.go index 0b051aa..a25f564 100644 --- a/internal/router/dnsmasq/dnsmasq.go +++ b/internal/router/dnsmasq/dnsmasq.go @@ -13,7 +13,7 @@ import ( const ConfigContentTmpl = `# GENERATED BY ctrld - DO NOT MODIFY no-resolv {{- range .Upstreams}} -server={{ .Ip }}#{{ .Port }} +server={{ .IP }}#{{ .Port }} {{- end}} {{- if .SendClientInfo}} add-mac @@ -36,7 +36,7 @@ if [ -n "$pid" ] && [ -f "/proc/${pid}/cmdline" ]; then # use ctrld as upstream pc_delete "server=" "$config_file" {{- range .Upstreams}} - pc_append "server={{ .Ip }}#{{ .Port }}" "$config_file" + pc_append "server={{ .IP }}#{{ .Port }}" "$config_file" {{- end}} {{- if .SendClientInfo}} pc_append "add-mac" "$config_file" # add client mac @@ -56,7 +56,7 @@ fi ` type Upstream struct { - Ip string + IP string Port int } @@ -69,7 +69,7 @@ func ConfTmpl(tmplText string, cfg *ctrld.Config) (string, error) { if ip == "0.0.0.0" || ip == "::" || ip == "" { ip = "127.0.0.1" } - upstreams := []Upstream{{Ip: ip, Port: listener.Port}} + upstreams := []Upstream{{IP: ip, Port: listener.Port}} return confTmpl(tmplText, upstreams, cfg.HasUpstreamSendClientInfo()) } @@ -97,25 +97,35 @@ func confTmpl(tmplText string, upstreams []Upstream, sendClientInfo bool) (strin } func firewallaUpstreams(port int) []Upstream { - matches, err := filepath.Glob("/home/pi/firerouter/etc/dnsmasq.dns.*.conf") - if err != nil { - return nil - } - upstreams := make([]Upstream, 0, len(matches)) - for _, match := range matches { - // Trim prefix and suffix to get the iface name only. - ifaceName := strings.TrimSuffix(strings.TrimPrefix(match, "/home/pi/firerouter/etc/dnsmasq.dns."), ".conf") - if netIface, _ := net.InterfaceByName(ifaceName); netIface != nil { - addrs, _ := netIface.Addrs() - for _, addr := range addrs { - if netIP, ok := addr.(*net.IPNet); ok && netIP.IP.To4() != nil { - upstreams = append(upstreams, Upstream{ - Ip: netIP.IP.To4().String(), - Port: port, - }) - } + ifaces := FirewallaSelfInterfaces() + upstreams := make([]Upstream, 0, len(ifaces)) + for _, netIface := range ifaces { + addrs, _ := netIface.Addrs() + for _, addr := range addrs { + if netIP, ok := addr.(*net.IPNet); ok && netIP.IP.To4() != nil { + upstreams = append(upstreams, Upstream{ + IP: netIP.IP.To4().String(), + Port: port, + }) } } } return upstreams } + +// FirewallaSelfInterfaces returns list of interfaces that will be configured with default dnsmasq setup on Firewalla. +func FirewallaSelfInterfaces() []*net.Interface { + matches, err := filepath.Glob("/home/pi/firerouter/etc/dnsmasq.dns.*.conf") + if err != nil { + return nil + } + ifaces := make([]*net.Interface, 0, len(matches)) + for _, match := range matches { + // Trim prefix and suffix to get the iface name only. + ifaceName := strings.TrimSuffix(strings.TrimPrefix(match, "/home/pi/firerouter/etc/dnsmasq.dns."), ".conf") + if netIface, _ := net.InterfaceByName(ifaceName); netIface != nil { + ifaces = append(ifaces, netIface) + } + } + return ifaces +} diff --git a/internal/router/router.go b/internal/router/router.go index 6cae16e..90882c9 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -188,6 +188,16 @@ func ServiceDependencies() []string { return nil } +// SelfInterfaces return list of *net.Interface that will be source of requests from router itself. +func SelfInterfaces() []*net.Interface { + switch Name() { + case firewalla.Name: + return dnsmasq.FirewallaSelfInterfaces() + default: + return nil + } +} + func distroName() string { switch { case bytes.HasPrefix(unameO(), []byte("DD-WRT")):