BIND DNS Server And Zone File Configuration

March 26, 2011 under The 100% Uptime Challenge

BIND is the standard for DNS services on Unix operating systems. It is somewhat complex and includes many useful features, but for this configuration I’m going to keep it really simple.

I already installed BIND using yum earlier on. On CentOS it’s installed from the ‘bind’ package, but the service is (somewhat illogically) called ‘named’. If you’re also going to use the server for local DNS resolution (by putting 127.0.0.1 in my /etc/resolv.conf) you’ll need a copy of the root server cache file, so BIND can look up external names. You’ll also need this if any records in your DNS zone refer to an external DNS name, for example a CNAME record pointing to another domain. Otherwise BIND will not be able to recurse and the lookup will fail.

So to get started:

# enable the service
chkconfig named on

# save the DNS root server info to /etc/db.cache:
wget -O /etc/db.cache http://www.internic.net/zones/named.cache

# create a config file for named:
# see my config file for an example
# at a minimum, edit the zone entry to match your domain
vi /etc/named.conf

# create the DNS zone file
# see my zone file for an example
# edit to match your domain and server IPs
vi /var/named/data/cwik.ch.hosts

# start the server
service named start

My sample config files are a very simple, minimal configuration. You may want to elaborate further. For further reading, check out the BIND documentation and/or the excellent DNS and BIND from O’Reilly.

In my setup, I have configured the 3 DNS servers in master/master/master configuration, because I wanted full control of the zone file on each server to be able to test different configurations. I also want to experiment later on with putting some intelligent health checks into the DNS system, whereby each server will check the availability of the other servers, and only return the IPs of those servers it can reach. The hope is that using this technique I can prevent the IP of an unreachable server being returned to the client, thus further increasing uptime.

Back to the BIND configuration, a little explanation on my config files:

DNS recursion: I’ve only listed the loopback interface under allow-recursion{}┬áin the options{} block of named.conf, so only my local system can issue recursive queries. You may want to add the IPs of each of your servers so they can use each other as backup resolvers. In my case I have used the DNS resolvers provided by my upstream providers as secondaries in my /etc/resolv.conf file.

Zone configuration: I have instructed each server to be a master for my zone file. I will therefore have to propagate updates to my zone file to all my DNS servers manually. Another (more usual) way to configure BIND is to nominate one server as your primary and instruct the other servers to slave your zone. In this configuration, zone updates are propagated automatically, but you lose the ability to modify the zone file on each resolver independently, which is why I have used 3 masters.

Zone file: My zone file is for the most part pretty standard: a default TTL, an SOA record, NS and A records for each of my nameservers and an MX record. I’ve also set up an SPF record to help ensure my mail gets through the more aggressive spam filters.

The interesting part is the configuration for www.cwik.ch, this blog. I’ve created 3 A records at the root of the domain, ie. http://cwik.ch/ – one for each of my servers. I’ve then created www.cwik.ch as a CNAME (Canonical NAME – ie. an alias) of cwik.ch, so any DNS query for www.cwik.ch will return the 3 IPs from the root of the domain. This is the foundation on which this whole 100% uptime project is based.

A test query shows it is working perfectly:

$ host -t A www.cwik.ch
www.cwik.ch has address 67.202.99.74
www.cwik.ch has address 80.93.25.175
www.cwik.ch has address 83.96.156.169

On the left hand side of this page, under MySQL replication status, you should find a small indicator showing which server you are currently connected to. It’ll be one of the above IPs, depending on which one your browser picked.

The glue: Once I had all 3 nameservers set up correctly, I went to SWITCH, the Swiss domain registry, and changed the listed nameservers for cwik.ch to my new setup. The process to do this varies by the registry you use, but all registries offer the facility. There is an extra step involved which is not necessary if you are using someone else’s nameservers: setting up the glue record. This is the mapping of your DNS server names to their IPs, which must be done statically at your registrar. In my case I could do it via a simple web interface as depicted here:

DNS glue

Each of the 3 servers need to be defined and the IP hard-coded. This IP is stored in the .ch root so other resolvers know how to recurse to the cwik.ch domain. If I ever change the IP of one of my servers, I’ll also need to update it at the registry.

Propagating zone updates: I’ve already explained why I chose not to configure a master/slave setup, choosing instead to have 3 masters. However this means I need to update the zone file manually on all 3 servers in order to make any changes. That’s not very convenient, so I wrote a small shell script to do it for me. Feel free to copy/use it if you find it’s useful.

comments: Comments Off on BIND DNS Server And Zone File Configuration tags: , , , , ,
Subscribe