Skip to content

Instantly share code, notes, and snippets.

@paul-chambers
Last active August 7, 2023 12:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paul-chambers/a94cfe614c586d4a4f037291612d45a2 to your computer and use it in GitHub Desktop.
Save paul-chambers/a94cfe614c586d4a4f037291612d45a2 to your computer and use it in GitHub Desktop.
My Control-D & dnsmasq config

These two config files work together to integrate Control-D for public DNS queries and dnsmasq for intranet ones (including those assigned by DHCP).

When these chages are made, the ctrld daemon is 'in front' and receives all queries first on listener.0, irrespective of origin. Listener.0 then diverts any that are for *.local or my intranet to the dnsmasq instance, which has been moved to port 531, to avoid conflicts. If dnsmasq doesn't resolve the request itself internally (i.e. dhcp allocations, /etc/hosts, static dhcp-host configs, etc.), it 'forwards' it back to ctrld on port 532, where listener.1 sends it upstream unconditionally (i.e. listener.1 has no rules to redirect intranet requests to dnsmasq, like there are for listener.0)

Note that you should have a working dnsmasq configuration first, then the snippet below should be added to it, then comment out the existing 'server =' configuration lines. Only then will ctrld start successfully (because dnsmasq would be camped on port 53 already).

[service]
log_level = "debug"
[listener]
[listener.0]
ip = "0.0.0.0"
port = 53
[listener.0.policy]
name = "default"
failover_rcodes = ["NXDOMAIN", "SERVFAIL"]
networks = [
{ "network.0" = ["upstream.0","upstream.2","upstream.3"] }
]
rules = [
{ "*.local" = ["upstream.1"] },
{ "*.bod.org" = ["upstream.1"] }
]
[listener.1]
ip = "127.0.0.1"
port = 532
restricted = "true"
[listener.1.policy]
name = "plain upstream"
failover_rcodes = ["NXDOMAIN", "SERVFAIL"]
networks = [
{ "network.1" = ["upstream.0","upstream.2","upstream.3"] }
]
[network]
[network.0]
name = "any address"
cidrs = ["0.0.0.0/0"]
[network.1]
name = "localhost"
cidrs = ["127.0.0.0/8"]
[upstream]
[upstream.0]
name = "Default"
type = "doq"
endpoint = "{Control-D Resolver}.dns.controld.com"
ip_stack = "split"
timeout = 500
[upstream.1]
name = "Local"
type = "legacy"
endpoint = "127.0.0.1:531"
timeout = 100
[upstream.2]
name = "Cloudflare 1"
type = "doq"
endpoint = "1.1.1.3"
timeout = 100
[upstream.3]
name = "Cloudflare 2"
type = "doq"
endpoint = "1.0.0.3"
timeout = 100
# modifications to integrate with the ctrld daemon
# Listen on this specific port instead of the standard DNS port
# (53). Setting this to zero completely disables DNS function,
# leaving only DHCP and/or TFTP.
port=531
# If you want dnsmasq to listen for DHCP and DNS requests only on
# specified interfaces (and the loopback) give the name of the
# interface (eg eth0) here.
# Repeat the line for more than one interface.
#interface=lo
# Or you can specify which interface _not_ to listen on
except-interface=wan0
# pass the request back to the ctrld daemon if dnsmasq can't resolve it locally
server=127.0.0.1#532
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment