Announcement

How to Set Up DNS Servers with BIND on Ubuntu 17.10



BIND (Berkeley Internet Name Domain) is the most wanted DNS software over the Internet. The BIND package is available for all Linux distributions including Ubuntu, which makes the installation simple and straightforward.


In this tutorial, we will show you how to install, configure and administer BIND 9 as a private DNS server on a Ubuntu 17.10. For the purpose of this guide, we will use the 172.22.10.0/24 subnet.


Prerequisites:


  • Two Ubunutu Servers (nsrv1 and nsrv2) connected to a private network
  • A DNS clients (Windows, Linux, Unix) machine that will connect to your DNS servers


Install BIND on Both Servers

If you are done with above prerequisites, you are ready to begin installing the packages on both servers:

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

Sample Output
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  libirs141
Suggested packages:
  bind9-doc resolvconf
The following NEW packages will be installed:
  bind9 bind9utils libirs141
0 upgraded, 3 newly installed, 0 to remove and 17 not upgraded.
Need to get 604 kB of archives.
After this operation, 2,996 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://us.archive.ubuntu.com/ubuntu artful/main amd64 libirs141 amd64 1:9.10.3.dfsg.P4-12.6ubuntu1 [18.3 kB]
Get:2 http://us.archive.ubuntu.com/ubuntu artful/main amd64 bind9utils amd64 1:9.10.3.dfsg.P4-12.6ubuntu1 [206 kB]
Get:3 http://us.archive.ubuntu.com/ubuntu artful/main amd64 bind9 amd64 1:9.10.3.dfsg.P4-12.6ubuntu1 [380 kB]
Fetched 604 kB in 3s (187 kB/s)
Preconfiguring packages ...
Selecting previously unselected package libirs141:amd64.
(Reading database ... 110883 files and directories currently installed.)
Preparing to unpack .../libirs141_1%3a9.10.3.dfsg.P4-12.6ubuntu1_amd64.deb ...
Unpacking libirs141:amd64 (1:9.10.3.dfsg.P4-12.6ubuntu1) ...
Selecting previously unselected package bind9utils.
Preparing to unpack .../bind9utils_1%3a9.10.3.dfsg.P4-12.6ubuntu1_amd64.deb ...
Unpacking bind9utils (1:9.10.3.dfsg.P4-12.6ubuntu1) ...
Selecting previously unselected package bind9.
Preparing to unpack .../bind9_1%3a9.10.3.dfsg.P4-12.6ubuntu1_amd64.deb ...
Unpacking bind9 (1:9.10.3.dfsg.P4-12.6ubuntu1) ...
Setting up bind9utils (1:9.10.3.dfsg.P4-12.6ubuntu1) ...
Processing triggers for ufw (0.35-5) ...
Rules updated for profile 'Apache Full'

Processing triggers for ureadahead (0.100.0-20) ...
Setting up libirs141:amd64 (1:9.10.3.dfsg.P4-12.6ubuntu1) ...
Processing triggers for libc-bin (2.26-0ubuntu2) ...
Processing triggers for systemd (234-2ubuntu12.1) ...
Processing triggers for man-db (2.7.6.1-2) ...
Setting up bind9 (1:9.10.3.dfsg.P4-12.6ubuntu1) ...
Adding group `bind' (GID 119) ...
Done.
Adding system user `bind' (UID 114) ...
Adding new user `bind' (UID 114) with group `bind' ...
Not creating home directory `/var/cache/bind'.
wrote key file "/etc/bind/rndc.key"
#
Created symlink /etc/systemd/system/multi-user.target.wants/bind9.service → /lib/systemd/system/bind9.service.
Processing triggers for systemd (234-2ubuntu12.1) ...
Processing triggers for ureadahead (0.100.0-20) ...
Processing triggers for ufw (0.35-5) ...
Rules updated for profile 'Apache Full'

To set BIND to IPv4 mode, you will do that by editing the “/etc/default/bind9” file on both servers and adding “-4” to the OPTIONS variable:

sudo nano /etc/default/bind9

The edited file should look something like this:

# run resolvconf?
RESOLVCONF=no

# startup options for the server
OPTIONS="-4 -u bind"

Save and exit the file.


Configure the Primary DNS Server

You need to edit the named.conf.options file:

sudo nano /etc/bind/named.conf.options

On top of the options block, add a new block called trusted.This list will allow the clients specified in it to send recursive DNS queries to our primary server. We will also add a couple of configuration settings to enable recursive queries on our nsrv1 and to have the server listen on our private network, add the configuration settings under the directory “/var/cache/bind” directive like in the example below:

acl "trusted" {
172.22.10.100;
172.22.10.200;
172.22.10.210;
172.22.10.220;
};
options {
directory "/var/cache/bind";
recursion yes;
        allow-recursion { trusted; };
        listen-on { 172.22.10.100; };
        allow-transfer { none; };

forwarders {
8.8.8.8;
8.8.4.4;
};
};

If the “listen-on-v6” directive is present in the named.conf.options file, delete it as we want BIND to listen only on IPv4.

When you are finished, Save and close the file

Now on nsrv1, open the named.conf.local file for editing:

sudo nano /etc/bind/named.conf.local

zone "example.com" {
    type master;
    file "/etc/bind/zones/db.example.com";
    allow-transfer { 172.22.10.200; };
};

zone "10.22.172.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/db.172.22.10";
    allow-transfer { 172.22.10.200; };
};

If your servers are in multiple private subnets in the same physical location, you need to specify a zone and create a separate zone file for each subnet.

When you are finished, save and close the file.

Now we’ll create the directory where we will store our zone files in:

sudo mkdir /etc/bind/zones

We will use the sample db.local file to make our forward zone file, let’s copy the file first:

cd /etc/bind/zones
sudo cp ../db.local ./db.example.com

Now edit the forward zone file we just copied:

sudo nano /etc/bind/zones/db.example.com

Replace localhost with your nsrv1 server’s FQDN, then replace “root.localhost” with “admin.example.com”.Every time you edit the zone file, increment the serial value before you restart named otherwise BIND won’t apply the change to the zone, we will increment the value to “3”. Add the nameserver records at the end of the file. After that add the A records for the hosts that need to be in this zone. That means any server whose name we want to end with “.example.com”:

The db.example.com file should look something like the following:

$TTL 604800
@ IN SOA nsrv1.example.com. admin.example.com. (
      3 ; Serial
604800 ; Refresh
  86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL

; name servers - NS records
IN NS nsrv1.example.com.
IN NS nsrv2.example.com.

; name servers - A records
nsrv1.example.com. IN A 172.22.10.100
nsrv2.example.com IN A 172.22.10.200

; 172.22.10.0/24 - A records
anyhost1.example.com IN A 172.22.10.210
anyhost2.example.com IN A 172.22.10.220

When you are done, save and close the file


Create the Reverse Zone File

We specify the PTR records for reverse DNS lookups in the reverse zone files. When the DNS server receives a PTR lookup query for an example for IP: “172.22.10.220”, it will check the reverse zone file to retrieve the FQDN of the IP address, in our case that would be “anyhost2.example.com”.

We will create a reverse zone file for every single reverse zone specified in the named.conf.local file we created on nsrv1. We will use the sample db.127 zone file to create our reverse zone file:

cd /etc/bind/zones
sudo cp ../db.127 ./db.172.22.10

Edit the reverse zone file so it matches the reverse zone defined in named.conf.local:

sudo nano /etc/bind/zones/db.172.22.10

You should modify the SOA record and increment the serial value. Add the nameserver records at the end of the file. Add the PTR records for all hosts that are on the same subnet in the zone file you created. This consists of our hosts that are on the 172.22.10.0/24 subnet. In the first column we reverse the order of the last two octets from the IP address of the host we want to add:

The “/etc/bind/zones/db.172.22.10” reverse zone file should look something like this:

$TTL 604800
@ IN SOA nsrv1.example.com. admin.example.com. (
      2 ; Serial
604800 ; Refresh
  86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
; name servers - NS records
IN NS nsrv1.example.com.
IN NS nsrv2.example.com.
; PTR records
100.10 IN PTR nsrv1.example.com. ;172.22.10.100
200.10 IN PTR nsrv2.example.com. ;172.22.10.200
210.10 IN PTR anyhost1.example.com. ;172.22.10.210
220.10 IN PTR anyhost2.example.com. ;172.22.10.220

Save and exit the reverse zone file.


Verify the Configuration Files

Use the following command to check the configuration syntax of all the named.conf files that we configured:

sudo named-checkconf

If your configuration files don’t have any syntax problems, the output will not contain any error messages. However if you do have problems with your configuration files, compare the settings in the “Configuring the Primary DNS Server” section with the files you have errors in and make the correct adjustment, then you can try executing the named-checkconf command again.

The named-checkzone can be used to check the proper configuration of your zone files.You can use the following command to check the forward zone “example.com”:

sudo named-checkzone example.com db.example.com

And if you want to check the reverse zone configuration, execute the following command:

sudo named-checkzone 10.22.172.in-addr.arpa /etc/bind/zones/db.172.22.10

Once you have properly configured all the configuration and zone files, restart the BIND service:

sudo systemctl restart bind9
sudo systemctl status bind9

Sample output
bind9.service - BIND Domain Name Server
   Loaded: loaded (/lib/systemd/system/bind9.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2017-11-23 10:58:29 PKT; 29min ago
     Docs: man:named(8)
  Process: 108624 ExecStop=/usr/sbin/rndc stop (code=exited, status=0/SUCCESS)
 Main PID: 108627 (named)
    Tasks: 4 (limit: 19660)
   Memory: 9.4M
      CPU: 16ms
   CGroup: /system.slice/bind9.service
           └─108627 /usr/sbin/named -f -4 -u bind

Nov 23 10:58:30 nsrv1.example.com named[108627]: zone 0.in-addr.arpa/IN: loaded serial 1
Nov 23 10:58:30 nsrv1.example.com named[108627]: zone localhost/IN: loaded serial 2
Nov 23 10:58:30 nsrv1.example.com named[108627]: zone example.com/IN: NS 'nsrv2.example.com' has no address records (A or AAAA)
Nov 23 10:58:30 nsrv1.example.com named[108627]: zone example.com/IN: not loaded due to errors.
Nov 23 10:58:30 nsrv1.example.com named[108627]: zone 255.in-addr.arpa/IN: loaded serial 1
Nov 23 10:58:30 nsrv1.example.com named[108627]: zone 127.in-addr.arpa/IN: loaded serial 1
Nov 23 10:58:30 nsrv1.example.com named[108627]: zone 10.22.172.in-addr.arpa/IN: loaded serial 1
Nov 23 10:58:30 nsrv1.example.com named[108627]: all zones loaded
Nov 23 10:58:30 nsrv1.example.com named[108627]: running
Nov 23 10:58:30 nsrv1.example.com named[108627]: zone 10.22.172.in-addr.arpa/IN: sending notifies (serial 1)


Configure the Secondary DNS Server

Setting up a secondary DNS server is always a good idea as it will serve as a failover and will respond to queries if the primary server is unresponsive.

On nsrv2, edit the named.conf.options file:

sudo nano /etc/bind/named.conf.options

At the top of the file, add the ACL with the private IP addresses for all your trusted servers:

acl "trusted" {
        172.22.10.100;
        172.22.10.200;
        172.22.10.210;
        172.22.10.220;
};
options {
recursion yes;
        allow-recursion { trusted; };
        listen-on { 172.22.10.100; };
        allow-transfer { none; };

        forwarders {
                8.8.8.8;
                8.8.4.4;
        };

Save and exit the file.

Now open the named.conf.local file for editing:

sudo nano /etc/bind/named.conf.local

Now you should specify slave zones that match the master zones on the nsrv1 DNS server. The masters directive should be set to the nsrv1 DNS server’s private IP address:

zone "example.com" {
    type slave;
    file "slaves/db.example.com";
    masters { 172.22.10.100; };
};

zone "10.22.172.in-addr.arpa" {
    type slave;
    file "slaves/db.172.22.10";
    masters { 172.22.10.100; };
};

Save and exit the file.

Use the following command to check the syntax of the configuration files:

sudo named-checkconf

Then restart the BIND service:

sudo systemctl restart bind9


Configure the DNS Clients

We will now configure the hosts in our 172.22.10.0/24 subnet to use the nsrv1 and nsrv2 servers as their primary and secondary DNS servers. This greatly depends on the OS the hosts are running but for most Linux distributions the settings that need to be changed reside in the /etc/resolv.conf file.

Generally on the Ubuntu, Debian and CentOS distributions just edit the /etc/resolv.conf file, execute the following command as root:

nano /etc/resolv.conf

Then replace the existing nameservers with:

nameserver 172.22.10.100 #nsrv1
nameserver 172.22.10.200 #nsrv2

Save and exit the file

Now, test if your clients can send queries to the DNS servers you just configured:

nslookup anyhost1.example.com

Sample Output:
Server:     172.22.10.100
Address:    172.22.10.100#53

Name:   anyhost1.example.com
Address: 172.22.10.210

You can also test the reverse lookup by querying the DNS server with the IP address of the host:

nslookup 172.22.10.210

Sample Output:
Server:     172.22.10.100
Address:    172.22.10.100#53

210.10.22.172.in-addr.arpa   name = anyhost1.example.com.

Check if all of the hosts resolve correctly using the commands above, if they do that means that you’ve configured everything properly.