MacOS – Configure dnsmasq and use DHCP provided DNS together

dnsmacoswebserver

Running MacOX Sierra on MacBook Pro, and setting up for local dev environment with nginx as the web server, but I have a problem.

What I want to do

  1. Use dnsmasq as the local dns server that returns 127.0.0.1 as the host for the wildcard domain *.develop (as .dev now clashes with ICANN).
  2. Forward any unresolved requests to DNS servers provided by DHCP whenever I connect to a network so that I can resolve all other hostnames (external and internal.)

Conditions and constraints

  1. I move between networks. My home network DHCP's the DNS server as 192.168.1.1, but my work DHCP gives my DNS as 10.128.x.x
  2. The corporate network with the 10.128.x.x DNS, also sets a search domain for internal addresses.
  3. I'm in China, so just setting a bunch of public DNS servers like Google or OpenDNS as well as 127.0.0.1 may well work, but they're international and get throttled by GFW.

What I've done so far

  1. I've installed nginx and dnsmasq using homebrew.
  2. Services running using sudo brew services start xxx. )This is so I can run nginx on port 80 and not port 8080.)
  3. Set dnsmasq directive address=/.develop/127.0.0.1
  4. I can verify that dnsmasq works, by using dig:

dig testing.testing.one.two.three.develop @127.0.0.1

; <<>> DiG 9.8.3-P1 <<>> testing.testing.one.two.three.develop @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46013
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;testing.testing.one.two.three.develop. IN A

;; ANSWER SECTION:
testing.testing.one.two.three.develop. 0 IN A   127.0.0.1

;; Query time: 2 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Jun 20 12:04:44 2017
;; MSG SIZE  rcvd: 71
  1. Setting the DNS server to 127.0.0.1 in Network Preferences does work and I can 'ping' this it:

Ping example:

ping -c 1 this.is.a.test.develop
PING this.is.a.test.develop (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.036 ms

--- this.is.a.test.develop ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.036/0.036/0.036/0.000 ms

but then no external services are available because the only DNS available is my dnsmasq at 127.0.0.1

The problem

  1. It seems like the simple solution would be just to add 127.0.0.1 + 192.168.0.1 to my network adapter DNS list. That works at home, but not at the corporate location
  2. Adding the corporate 10.128.x.x would obviously work at the office, but then not at home
  3. So add both corporate and home DNS to the list? This would then break any other wifi/ethernet connections because I would not pick up their DHCP DNS server
  4. I cannot just add public DNS servers (like Google or Open DNS, because I'm in China. I need to have the DHCP supplied ones, as public DNS is very slow in China)

I'd like to know how others have solved what seems like a very frequent setup, but I'm having trouble.

I've already looked at two separate questions on stack exchange which have similar problems but not identical. The questions are attached to the bottom of this question [1], [2]. What these questions show are that on macOS, /etc/resolve.conf has this notice:

in the header

#
# Mac OS X Notice
#
# This file is not used by the host name and address resolution
# or the DNS query routing mechanisms used by most processes on
# this Mac OS X system.
#
# This file is automatically generated.
#

This suggests that any modifications will not be read from this file, and other answers from the questions suggest that any files in /etc/resolver/* will also not be read

So, my real question is: is there any way to do:

  1. Always use 127.0.0.1 first
  2. If not found use the dynamic DNS from whatever DHCP gives

Why didn't you just use hosts?

Becuase the idea of having a *.develop domain and then just adding a single site that uses regular expressions to dynamically resolve local sites is very attractive!

i.e. some-sub-domain.develop -> /Users/myuser/www/some-sub-domain/

[1] dnsmasq not working on Mac OS Sierra

[2] https://serverfault.com/questions/478534/how-is-dns-lookup-configured-for-osx-mountain-lion

Best Answer

Answer found! For those looking to make this work, specifically in MacOS Sierra, the standard solution of using a resolver file in /etc/resolver/* actually works, without the need to change network preferences.

In my instance, where I wanted my local development domain name to be *.develop, I created a file called develop (no extension) with contents:

nameserver 127.0.0.1

I thought this hadn't worked and that macOS does not read from these files, as I used the command dscacheutil -flushcache and it didn't work. Only a hard restart was enough to kick the system into using the local resolver.

For completeness, the content of my dnsmasq.conf file is:

no-resolv
address=/.develop/127.0.0.1