Dizwell Informatics

News from Nowhere

Build a Bind DNS Server

A Domain Name Server (DNS) resolves machines names (“feynman”) into IP addresses (192.168.0.1). Having your own DNSServer running at home means your domestic PCs can communicate amongst themselves without having to bother any external DNS servers (such as those provided by your ISP). That saves traffic and time.

Bind is the most common DNS server product in use today, probably, though it’s quite possibly overkill for home use. A lot of people would recommend using dnsmasq instead, for home use. But I don’t see a problem with using a Bind server at home: it’s not really difficult to do, and the resource requirements are pretty small: I run mine on the same 128MB virtual machine that hosts an apache webserver and my DHCP server, so it’s not exactly causing me to have a hardware meltdown!

The following instructions work for RHEL 6.3, with Bind version 9.8. They replace an article I wrote way back in 2006 for running Bind 9.2 on Centos 4.3… how time flies!

As root, install the appropriate software:

yum -y install bind bind-utils

Now edit /etc/named.conf like so:

options {
//      listen-on port 53 { 127.0.0.1; };
//      listen-on-v6 port 53 { ::1; };
        directory "/var/named";
        dump-file "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        allow-query { localhost; 192.168.0.0/24; };
        forward first;
        forwarders { 208.67.222.222; 208.67.220.220; };
        recursion yes;
        dnssec-enable no;
        dnssec-validation no;
        dnssec-lookaside auto;

        /* Path to ISC DLV key */
        bindkeys-file "/etc/named.iscdlv.key";

        managed-keys-directory "/var/named/dynamic";
};
logging {
        channel default_debug {
            file "data/named.run";
            severity dynamic;
         };
};
zone "." IN {
         type hint;
         file "named.ca";
};
zone "dizwell.home" IN {
        type master;
        file "dizwell.hosts";
};
zone "0.168.192.in-addr.arpa" IN {
        type master;
        file "192.168.0.reverse";
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

In the Options section you see here, I have commented out the line (that is, added “//” at its beginning) that mentions listen-on port 53… -it’s ‘on’ by default, but we need it off. You can delete the entire line if you like, or comment it out as I have here. I’ve also edited the line about ‘listening on v6′: I don’t use IPv6 at home, so I’ve no need for my DNS server to handle those sorts of addresses.

The allow-query line has been edited to permit all the PCs on my home network to make DNS queries. The “192.168.0.0/24″ addition here means all PCs with a 192.168… address will be able to connect.

The forward first and forwarders lines means my domestic DNS server knows how to refer queries it can’t handle to the “proper” DNS servers run by my ISP (the 208.67 adresses shown are those belonging to the OpenDNS servers). These lines are crucial in allowing all my home PCs to connect to the Internet. Without them, feynman.dizwell.home could be resolved, but google.com could not.

The dnssec-enable and dnssec-validation lines are also crucial. DNSSEC is a fairly new protocol that encrypts DNS traffic (which is, generally, an excellent idea). But if you don’t have the encryption keys used by your ISP’s servers, then all external DNS traffic will come back untrusted -and you are back to not being able to connect to the outside world. For proper Internet functionality at home, therefore, turning off DNSSEC is the simplest answer.

Finally, the file declares two new zones: a dizwell.home zone, in which names get turned into IP addresses (called a ‘forward zone’); and a weird-looking 0.168.192.in-addr.arpa zone, in which IP addresses get turned back into host names (called a ‘reverse lookup zone’). Each zone ‘stanza’ declares where its own confguration file exists: we next have to create those two files:

touch /var/named/dizwell.hosts
touch /var/named/192.168.0.reverse
chown named:named /var/named/dizwell.hosts
chown named:named /var/named/192.168.0.reverse

Now edit /var/named/dizwell.hosts so that it looks like this:

$TTL 86400
@ IN SOA maxwell.dizwell.home. hjr.dizwoll.com. (
2012111902 ;Serial
3600 ;Refresh
1800 ;Retry
604800 ;Expire
86400 ;Minimum TTL
)

		IN NS 	maxwell.dizwell.home. 
		IN A 	192.168.0.251

maxwell	IN A 	192.168.0.251
galileo 	IN A 	192.168.0.101
newton 	IN A 	192.168.0.100
dirac 	IN A 	192.168.0.32
feynman 	IN A 	192.168.0.33
rutherford 	IN A 	192.168.0.34
kelvin 	IN A 	192.168.0.53

;; end of zone
;;

These are, obviously, my own network details, so yours will be different!

The first part of the file simply assigns a unique serial number to this configuration. It’s a number based on a date. The point is to increment it every time you edit the file. Notice on the line above the serial number that the DNS Server name is specified (maxwell.dizwell.home) with a period/full-stop at the end of it. That trailing full-stop is critical and must be present. On that same line is a reference to the email address of the administrator of this server, again with a trailing full-stop, and with the “@” symbol turned into a full-stop, too. So [email protected] becomes hjr.dizwell.com.

The middle two lines that begin IN … are merely declaring Maxwell to be the Names Server (hence the NS bit) and that it has an IP address of 192.168.0.251.

After that comes the list of all the PCs, netbooks, laptops and other bits of hardware that make up my home network. You just specify the hostname, IN A and then its IP address, each new host on a new line.

Now edit /var/named/192.168.0.reverse:

$TTL 86400
@ IN SOA maxwell.dizwell.home. hjr.dizwoll.com. (
2012011903 ;Serial
3600 ;Refresh
1800 ;Retry
604800 ;Expire
86400 ;Minimum TTL
)

	IN NS 	maxwell.dizwell.home.

	IN PTR 	dizwell.home.
	IN A 	255.255.255.0

251 	PTR maxwell.dizwell.home.
101 	PTR galileo.dizwell.home.
100 	PTR newton.dizwell.home.
32 	PTR dirac.dizwell.home.
33 	PTR feynman.dizwell.home.
34 	PTR rutherford.dizwell.home.
53 	PTR kelvin.dizwell.home.

;; end of zone
;;

The first part of this file is much the same as before: server names and email addresses with trailing full-stops, unique serial numbers and so on.

Again, there’s an IN line which declares Maxwell to be my Name Server.

There are two new IN lines which declare which domain the names server is authoritative for -again, note the trailing full-stop. The ‘A’ line is using the netmask for my home network.

After that comes the set of pointer records (hence the PTR designator) which match the last bit of a PC’s IP address to its full-qualified domain name (plus a trailing full-stop). So the ’101′ line means that IP 192.168.0.101 belongs to a PC with a name ‘galileo.dizwell.home’, and so on.

With both zone files saved correctly, issue this command to switch on your DNS server:

service named start

You can arrange for the service to start automatically at every reboot by issuing this:

chkconfig named on

Finally ensure that your DNS server knows to consult itself for names resolution duties: edit /etc/resolv.conf so that it reads:

nameserver 192.168.0.251
search dizwell.home

Now you can test that the DNS server is resolving names properly like so:

[[email protected] ~]# nslookup feynman
Server: 192.168.0.251
Address: 192.168.0.251#53

Name: feynman.dizwell.home
Address: 192.168.0.33

That tells you that the DNS server with IP address 192.168.0.251 was consulted about the name ‘feynman’ (and that port 53 was used in the looking up, too, which is the default port for DNS traffic -and needs to be open, if you are using a firewall). Server 192.168.0.251 found an entry in its zone files for ‘feynman.dizwell.home’, and that entry says that PC has IP address 192.168.0.33 …which, if you check my dizwell.hosts file above, is true.

You should also check that the DNS server, when it can’t resolve them itself, knows how to forward name resolution queries to the outside world:

[[email protected] ~]# nslookup google.com
Server: 192.168.0.251
Address: 192.168.0.251#53

Non-authoritative answer:
Name: google.com
Address: 74.125.237.145
Name: google.com
Address: 74.125.237.146

All that then remains is to re-configure all your clients so that they know to talk to the new DNS server, too. In Linux, that potentially means editing both the /etc/resolv.conf file, as we did before on the DNS Server itself AND using the graphical System > Preferences > Network Connections tool to set the right DNS server and search domain via the Network Manager tool. On Windows, you just need to alter the adapter settings once (via the Network and Sharing Centre, if you’re using Windows 7).

Finally, if you have a DHCP Server on the premises, just make sure it’s updated to know about the new DNS Server address: it will hand that out as the DNS address which should apply to any new client that makes contact, so you need to ensure the right address is configured before that happens.

PS: If you wanted to know how to create a Bind DNS Server for a machine running Debian rather than Red Hat/CentOS/Scientific Linux, a brief walk-through is contained in Section 8 of this article.