macOS – Using launchctl and dnsmasq for Localhost Domain Spoofing

dnslaunchdweb app

I am usually a Linux user, but I would like to test my mojolicious webapp on a macOS system. thus, I would like *.test *.*.test and *.*.*.test all to resolve to 127.0.0.1, where my webapp is eagerly listening on port 80 .

I understand that this is best done by installing dnsmasq. For macOS,

# brew install dnsmasq

and then

# echo "address=/test/127.0.0.1" >> /usr/local/dnsmasq.conf
# launchctl start dnsmasq
# launchctl list | grep dns
89254   0   homebrew.mxcl.dnsmasq

so, if I understand this correctly, ping abc.test should now ping localhost. alas, it does not. (or, is there a better way to test?)

I also do not understand how to shut down and restart dnsmasq. launchctl restart dnsmasq, launchctl kill dnsmasq.mxcl.dnsmasq, and launchctl disable 89254 (and many permutations thereof) all seem to elicit scorn but no results.

Best Answer

You've not said which version of MacOS you're on; my reply here is from macOS Sierra Version 10.12.5. (I'm using it in order to run tests against a VMWare installation of ADCS...)

First, the commands to stop and start dnsmasq are:

sudo launchctl stop homebrew.mxcl.dnsmasq
sudo launchctl start homebrew.mxcl.dnsmasq

ETA If launchctl stop doesn't actually stop it, it's likely that the .plistfile (presumably /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist contains the lines

<key>KeepAlive</key>
<true/>

If you don't want it to be always on, change that to

<key>KeepAlive</key>
<false/>

instead. Or you can disable it with

sudo launchctl disable homebrew.mxcl.dnsmasq

The next time you want to turn it on, run

sudo launchctl enable homebrew.mxcl.dnsmasq

Second, you should check the other values of your dnsmasq.conf file. Here's mine:

[jenny@temeraire ~] $ grep -v ^# /usr/local/etc/dnsmasq.conf | grep -v ^$
domain-needed
bogus-priv
resolv-file=/usr/local/etc/resolv.conf
server=/ad.dybedahl.se/192.168.226.10
server=/226.168.192.in-addr.arpa/192.168.226.10
listen-address=127.0.0.1
no-negcache

Note the line resolv-file. It tells dnsmasq which nameservers to use for hosts that aren't in the dnsmasq config. In my case, it looks like this:

[jenny@temeraire ~] $ more /usr/local/etc/resolv.conf 
nameserver 8.8.8.8
nameserver 8.8.8.4

So all DNS lookups that aren't answered by my virtual AD server will be handled by Google's nameservers, meaning that I can still connect to hosts that aren't in my config.

Third, to debug whether dnsmasq acts properly, don't use ping. Instead, use dig, like so:

dig @127.0.0.1 abc.test

To test whether your system is using dnsmasq as its resolver, again use dig:

dig abc.test

It will tell you what nameserver it's using, among other things.

Dig will give you information about how the lookup is actually done.

Fourth, in order to use dnsmasq as your resolver, you need to also change /etc/resolv.conf to point to 127.0.0.1 instead of whatever it now points at. You should start by copying your current /etc/resolv.conf to /usr/local/etc/resolv.conf, so that dnsmasq will know what nameservers to use. Then change /etc/resolv.conf to read

nameserver 127.0.0.1

On my laptop, I do this in System Preferences -> Network -> DNS. I'm not sure how you do it on a server; perhaps simply editing the file will work.