adding local DNS resolution for a custom top level domain on macOS using macports

Recently I was testing some applications in a local kubernetes installation running in minikube, especially the access via an ingress. For this I defined the ingress endpoints using a custom otherwise not existing top level domain to produce names like application1.foobar or application2.foobar. (The list  of officially registered TLDs can be found at https://www.iana.org/domains/root/db).

Now in order to access these applications locally with an URL like http://application1.foobar/ I need to make the DNS resolution resolve this address to the IP address of my local minikube instance. This IP address can be retrieved with

minikube ip

which in this sample case returns 192.168.99.100.

Now I could add the following line to my /etc/hosts file (which needs to be edited with sudo):

192.168.99.100  application1.foobar appiicaton2.foobar

but this is no nice solution as every time when a new application is added, the /etc/hosts file must be updated.

So instead I set up a local DNS server (using dnsmasq) which will resolve every call to an address with the .foobar top level domain to our IP address. Then I reconfigure the local name resolution process of macOS to use this DNS resolver for .foobar addresses – we want to keep the normal DNS resolution working.

Setting up dnsmasq

I am using MacPorts on my machines, other people prefer homebrew, both have dnsmasq as package available. The first step is the installation:

sudo port install dnsmasq

The next step is to edit the dnsmasq configuration, so that any request for an address in the .foobar domain ist resolved to our ip address. The macports installation has its configuration file at /opt/local/etc/dnsmasq.conf, this file must be edited with sudo vi /opt/local/etc/dnsmasq.conf and the following line must be added:

address=/foobar/192.168.99.100

After changing the configuration the dnsmasq service is started with sudo port load dnsmasq. it can be stopped with the corresponding command sudo port unload dnsmasq.

Now the local running DNS server will return our IP for any host in the foobar domain:

$ dig application1.foobar @localhost +noall +answer

; <<>> DiG 9.10.6 <<>> application1.foobar @localhost +noall +answer
;; global options: +cmd
application1.foobar.	0	IN	A	192.168.99.100

$ dig adifferenthost.foobar @localhost +noall +answer

; <<>> DiG 9.10.6 <<>> adifferenthost.foobar @localhost +noall +answer
;; global options: +cmd
adifferenthost.foobar.	0	IN	A	192.168.99.100

$ dig even.subdomains.are.working.foobar @localhost +noall +answer

; <<>> DiG 9.10.6 <<>> even.subdomains.are.working.foobar @localhost +noall +answer
;; global options: +cmd
even.subdomains.are.working.foobar. 0 IN A	192.168.99.100

Configuring the system resolving process

The next step is to reconfigure the nameserver resolution of macOS to use our local running dnsmasq when requests for our .foobar domain come in. For this we need to add a file named foobar to the /etc/resolver directory (which may not yet exist on your machine) and add the following line:

nameserver 127.0.0.1

This can be done with:

sudo mkdir -p /etc/resolver
echo "nameserver 127.0.0.1" | sudo tee -a /etc/resolver/foobar

After this you can check that this dns resolver is configured by issuing a scutil --dns command, the output contains an entry like this:

resolver #19
  domain   : foobar
  nameserver[0] : 127.0.0.1
  flags    : Request A records, Request AAAA records
  reach    : 0x00030002 (Reachable,Local Address,Directly Reachable Address)

or you could do a

$ ping application2.foobar
PING application2.foobar (192.168.99.100): 56 data bytes
64 bytes from 192.168.99.100: icmp_seq=0 ttl=64 time=0.559 ms
64 bytes from 192.168.99.100: icmp_seq=1 ttl=64 time=0.472 ms

$ ping any.hostname.you.can.think.of.foobar
PING any.hostname.you.can.think.of.foobar (192.168.99.100): 56 data bytes
64 bytes from 192.168.99.100: icmp_seq=0 ttl=64 time=1.156 ms
64 bytes from 192.168.99.100: icmp_seq=1 ttl=64 time=0.456 ms

 

Leave a Reply

Your email address will not be published. Required fields are marked *