MacOS – How to get DNS resolution on-line and offline for virtual machine and local app using dnsmasq or similar

dnsmacos

I have read all the answers I can find about setting up dnsmasq as a local DNS server for development. But I can't make it work for my case. Most out there want 127.0.0.1 to be resolved for names in the .dev domain.

In my case I have a VirtualBox virtual machine running windows in my MacBook Air. This Windows runs SQL server express. It is set up with two interfaces – a network bridge – to share the external wifi interface and be a peer on my local network when I am on line. I also have VirtualBox set up a host-only network. The subbnet is 192.168.56.0/24 with my Mac being .1 and the Windows virtual machine being .2.

dnsmasq running on the MacBook support this and from a Windows perspective it does everything perfectly, on-line and off. Using its ability to assign complete domains an address it gives .rab to 192.168.56.1 and .tig to 192.168.56.2

On the Mac itself I am developing a nodejs application, which is a web server (so it needs a domain name – lets say abc.rab – my Mac is called Rabbit) and to acccess the Windows machine's database (called abc.tig – Windows machine is called Tigger). Here things don't seem to work.

I wrote a small nodejs program to test DNS lookup

'use strict';
const dns = require('dns');
dns.lookup('abc.tig',(err,add,family) =>{
    console.log('addresses:',add);
});

and it can't find the address. Yet on the terminal this DNS lookup works

alan@rabbit:~/Documents$nslookup abc.tig
Server:     127.0.0.1
Address:    127.0.0.1#53

Name:   abc.tig
Address: 192.168.56.2

alan@rabbit:~/Documents$

In a web browser abc.rab also tells me it can't find the domain name.

As I said, I had set up dnsmasq to run on all interfaces. In the network properties for my Wi-Fi interface I have set nameservers as 127.0.0.1 and 8.8.8.8

In /etc/resolver I created a file called literally 'whatever' (the answer that I read about this didn't make it clear if it literally had to be called that or it was just an example) with

nameserver 127.0.0.1
domain .

in it

Obviously there are two name resolution processes in place. The mDNSResponder and dnsmasq are both shown running in my activity panel. I presume different ones are being used by the terminal and by my application

What am I doing wrong here?
(writing and testing this I am currently online)

(PS I have a similar setup working on my home development machine running linux working perfectly – I just want to be able to develop on the move).

Best Answer

mDNSResponder and dnsmasq have to run both: dnsmasq is the lightweight DNS-server (and DHCP/Router) and mDNSResponder is responsible for all local queries.


To set up dnsmasq in OS X in your environment properly do the following:

Remove any DNS-server in the network preferences of the dnsmasq host (your MacBook Air) except 127.0.0.1.

Remove any DNS-server in the network preferences of the VMs in use and replace them by the IP-address of the VM-host (your MacBook Air).

Remove any file in /etc/resolver/. Usually they aren't necessary. You may keep them but then they probably should have this form:

/etc/resolver/rab with the content

nameserver    127.0.0.1

/etc/resolver/tig with the content

nameserver    127.0.0.1

The logic behind this is mentioned in resolver(5):

domain
    Domain name associated with this resolver configuration. This option is normally not     required by the Mac OS X DNS search system when the resolver configuration is read from a     file in the /etc/resolver directory. In that case the file name is used as the domain name.     However, domain must be provided when there are multiple resolver clients for the same     domain name, since multiple files may not exist having the same name. See the SEARCH     STRATEGY section for more details.

Then edit /usr/local/etc/dnsmasq.conf and add/modify

server=/rab/192.168.0.2 #your main IP-address or 127.0.0.1
server=/tig/192.168.0.2 #your main IP-address or 127.0.0.1
server=8.8.8.8 #forwarder
addn-hosts=/usr/local/etc/hosts/hosts.conf

Now add the hosts.conf file in /usr/local/etc/hosts/ with the content:

127.0.0.1   localhost
192.168.56.1    abc.rab
192.168.56.2    abc.tig

Then restart dnsmasq with launchctl to load the new conf files.


Since your Windows VM already is in the bridged Wi-Fi network you can completely dump the host-only network and modify /usr/local/etc/hosts/hosts.conf:

127.0.0.1   localhost
192.168.0.2 abc.rab #IP-address of the MacBook Air Wi-Fi interface
192.168.0.3 abc.tig #IP-address of the Windows bridge interface