6 minutes read

How to set up Secondary DNS server

We've been talking about the use of Secondary DNS. Now, we are going to show you how you can set up a secondary DNS server. While exploring how to make this setup we'll be using BIND9 service for our DNS.

Specification:

OS Version: Ubuntu 18.04.3 (LTS) x64
IP addresses:
  • 12.13.14.15: Example local network IP
  • 13.14.15.16: Example Ubuntu DNS server IP
  • 14.15.16.17: Example CentOS DNS server IP
  • 15.16.17.18: Example IP our test domain should resolve to

We have made few "howto" articles earlier on the installation of the DNS on CentOS and Ubuntu servers. Now, we are going to use those two installations to set up one as master DNS and another as the slave DNS. So, to begin with, let's get familiar with DNS installation processes for CentOS or Ubuntu.

Configuration of the DNS Slave type

We will be using CentOS DNS server as a slave DNS. Let's jump right to set up Secondary DNS!

Since we are working on CentOS DNS server to set it up as slave DNS we need to open zone file /etc/named/bluegrid.awesome.zones and change it to reflect the following (make sure to change the IP address to reflect your own setup):

zone "bluegrid.awesome" IN {
    type slave;
    masters { 13.14.15.16; };
    file "db.bluegrid.awesome";
};

Important note: If you already have the file db.bluegrid.awesome (or however, was your test database file called) make sure to remove it so it doesn't interfere with sync from the master.

What we have essentially changed comparing to the default setting is the type of DNS and we have added parameter masters. The type defines this DNS instance as slave DNS which obtains the DNS information from the master server defined under the master parameter.

Important note: Parameter master defines master servers from which our slave DNS will obtain information. Here's the shocker, those servers under master parameter does NOT have to be set up as masters. Slave DNS can treat other slave DNS servers as master if used within this directive.

We have practically already set the CentOS server as a slave DNS. Now, let's define how the slave will know when to pull the data from master.

Zone transfer configuration

By default, master DNS will push the notification of the zone change to slave DNS. However, we want to be good engineers and make sure it's specifically enabled there. What we need to do is open zone file on the master DNS and edit it as follows:

zone "bluegrid.awesome" IN {
    type master;
    notify yes;
    file "db.bluegrid.awesome";
};

Note that this way we can enable notifications to slave DNS for this specific zone. If, however, we want this setup to be applied to all zones we'll place notify yes; under the options file:

options {
        notify yes;
...
}

What you set up within the zone file will have the priority so, make sure you don't override the all-zones setting.

Now, let's tell the DNS server which slaves to notify. We can do this on a per-zone basis or globally under the options context using parameter also-notify:

Zone file

zone "bluegrid.awesome" IN {
    type master;
    notify yes;
    also-notify { 14.15.16.17; };
    file "db.bluegrid.awesome";
};

Options file

options {
        notify yes;
        also-notify { 14.15.16.17; };
...
}

Why is this parameter called also-notify? Are there some other notifications and this one being additional?
- Well no, there are no background notifications. Master DNS will notify slave servers by default if they have the NS record. However, for more precise management of this setup, we are choosing to use a parameter that overrides the global behavior. This way we can specifically define allowed slave servers.

The next step is to allow transfers on the master DNS server. Same as with notifications, we can do this on both, zone file and options context level:

Zone file

zone "bluegrid.awesome" IN {
    type master;
    notify yes;
    also-notify { 14.15.16.17; };
    allow-transfer { 14.15.16.17; };
    file "db.bluegrid.awesome";
};

Options file

options {
        notify yes;
        also-notify { 14.15.16.17; };
        allow-transfer { 14.15.16.17; };
...
}

Testing this setup

Now we want to query a slave DNS server and since we have removed the db.bluegrid.awesome from the slave DNS we should still see proper response from it:

dig @14.15.16.17  -t SOA bluegrid.awesome +norecurs
; <<>> DiG 9.11.13-RedHat-9.11.13-5.el8_2 <<>> @14.15.16.17 -t SOA bluegrid.awesome +norecurs
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60660
;; flags: qr aa ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: cc1341d4084855e2d62f337b5f37342a66264d64108b0403 (good)
;; QUESTION SECTION:
;bluegrid.awesome.		IN	SOA
;; ANSWER SECTION:
bluegrid.awesome.	86400	IN	SOA	ns.bluegrid.awesome. root.bluegrid.awesome. 2020031201 43200 900 1814400 7200
;; AUTHORITY SECTION:
bluegrid.awesome.	86400	IN	NS	ns.bluegrid.awesome.
;; ADDITIONAL SECTION:
ns.bluegrid.awesome.	86400	IN	A	15.16.17.18
;; Query time: 0 msec
;; SERVER: 14.15.16.17#53(14.15.16.17)
;; WHEN: Sat Aug 15 01:02:34 UTC 2020
;; MSG SIZE  rcvd: 147

How to interpret these results

First, we have sent a non-recursive query which means we want this server to respond with what it has of required DNS information.
Then, the response came from a slave DNS that does not have the db.bluegrid.awesome meaning that slave DNS got this information from the master DNS. Master was the only one who had it!
Also, look at the following line:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60660
;; flags: qr aa ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

we can see "aa" under the flags list. "aa" means that this was the authoritative response thus, the server was indeed operating as a slave.

Quick test #2

Let's check if changing the A record on the master DNS will propagate through to slave DNS. I have changed the A record to 1.2.3.4 and check the slave DNS for a response. Also, make sure to increment the Serial number for this record you are changing so that slave recognizes the change:

dig @14.15.16.17 -t SOA bluegrid.awesome +norecurs
; <<>> DiG 9.11.13-RedHat-9.11.13-5.el8_2 <<>> @14.15.16.17 -t SOA bluegrid.awesome +norecurs
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6737
;; flags: qr aa ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 798362098203afbf259d31b95f37377f835f935b68d9e86c (good)
;; QUESTION SECTION:
;bluegrid.awesome.		IN	SOA
;; ANSWER SECTION:
bluegrid.awesome.	86400	IN	SOA	ns.bluegrid.awesome. root.bluegrid.awesome. 2020031201 43200 900 1814400 7200
;; AUTHORITY SECTION:
bluegrid.awesome.	86400	IN	NS	ns.bluegrid.awesome.
;; ADDITIONAL SECTION:
ns.bluegrid.awesome.	86400	IN	A	1.2.3.4
;; Query time: 0 msec
;; SERVER: 14.15.16.17#53(14.15.16.17)
;; WHEN: Sat Aug 15 01:16:47 UTC 2020
;; MSG SIZE  rcvd: 147

Looking good! We have successfully created and set up Secondary DNS server.