Via brew or other method
In order to work on every connection and on any TLD, dnsmasq
needs to be the first DNS resolver receving the query.
And since dnsmasq
is a local process, all DNS queries need to go to 127.0.0.1
On macOS, /etc/resolv.conf
is automaticaly created, depending on a variety of things (network settings, etc), so it cannot be edited.
The only practical option is to create a new Network Location via Network Preferences, and set all interfaces (Wi-Fi, Thunderbolt Ethernet, etc) to use a static DNS server address.
This can be done via GUI or via Terminal. Mutliple DNS servers can be passed, and will be used in-order.
networksetup -setdnsservers "Wi-Fi" 127.0.0.1
networksetup -setdnsservers "Bluetooth PAN" 127.0.0.1
networksetup -setdnsservers "Thunderbolt Ethernet" 127.0.0.1
networksetup -setdnsservers "Thunderbolt Bridge" 127.0.0.1
dnsmasq
configuration is simple.
domain-needed # Only lookup full domains
bogus-priv # No reverse IP lookups
no-resolv # Don't use DNS servers listed in resolv.conf
no-poll # Don't poll changes in resolv.conf
no-hosts # Don't read /etc/hosts
# Host files
addn-hosts=/etc/hosts-a
addn-hosts=/etc/hosts-b
# Wildcard .dev domain
address=/dev/127.0.0.1
# DNS Servers
server=84.200.69.80 # DNS.WATCH
server=8.8.8.8 # Google
server=8.26.56.26 # Comodo Secure DNS
# Listen for DHCP requests
listen-address=127.0.0.1
# TODO: look into forwarding DHCP options from router for captive networks, etc.
# dhcp-option=option:dns-server,0.0.0.0,10.10.10.1
dhcp-hostsdir
, dhcp-optsdir
and hostsdir
are not supported on macOS. Attempting to set these wil prevent dnsmasq
to start.
Another popular use of dnsmasq is to route all whaveter**.dev** requests to 127.0.0.1
, to use for local development environments.
In order for this setup to work, we need:
- A new DNS reolver entry in
/etc/resolver/
- A config line in
dnsmasq.conf
For (1) simply create /etc/resolver/dev
. The filename dev
is used by resolver (5)
to determin the domain it applies to (.dev
in our case).
The contents of the file would simply be:
nameserver 127.0.0.1
Changes in the /etc/resolver/*
are automatically read and applied.
dnsmasq.conf
is read once at load. In order to refresh it the dnsmasq
service needs to be restarted. homebrew.mxcl.
below only applies if dnsmasq
was installed via Homebrew (https://brew.sh/)
sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
sudo sudo launchctl stop homebrew.mxcl.dnsmasq
sudo sudo launchctl start homebrew.mxcl.dnsmasq
If you have set dnsmasq
to load hosts from external files (addn-hosts=…
), then those file changes can be updated by sending SIGHUP
to dnsmasq
like this:
sudo pkill -SIGHUP dnsmasq
This worked great except for that I had to go back and manually add a secondary DNS (fallback) in network preferences. Otherwise, no websites will load.