mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
feat: add --rfc1918 flag for explicit LAN client support
Make RFC1918 listener spawning opt-in via --rfc1918 flag instead of automatic behavior. This allows users to explicitly control when ctrld listens on private network addresses to receive DNS queries from LAN clients, improving security and configurability. Refactor network interface detection to better distinguish between physical and virtual interfaces, ensuring only real hardware interfaces are used for RFC1918 address binding.
This commit is contained in:
committed by
Cuong Manh Le
parent
e52402eb0c
commit
0e3f764299
@@ -189,6 +189,7 @@ func initRunCmd() *cobra.Command {
|
||||
runCmd.Flags().StringVarP(&iface, "iface", "", "", `Update DNS setting for iface, "auto" means the default interface gateway`)
|
||||
_ = runCmd.Flags().MarkHidden("iface")
|
||||
runCmd.Flags().StringVarP(&cdUpstreamProto, "proto", "", ctrld.ResolverTypeDOH, `Control D upstream type, either "doh" or "doh3"`)
|
||||
runCmd.Flags().BoolVarP(&rfc1918, "rfc1918", "", false, "Listen on RFC1918 addresses when 127.0.0.1 is the only listener")
|
||||
|
||||
runCmd.FParseErrWhitelist = cobra.FParseErrWhitelist{UnknownFlags: true}
|
||||
rootCmd.AddCommand(runCmd)
|
||||
@@ -531,6 +532,7 @@ NOTE: running "ctrld start" without any arguments will start already installed c
|
||||
startCmd.Flags().BoolVarP(&skipSelfChecks, "skip_self_checks", "", false, `Skip self checks after installing ctrld service`)
|
||||
startCmd.Flags().BoolVarP(&startOnly, "start_only", "", false, "Do not install new service")
|
||||
_ = startCmd.Flags().MarkHidden("start_only")
|
||||
startCmd.Flags().BoolVarP(&rfc1918, "rfc1918", "", false, "Listen on RFC1918 addresses when 127.0.0.1 is the only listener")
|
||||
|
||||
routerCmd := &cobra.Command{
|
||||
Use: "setup",
|
||||
|
||||
@@ -207,8 +207,8 @@ func (p *prog) serveDNS(listenerNum string) error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
// When we spawn a listener on 127.0.0.1, also spawn listeners on the RFC1918
|
||||
// addresses of the machine. So ctrld could receive queries from LAN clients.
|
||||
// When we spawn a listener on 127.0.0.1, also spawn listeners on the RFC1918 addresses of the machine
|
||||
// if explicitly set via setting rfc1918 flag, so ctrld could receive queries from LAN clients.
|
||||
if needRFC1918Listeners(listenerConfig) {
|
||||
g.Go(func() error {
|
||||
for _, addr := range ctrld.Rfc1918Addresses() {
|
||||
@@ -1039,7 +1039,7 @@ func (p *prog) queryFromSelf(ip string) bool {
|
||||
// needRFC1918Listeners reports whether ctrld need to spawn listener for RFC 1918 addresses.
|
||||
// This is helpful for non-desktop platforms to receive queries from LAN clients.
|
||||
func needRFC1918Listeners(lc *ctrld.ListenerConfig) bool {
|
||||
return lc.IP == "127.0.0.1" && lc.Port == 53 && !ctrld.IsDesktopPlatform()
|
||||
return rfc1918 && lc.IP == "127.0.0.1" && lc.Port == 53
|
||||
}
|
||||
|
||||
// ipFromARPA parses a FQDN arpa domain and return the IP address if valid.
|
||||
|
||||
@@ -39,6 +39,7 @@ var (
|
||||
skipSelfChecks bool
|
||||
cleanup bool
|
||||
startOnly bool
|
||||
rfc1918 bool
|
||||
|
||||
mainLog atomic.Pointer[zerolog.Logger]
|
||||
consoleWriter zerolog.ConsoleWriter
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"maps"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const listnetworkserviceorderOutput = `
|
||||
(1) USB 10/100/1000 LAN 2
|
||||
(Hardware Port: USB 10/100/1000 LAN, Device: en7)
|
||||
|
||||
(2) Ethernet
|
||||
(Hardware Port: Ethernet, Device: en0)
|
||||
|
||||
(3) Wi-Fi
|
||||
(Hardware Port: Wi-Fi, Device: en1)
|
||||
|
||||
(4) Bluetooth PAN
|
||||
(Hardware Port: Bluetooth PAN, Device: en4)
|
||||
|
||||
(5) Thunderbolt Bridge
|
||||
(Hardware Port: Thunderbolt Bridge, Device: bridge0)
|
||||
|
||||
(6) kernal
|
||||
(Hardware Port: com.wireguard.macos, Device: )
|
||||
|
||||
(7) WS BT
|
||||
(Hardware Port: com.wireguard.macos, Device: )
|
||||
|
||||
(8) ca-001-stg
|
||||
(Hardware Port: com.wireguard.macos, Device: )
|
||||
|
||||
(9) ca-001-stg-2
|
||||
(Hardware Port: com.wireguard.macos, Device: )
|
||||
|
||||
`
|
||||
|
||||
func Test_networkServiceName(t *testing.T) {
|
||||
tests := []struct {
|
||||
ifaceName string
|
||||
networkServiceName string
|
||||
}{
|
||||
{"en7", "USB 10/100/1000 LAN 2"},
|
||||
{"en0", "Ethernet"},
|
||||
{"en1", "Wi-Fi"},
|
||||
{"en4", "Bluetooth PAN"},
|
||||
{"bridge0", "Thunderbolt Bridge"},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.ifaceName, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
name := networkServiceName(tc.ifaceName, strings.NewReader(listnetworkserviceorderOutput))
|
||||
assert.Equal(t, tc.networkServiceName, name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const listallhardwareportsOutput = `
|
||||
Hardware Port: Ethernet Adapter (en6)
|
||||
Device: en6
|
||||
Ethernet Address: 3a:3e:fc:1e:ab:41
|
||||
|
||||
Hardware Port: Ethernet Adapter (en7)
|
||||
Device: en7
|
||||
Ethernet Address: 3a:3e:fc:1e:ab:42
|
||||
|
||||
Hardware Port: Thunderbolt Bridge
|
||||
Device: bridge0
|
||||
Ethernet Address: 36:21:bb:3a:7a:40
|
||||
|
||||
Hardware Port: Wi-Fi
|
||||
Device: en0
|
||||
Ethernet Address: a0:78:17:68:56:3f
|
||||
|
||||
Hardware Port: Thunderbolt 1
|
||||
Device: en1
|
||||
Ethernet Address: 36:21:bb:3a:7a:40
|
||||
|
||||
Hardware Port: Thunderbolt 2
|
||||
Device: en2
|
||||
Ethernet Address: 36:21:bb:3a:7a:44
|
||||
|
||||
VLAN Configurations
|
||||
===================
|
||||
`
|
||||
|
||||
func Test_parseListAllHardwarePorts(t *testing.T) {
|
||||
expected := map[string]struct{}{
|
||||
"en0": {},
|
||||
"en1": {},
|
||||
"en2": {},
|
||||
"en6": {},
|
||||
"en7": {},
|
||||
"bridge0": {},
|
||||
}
|
||||
m := parseListAllHardwarePorts(strings.NewReader(listallhardwareportsOutput))
|
||||
if !maps.Equal(m, expected) {
|
||||
t.Errorf("unexpected output, want: %v, got: %v", expected, m)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user