Extending macOS DNS resolution for fun and utility

In macOS, it is possible to extend DNS resolution for specific n-level domains using specially named files in /etc/resolver/ to use nameservers (and the associated options) without changing your default nameservers. In this post I’m going to outline what I’m using it for and how to accomplish it, and some other things you can do, should you be inclined.

I recently became aware of the OpenNIC Project which provides a variety of services like public DNS servers, dynamic DNS, and a couple top-level domains – and it’s that last item I found interesting and wanted to play with it. I could just change my DNS nameservers to any one of many nameservers run by members of the OpenNIC project, but I’m not ready to commit to moving away from Google DNS just yet.

In Linux, I could probably accomplish this by running a nameserver on localhost and slurping in all the OpenNIC TLD data, but in MacOS I wasn’t sure if there was a better solution.

Enter /etc/resolver/. If you create /etc/resolver on your mac, you can then place files there for whatever n-level domains you want. Here is the beginnings of a script I created; it:

– creates the directory /etc/resolver/ if it does not exist,
– creates the file _opennic and supplies a few v4 and v6 nameservers for the OpenNIC project,
– creates symlinks to _opennic for each of the OpenNIC TLD’s I’m interested in resolving.

## add_other_resolvers.sh - add other resolvers to /etc/resolver 
## (see 'man 5 resolver' for more info)
## 03192017 jkl 

# if /etc/resolver doesn't exist make it 
[ -d /etc/resolver ] || mkdir /etc/resolver; 

# provide for the OpenNIC Project (opennicproject.org) and a few TLD's:
tee <<EOF /etc/resolver/_opennic >/dev/null
nameserver 2a05:dfc7:5::53
nameserver 2a05:dfc7:5::5353
nameserver 2a0b:1904:0:53::

ln -fs _opennic /etc/resolver/o
ln -fs _opennic /etc/resolver/dyn
ln -fs _opennic /etc/resolver/oss
ln -fs _opennic /etc/resolver/bbs
ln -fs _opennic /etc/resolver/free
ln -fs _opennic /etc/resolver/geek

# that's all for now

You don’t have to do it this way. You could simply echo 'nameserver' > /etc/resolver/dyn and it would do the same thing; I’m doing it this way because it’s less work if I have to make a major change that effects multiple things on the same location.

Similarly, if you want to affect a single second-level domain and all of the hosts under it, you could for example do echo 'nameserver' > /etc/resolver/mycool.com' and it would cause lookups for mycool.com and *.mycool.com to go through You could specify a third-level domain in much the same way as /etc/resolver/thisis.mycool.com for example, and so on.

(This also means you could make up any TLD you want for local use if you did, say, run dnsmasq locally, and echo 'nameserver' > /etc/resolver/jkl, but I digress. 😉 )

The last thing to remember is that certain tools like dig and nslookup are not going to provide accurate results if you use them on a hostname you have configured in this way. To confirm it is working, use the dns-sd command, thus:

$ dns-sd -G v4 reg.dyn
DATE: ---Mon 20 Mar 2017---
6:22:20.420 ...STARTING...
Timestamp A/R Flags if Hostname Address TTL
6:22:20.421 Add 2 0 reg.dyn. 377