Infrastructure 2017: A new DNS setup

Previously, DNS has been a pain to maintain. I was using a cloud DNS service, so for every subdomain, I would have to log on to CloudNS and use their web interface to update DNS records. This made it hard to switch DNS providers and easily edit records. And their three domain limit made it impossible to add my other domains, thus I had to run another DNS server. I made the decision to run BIND, but I had to run a service to update my zone files when my IP address changes because I didn't purchase a static IP.

To simplify my complex setup, I decided to host all my DNS locally and solve the dynamic IP problem at once. I made the switch from BIND to CoreDNS due to its extensibility. To ensure that parent DNS servers are always pointing to the right IP, I got a couple of free domains (an example is "") and pointed it to HE's DNS service, where I set up dynamic DNS updates. In my local zone files, I could also use CNAME records to point to the same dynamically updated DNS record, thus needing to only update the address in one place. However, CNAME records can't be put on the zone apex, so I solved this by creating a CoreDNS plugin to replace CNAME records on the zone apex with the resolved records. This meant that a request for "" would return the actual IP address, instead of a CNAME record, which made it compliant with DNS standards. And since all my records are stored locally, I can painlessly edit them, rather than having some of them hosted on a cloud service.

So now, if you dig +trace our domains, you would get this:        86400   IN  NS        86400   IN  NS  
;; Received 121 bytes from in 60 ms        29  IN  A        300 IN  NS        300 IN  NS  
;; Received 137 bytes from in 6 ms

And all I have to write in my zone file is:

@       IN    CNAME
www     IN    CNAME   @  
ambrose IN    CNAME   @  
gitlab  IN    CNAME   @