Running DNS locally for home network

Posted on

DNS, or the Domain Name System, is an essential component of modern internet communication. It allows us to reference computers by names instead of IP addresses. we will discuss how to install and configure the Bind9 DNS server as authoritative-only DNS servers on Ubuntu 14.04 machines.

Why set up a private DNS server?

This question is valid and the answer may vary depending on your home network environment. In our case we're working on application with the ability to manage thousand of hosts, adding a private DNS server may be more attractive instead of maintaining a host file on each client with IP/hostname mappings.

Install BIND on DNS Servers

BIND9 is available in the Main repository. No additional repository needs to be enabled for BIND9. On DNS servers, update apt and install it with package manage:

  $ sudo apt-get update
  $ sudo apt-get install bind9 bind9utils bind9-doc

Configure the Master Bind Server

Now that we have the software installed, we can begin by configuring our DNS server on the master server.

Before continuing, let's set BIND to IPv4 mode, edit the bind9 service parameters file (sudo privileges needed) and add "-4" to the OPTIONS variable. It should look like the following:

# /etc/default/bind9
OPTIONS="-4 -u bind"

Configuring the Options File

The first thing that we will configure to get started is the named.conf.options file.

The Bind DNS server is also known as named. The main configuration file is located at /etc/bind/named.conf. This file calls on the other files that we will be actually configuring.

Open the options file with sudo privileges in your editor

# /etc/bind/named.conf.options
options {
  directory "/var/cache/bind";
  recursion no;
  allow-transfer { none; };

  dnssec-validation auto;

  auth-nxdomain no;    # conform to RFC1035
  listen-on-v6 { any; };
};

Configuring the Local File

The next step that we need to take is to specify the zones that we wish to control this server. A zone is any portion of the domain that is delegated for management to a name server that has not been sub-delegated to other servers.

We are configuring the algonauti.lan domain and we are not going to be sub-delegating responsibility for any portion of the domain to other servers. So the zone will cover our entire domain.

To configure our zones, we need to open the /etc/bind/named.conf.local file with sudo privileges and append this configuration at the end of it (replace 192.168.24 with the actual subnet mask of your host):

zone "algonauti.lan" {
  type master;
  file "/etc/bind/zones/db.algonauti.lan";
};

zone "24.168.192.in-addr.arpa" {
  type master;
  file "/etc/bind/zones/db.192.168.24";
};

Create the Forward Zone File

We have told Bind about our forward and reverse zones now, but we have not yet created the files that will define these zones. If you recall, we specified the file locations as being within a subdirectory called zones. We need to create this directory:

$ sudo mkdir /etc/bind/zones

Now, open the forward zone /etc/bind/zones/db.algonauti.lan with sudo privileges in your text editor and paste the following settings (replace 192.168.24.24 with the actual IP address of your host):

;
; BIND data file for local loopback interface
;
$TTL    604800
@       IN      SOA     n1.algonauti.lan. root.algonauti.lan. (
                              5         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL

; Name servers
algonauti.lan.    IN      NS      ns1.algonauti.lan.

; A records for name servers
ns1               IN      A       192.168.24.24

; Other A records
@                 IN      A       192.168.24.24
www               IN      A       192.168.24.24

The same things need to be done with reverse data file located at /etc/bind/zones/db.192.168.24

;
; BIND reverse data file for local loopback interface
;
$TTL    604800
@       IN      SOA     algonauti.lan. root.algonauti.lan. (
                              5         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      ns1.algonauti.lan.
1.0.0   IN      PTR     ns1.algonauti.lan.

After restart BIND your primary DNS server is now setup and ready to respond to DNS queries.

sudo service bind9 restart

Use different DNS servers for different domains

Now we want to test our brand-new private DNS server; we'll be using a Macbook attached to the same LAN. Mac OS X has a very nice and simple generic way to set up a DNS server's routing.

In the simplest case, all you need to do is to create a text file in the directory /etc/resolver/ with the same name as the desired domain, and define the nameservers inside. In our case we need to resolve algonauti.lan with custom DNS 192.168.24.24.

$ sudo mkdir /etc/resolver
$ sudo echo 'nameserver 192.168.24.24' > /etc/resolver/algonauti.lan

From this moment on, all requests for algonauti.lan and its subdomains will go directly to specified servers, and all other requests will go to the default server in /etc/resolv.conf. No need to mess with bind configuration and it will work as soon as file created without restarts, reboots, logouts and other radical enforcements. We can test result with a simple ping to our new domain.

$ ping -c 3 www.algonauti.lan
PING www.algonauti.lan (192.168.24.24): 56 data bytes
64 bytes from 192.168.24.24: icmp_seq=0 ttl=64 time=0.539 ms
64 bytes from 192.168.24.24: icmp_seq=1 ttl=64 time=0.325 ms
64 bytes from 192.168.24.24: icmp_seq=2 ttl=64 time=0.301 ms

--- www.algonauti.lan ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.301/0.388/0.539/0.107 ms

Questions? Comments? Clarifications? Feel free to post them in the comments below, where courteous comments are not only welcome, but encouraged.