Tom's Blog

Host your own DNS, without sacrificing reliability

A few months ago, my domain’s DNS was provided by my domain’s registrar. Their DNS hosting is reliable, but:

  • the interface to modify your zonefile is clunky
  • their support for versioning was primitive/slow, in comparison to modern approaches.
  • changes made in the interface took minutes to be visible in their nameservers, which was frustrating
  • their domain’s authoritative name servers are not IPv6 accessible[1]
  • and I wanted to learn BIND

Notable alternatives have flaws too:

  • Serve DNS from your own server: this provides full control but is slow and unreliable
  • Amazon Route 53: fast, cheap, programmatic configuration (therefore manageable with scripts/git), what’s not to like? Route 53 isn’t accessible over IPv6, and its API doesn’t support zonefiles and is instead Route 53-specific, which is vendor lockin. :(
  • Luadns: free (for low traffic)! supports BIND zonefiles (thereby avoiding vendor lockin)! manageable by git! However, LuaDNS isn’t accessible over IPv6. Also, that they provide so much functionality means if they ever fail, it’ll be harder to quickly migrate to another solution than if they left some functionality for you to handle. If these two concerns don’t bother you, LuaDNS is probably a fine choice!

The purpose of this post is to describe a solution using a Hidden Master Name Server:

  1. Host your own DNS zonefile (by running BIND on your own server, for example).
  2. Configure a secondary DNS provider (e.g. BuddyNS) to also host your domain.
  3. In your registrar, set your domain’s name servers to be the your secondary DNS provider’s nameservers.
  4. Set your zonefile’s NS record to be the secondary DNS provider.
  5. Set your zonefile’s slave expiration time to some large duration, e.g. 4 weeks

When Joe Bloggs tries to resolve your domain, his request will be served by BuddyNS’s servers (which are fast, reliable and distributed around the globe). When you want to update your zonefile, you change your BIND zonefile and refresh BIND, which can be configured to send IXFR requests, so BuddyNS can instantly start serving the updated zonefile. /

This solution provides the following advantages:

  • full control over zonefile
  • your config is now just your BIND configuration, which can be managed using standard tools: git, rsync, puppet, …
  • short feedback loop between making changes, and seeing them (assuming your secondary DNS provider is quick. BuddyNS is quick.)
  • you’re only reliant on BuddyNS providing secondary DNS. If you wish to move, you just point your NS records to another secondary DNS provider, such as Hurricane Electric.

and disadvantages:

  • less reliable: if your server’s DNS server goes down, your secondary will eventually go down. The secondary DNS server will continue to serve your zonefile for 4 weeks (or however long you set the slave expiration time), so everything will be fine if you fix your DNS server within 4 weeks, which is acceptable for me
  • BIND, though more powerful than typical DNS management web interfaces, also has a steeper learning curve
  • BIND may be exploited by attackers, though you can and should restrict DNS traffic to just your secondary DNS provider

Here’s my BIND configuration, which is configurd to uses BuddyNS as a secondary DNS provider:

zone "tom-fitzhenry.me.uk" in {
    type master;
    allow-transfer {
        173.244.206.26;  # a.transfer.buddyns.com
        88.198.106.11;   # b.transfer.buddyns.com
    };
    file "/etc/bind/zones/tom-fitzhenry.me.uk.db";
};

and /etc/bind/zones/tom-fitzhenry.me.uk.db …

$ORIGIN tom-fitzhenry.me.uk. ; supposedly a good idea to put this: http://www.zytrax.com/books/dns/ch8/origin.html
$TTL 3h
@ IN SOA b.ns.buddyns.com. hostmaster.tom-fitzhenry.me.uk. (
    201210160 ; serial number of this zone file
    3h        ; slave refresh
    1h        ; slave retry time in case of a problem
    4w        ; slave expiration time
    1h        ; maximum caching time in case of failed lookups
)


         ;; When modifying NS records, remember to modify the parent's zonefile
         15m     NS      b.ns.buddyns.com.
         15m     NS      c.ns.buddyns.com.
         15m     NS      d.ns.buddyns.com.
         15m     NS      e.ns.buddyns.com.
         15m     NS      f.ns.buddyns.com.

         5m      A       78.129.251.129

etc. etc.

Once you’re setup, sanity check your DNS using a tool such as intoDNS.


Footnotes

  1. Notice the lack of IPv6 addresses in dig AAAA gandi.net +trace
blog comments powered by Disqus