Ubuntu Server 18.04 – Creating a secondary (slave) DNS server

Docker Compose Tutorial for Beginners

Depending on just one server to provide a resource to your network is almost never a good idea. If our DNS server has a problem and fails, our network users will be unable to resolve any names, internal or external. To rectify this, we can actually set up a slave DNS server that will cache zone records from the master and allow name resolution to work in case the primary fails. This is not required, but redundancy is always a good thing.

To set up a secondary DNS server, we first need to configure our primary server to allow it to transfer zone records to a slave server. To do so, we’ll need to edit the /etc/bind/named.conf.options file, which currently looks similar to the following:

options { 
        directory "/var/cache/bind"; 
        forwarders { 
                8.8.8.8; 
                8.8.4.4; 
        }; 
        dnssec-validation auto; 
 
        auth-nxdomain no; 
        listen-on-v6 { any; }; 
}; 

I’ve omitted some redundant lines from the file (such as comments). When we edited this file the last time, we uncommented the forwarders section and added two external DNS servers there. In order to allow the transfer of zone records to another server, we’ll need to add a new line to this file. Here’s the contents of this file again, with a new line added to it:

options { 
        directory "/var/cache/bind"; 
        allow-transfer { localhost; 192.168.1.2; }; 
        forwarders { 
                8.8.8.8; 
                8.8.4.4; 
        }; 
        dnssec-validation auto; 
 
        auth-nxdomain no; 
        listen-on-v6 { any; }; 
}; 

Basically, we added one line to the file, which allows zone transfer to an IP address of 192.168.1.2, which you’d want to change to be the IP address for your secondary DNS server. Next, restart the bind9 service on your primary server, and it should be ready to allow transfer to another machine.

On the slave DNS server, the first thing you’ll need to do is to install the bind9 packages as we did with the first server. Then, we’ll configure the slave server quite similar to the master server, but with some notable differences. On the slave server, you’ll omit the allow-transfer line that we added to the /etc/bind/named.conf.options file, since the slave server is only going to receive records, not transfer them. Like before, you’ll uncomment the forwarders section in the /etc/bind/named.conf.options file. In the /etc/bind/named.conf.local file, you’ll add an entry for our zone just as we did with the first server, but we’ll configure this file differently than we did the last time:

zone "local.lan" IN { 
    type slave; 
    masters { 192.168.1.1; }; 
    file "/var/lib/bind/net.local.lan"; 
}; 

Inside the /etc/bind/named.conf.local file on the slave server, we first identify it as a slave (type slave;) and then we set the master server to 192.168.1.1 (or whatever the IP address of your primary DNS server is). Then, we save our zone file to a different location than we did on the master; in this case, it is /var/lib/bind/net.local.lan. This is due to how the permissions differ on the slave and the master server, and /var/lib/bind is a good place to store this file. After the new configuration is in place, restart bind9 on both the slave and the master servers. At this point though, we should test both servers out one last time to ensure both are working properly.

In this chapter, I’ve mentioned the dig command a few times. It’s a great way to interrogate DNS servers to ensure they’re providing the correct records. One thing I haven’t mentioned so far is that you can specify a DNS server for the dig command to check, rather than having it use whatever DNS server the system was assigned. In my examples, I have two DNS servers set up, one at 192.168.1.1 and the other at 192.168.1.2. Specifying a DNS server to interrogate with the dig command is easy enough:

dig @192.168.1.1 fileserv 
dig @192.168.1.2 fileserv 

You should see results from both of your DNS servers. When you check the status of the bind9 daemon on your slave server (systemctl status bind9), you should see entries that indicate a successful transfer. The output will look similar to this:

May 06 13:19:47 ubuntu-server named[2615]: transfer of 'local.lan/IN' from 10.10.99.184#53: connected using 192.168.1.2#35275 
May 06 13:19:47 ubuntu-server named[2615]: zone local.lan/IN: transferred serial 201602093 
May 06 13:19:47 ubuntu-server named[2615]: transfer of 'local.lan/IN' from 10.10.99.184#53: Transfer status: success 
May 06 13:19:47 ubuntu-server named[2615]: transfer of 'local.lan/IN' from 10.10.99.184#53: Transfer completed: 1 messages, 10 records, 290 
May 06 13:19:47 ubuntu-server named[2615]: zone local.lan/IN: sending notifies (serial 201602093) 

From this point forward, you should have a redundant bind slave to work with, but the server is useless until you inform your clients to use it. To do that, we need to revisit our DHCP server configuration yet again. Specifically, the /etc/dhcp/dhcpd.conf file. Here are the sample contents of the file again, so you don’t need to flip back to the earlier section:

default-lease-time 86400; 
max-lease-time 86400; 
option subnet-mask 255.255.255.0; 
option broadcast-address 192.168.1.255; 
option domain-name "local.lan"; 
authoritative; 
subnet 192.168.1.0 netmask 255.255.255.0 { 
    range 192.168.1.100 192.168.1.240; 
    option routers 192.168.1.1; 
    option domain-name-servers 192.168.1.1; 
} 

On the last line, we inform clients to set their DNS server to 192.168.1.1. However, since we now have a slave server, we should change this file to include it so that it’s passed along to clients:

default-lease-time 86400; 
max-lease-time 86400; 
option subnet-mask 255.255.255.0; 
option broadcast-address 192.168.1.255; 
option domain-name "local.lan"; 
authoritative; 
subnet 192.168.1.0 netmask 255.255.255.0 { 
    range 192.168.1.100 192.168.1.240; 
    option routers 192.168.1.1; 
    option domain-name-servers 192.168.1.1, 192.168.1.2; 
} 

Basically, all we did was add the secondary server to the option domain-name-servers line. We separated the first with a comma, then we ended the line with a semicolon as we did before. At this point (assuming you’ve tested your secondary DNS server and trust it), you can restart the isc-dhcp-server daemon, and your nodes will have the primary and secondary DNS servers assigned to them the next time they check in for an IP address or to renew their existing lease.

That about does it for our journey into setting up bind. From now on, you have a DHCP server and a DNS server or two in your network, providing addressing and name resolution. We’ve pretty much set up two of the most common services that run on commercial routers, but we haven’t actually set up a router just yet. In the next section though, we’ll change that.

Comments are closed.