Skip to main content

Install DNS server bind9 on ubuntu 22.04

 

Part 1 - Recursive DNS
Part 2 - Authoritative DNS
Part 3 - Reverse DNS
Part 4 - Secure Zone Transfer and RNDC

DNS Diagram


For reference, these are the IP address assignments for the servers:




Both will be configured as recursive and authoritative DNS servers as part of this lab.

Part 1 - Recursive DNS

Recursive DNS server, also known simply as Resolver, answers DNS queries by sending iterative queries until it receives an answer or an error. In this lab, you will setup a resolver using BIND 9.

There are 2 steps in this part:
  • Step 1 - Install and Verify BIND
  • Step 2 - Configure Recursive DNS Server
  • Step 3 - Resolving Domains

Step 1 - Install and verify DNS

For this lab, BIND 9 has already been installed, so this step only requires you to verify it is running and be familiar with BIND commands

1. Select primary dns and login to the machine
          username : username
          password  : password

2.The following steps will install BIND and other utilities using APT, Ubuntu's package manager. This part is already completed

sudo apt -y update
sudo apt -y upgrade
sudo apt install -y bind9 bind9utils bind9-doc

3. Check where BIND is installed and note the version.

which named
named -v 

4. It should show that named is located in /usr/sbin/named and running BIND version 9.18.30 for Ubuntu 22.04.

5. Check if BIND is running.

ps aux | grep named


Check the you see the bind process running.

sudo systemctl status named

You may use bind9 instead of named as follows. This is an alias defined in the service file /lib/systemd/system/named.service.

sudo systemctl status bind9

If the service is not currently running, start as follows:

sudo systemctl start bind9

Confirm that you see the status as active (running).

6. Check the configuration file.
The main config folder used by BIND is /etc/bind.
cd /etc/bind/

Check the contents of this folder. It already contains default configuration and zone files from the installation.

ls -al

Check the config file.

ls -al named.conf*

The main configuration file is named.conf which includes a few files:
  • named.conf.options - contains global configuration options
  • named.conf.local - add custom zones and zone-specific config
  • named.conf.default-zones - zone statements for localhost, forward and reverse zones per RFC1912
7. Check the logs and notice if there are any errors. Open a new tab in the Terminal, and run the command:

sudo tail -f /var/log/named/bind.log



The zone files should load correctly with no issues.

Keep checking the logs whenever you update the config file or restart the BIND service. This is a good way to spot errors and fix them.

8. Open secondarydns and do the same steps above. Make sure to confirm that BIND is running without errors. Note that the configuration file may be in a subfolder in /etc/bind.

From the secondarydns:

cd /etc/bind
ls -alh /etc/bind/named.conf*
sudo systemctl status named





Step 2 - Configure Recursive DNS Server

Now that you are familiar with the lab setup and BIND9 is running, we can proceed with configuring the server as a resolver.

1. Open primarydns. Go to the BIND directory, open a new tab in the terminal window and type the following command:

cd /etc/bind/

2. Check the contents of the root hints file.

**Hints file** contains the records of the authoritative name servers for the root zone, which allows the DNS software to bootstrap the DNS resolution process. This includes the resource records for all the 13 root servers [A-M].root-servers.net.

For this version of BIND, a copy of the root hints file can be found in /usr/share/dns/root.hints.
Check the contents of this file. It should have NS, A, AAAA records for each rootserver.

more /usr/share/dns/root.hints

For example, the records for a.root-servers.net is shown as follows:

.                                      3600000      NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
A.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:ba3e::2:30


To download a fresh copy of the hints file manually, go to https://www.internic.net/domain/named.root or check the IANA website for all root files https://www.iana.org/domains/root/files.

cd ~
wget https://www.internic.net/domain/named.root
sudo mv named.root /etc/bind/

Most DNS software including BIND now comes with a built-in root hints zone and loads the hints file automatically. It is also possible to manually configure and maintain the hints file.

3. Update the BIND configuration file. First, open named.conf.options and check the directory path and update as needed.

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

The options statement defines global settings and parameters used by the nameserver. Update or add the line starting with "directory" within the options clause, and point to the /var/cache/bind folder. This is the default location of relative filenames defined in the config.

directory "/var/cache/bind";

4. Still in named.conf.options config file, add the following line to set recursion.

recursion yes;


Note that this is also the default, so this line may be ommitted. However, it is recommended to add so you can quickly disable if needed by setting to no.

5. Still in named.conf.options config file, create an access-list clause to allow queries only from the local network.

acl trusted {
     localnets;
     localhost;
};

From the options clause, add the following

allow-query { any; };
allow-recursion { trusted; };
allow-query-cache { trusted; };

After the last 3 instructions, the config file should looks as follows:

options {
      directory "/var/cache/bind";
      recursion yes;
      allow-query { any; };
      allow-recursion { trusted; };
      allow-query-cache { trusted; };
    ....
};

acl trusted {
     localnets;
     localhost;
};

Exit and save the file using :wq

If neither allow-recursion and allow-query-cache is set, the default (localnets and localhost) is used;

6. Next, open named.conf.default-zones and update the recursive name server configuration.

sudo vi /etc/bind/named.conf.default-zones


Press i to insert text.

zone statement is used to define a zone. We will use this further to define default and authoritative zones later. For this part, update the zone statement that explicitly defines the hints file. As explained previously, this is optional since most DNS software will load the hints automatically.

zone "." {
       type hint;
       file "/etc/bind/named.root";
};

To save and exit, press ESC key and type :wq

7. In the same named.conf.default-zones file, check that the localhost forward and reverse zones are added. This indicates that the server is authoritative for localhost forward and reverse zones.

more /etc/bind/named.conf.default-zones

zone "localhost" {
       type master;
       file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
       type master;
       file "/etc/bind/db.127";
};

Also check that the broadcast zones are added:

zone "0.in-addr.arpa" {
       type master;
       file "/etc/bind/db.0";
};
zone "255.in-addr.arpa" {
       type master;
       file "/etc/bind/db.255";
};

8. Check the zone files in the same directory.

Confirm that the corresponding zone files (db.local, db.127, db.0 and db.255) referenced in the zone statements in previous step can be found in /etc/bind folder. These were automatically created during BIND install.

cd /etc/bind
ls -alh

Let's check one of the zone files.

sudo vi /etc/bind/db.local

(Optional) Update the serial and the timing parameters as below. Press i to insert text.

$TTL 300
@   IN  SOA localhost.  root.localhost. (
                              2025061201  ;serial
                              3600        ;refresh
                              1800        ;retry
                              86400       ;expire
                              10800       ;negative ttl
                              );

@   IN  NS  localhost.
@   IN  A   127.0.0.1
@   IN  AAAA   ::1


The serial is a 10-digit number, commonly written in the date format YYYYMMDDXX, where XX is an incrementing number. Remember to update and increment the serial everytime you make changes to the zone file.

To save and exit, press ESC key and type :wq

9. Open named.conf.options and check that the logging option has been configured.

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

If not added yet, add the following logging statement at the end of the file (outside of the options statement).

logging {
      channel named_log { 
             file "/var/log/named/bind.log" versions 3 size 5m; 
             severity info; 
             print-time yes;
             print-severity yes; 
             print-category yes;
     };
     category default { named_log; };
     category config  { named_log; };
     category queries { named_log; };
     category query-errors { named_log; };
     category dnssec { named_log; };
     category xfer-in  { named_log; };
     category xfer-out { named_log; };
     category security { named_log; };
};

This tells DNS to save the logs into bind.log folder instead of the default syslog. You may also create multiple channels and add the categories to separate channels.

10. Confirm that the configuration file has no error.

named-checkconf /etc/bind/named.conf

If successful, there should be no output and it will just show the next prompt.

11. We can now run BIND with the new or updated configuration.

sudo systemctl stop named
sudo systemctl start named
sudo systemctl status named

Verify that there are no errors in the log file:

sudo tail -f /var/log/named/bind.log

12. (OPTIONAL) Configure the secondary DNS as recursive. Open secondarydns and do the same steps as above.

First update named.conf.options to add directory and set recursion to yes.

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

options {
      directory "/var/cache/bind";
      recursion yes;
      allow-query { any; };
      allow-recursion { trusted; };
      allow-query-cache { trusted; };
      ....
};

acl trusted {
     192.168.0.0/16;
     localnets;
     localhost;
};


Update named.conf.options to update logging.

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

If not added yet, add the following logging statement at the end of the file (outside of the options statement).

logging {
      channel named_log { 
             file "/var/log/named/bind.log" versions 3 size 5m; 
             severity info; 
             print-time yes;
             print-severity yes; 
             print-category yes;
      };
      category default { named_log; };
      category config  { named_log; };
      category queries { named_log; };
      category query-errors { named_log; };
      category dnssec { named_log; };
      category xfer-in  { named_log; };
      category xfer-out { named_log; };
      category security { named_log; };
   };

Check that there are no syntax errors in the config file.

named-checkconf /etc/bind/named.conf

Then restart the BIND service.

sudo systemctl stop named
sudo systemctl start named
sudo systemctl status named

Download a copy of the root hints file.

cd ~
wget https://www.internic.net/domain/named.root

sudo mv named.root /etc/bind/

Then update named.conf.default-zones to add the zone statement for hints.

sudo vi /etc/bind/named.conf.default-zones

zone "." {
       type hint;
       file "/etc/bind/named.root";
};

Type :wq to exit.

Then restart BIND.

sudo systemctl restart named
sudo systemctl status named


Step 3 - Resolving domains

1. Open primarydns. Test the recursive name server to get an A and AAAA record for any domain.

Let's try to resolve wwww.academy.apnic.net. What is the IP address?

dig @localhost google.com
dig @127.0.0.1 google.com


2. (Optional) Update the nameserver configuration.

In Linux systems that use systemd, /etc/resolv.conf points to the local stub resolver 127.0.0.53.

more /etc/resolv.conf

To update, open /etc/systemd/resolved.conf and update the line starting with DNS=

sudo vi /etc/systemd/resolved.conf

If this is not updated yet, set DNS to use the local ip of the primary server

DNS=85.209.163.249

Restart systemd-resolved

sudo systemctl restart systemd-resolved
sudo systemctl status systemd-resolved






























3. Now that the machine is using your resolver, you may simply run dig without the @ parameter.

dig google.com

4. Try to resolve other domains on the Internet.

To find an A record:

dig facebook.com

To find the nameservers of a domain:

dig google.com -t NS

5. Since we are logging queries, you can also see these in the logs.

sudo tail -f /var/log/named/bind.log

6. Login to secondarydns and try to resolve domains.


Part 2 - Authoritative DNS

An Authoritative DNS server answers user queries for the zones that they have authority for. It can be configured to be authoritative for one or more zones.

There are 2 steps in this part:
  • Step 1 - Configure the Primary DNS Server
  • Step 2 - Configure the Secondary DNS Server

Step 1 - Configure the Primary DNS Server

1. Open primarydns. Go to the master directory where our custom zonefiles will be added.

cd /etc/bind/master

If the directory doesn't exist, you can create it with this command

sudo mkdir /etc/bind/master

2. For this lab, we will use the domain herdiansah-lab.xyz.

Create a zone file for your domain in the directory. Add the necessary resource recourds like NS, A, TXT and MX records.

sudo vi db.herdiansah-lab

Add the following content to the zonefile db.herdiansah-lab for the SOA record and NS record.

Press i to insert text

$TTL 300
@       SOA     NS.herdiansah-lab.xyz.  email.NS.herdiansah-lab.xyz. (
                                  2025082209  ;serial no. 
                                  3600             ;refresh 
                                  1800             ;retry
                                  86400           ;expire
                                  10800           ;negative cache ttl
                                  );
@       NS      ns1.herdiansah-lab.xyz.


A SOA record contains administrative information about the zone - the authoritative nameserver, admin contact, and timing parameters for zone transfers.    

3. Add a few more resource records.

To do this, open the file db.herdiansah-lab again to add the following lines. Be creative and add records for typical services that you find in a network, such as mail, authentication, file server etc.

ns1       A       85.209.163.249
www     A       85.209.163.260

herdiansah-lab.xyz.         MX  10 mail01
                                     MX  20 mail02

mail01   A       85.209.163.271
mail02   A       85.209.163.272 

To save and exit, press ESC key and type :wq

Check for any errors.

named-checkzone herdiansah-lab.xyz db.herdiansah-lab

If successful, the output shows

zone herdiansah-lab.xyz/IN: loaded serial 2025082209
OK






If the output shows an error, check the db file again and fix.

A resource record is an entry in dns that maps one resource to another. Some examples are: * A record - maps domain to IPv4 address * AAAA record - maps domain to IPv6 address * NS record - maps to the nameserver * MX record - specifies the mail servers for the domain

4. Update the configuration file and add a zone statement for the new zone. Please note that the primary zone is of type "master" while a secondary zone is of type "slave".

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

Press i to insert text

Add the following content:

zone "herdiansah-lab.xyz" {
       type master;
       file "/etc/bind/master/db.herdiansah-lab";
};

To save and exit, press ESC key and type :wq

Check for errors and fix if needed.

named-checkconf /etc/bind/named.conf

5. Run the BIND service.

sudo systemctl stop named
sudo systemctl start named

Then check the log file

sudo tail -f /var/log/named/bind.log

If successful, you should see the following lines in the log. Make sure it shows the latest serial.

zone herdiansah-lab.xyz/IN: loaded serial 2025082009

6. Once BIND is running, open another terminal and do some basic test using DNS tools like dig.

Check the A record for the webserver. Notice that by default, the query looks for the A record.

dig @127.0.0.1 www.herdiansah-lab.xyz






















Check the SOA record and note the serial is correct.

dig @localhost herdiansah-lab.xyz SOA

Check the mail servers for the domain. Here we use -t argument to specify the resource record type.

dig @127.0.0.1 herdiansah-lab.xyz -t MX

As in previous part, you should be able to run the dig command without specifying the resolver IP.

dig www.herdiansah-lab.xyz 


Step 2 - Configure the Secondary DNS Server

1. Open secondarydns. Add the same zone. The secondary DNS will also be authoritative for this zone.

First, create a folder in the working directory where the zone files will be dumped from the master.

cd /var/cache/bind
mkdir slave
sudo chown -R bind:bind slave

Then update the configuration file to add the zone statement for herdiansah-lab.xyz.

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

Make sure the type is slave. Also specify the IP address of the primary server.

zone "herdiansah-lab.xyz" {
       type slave;
       file "/var/cache/bind/slave/db.herdiansah-lab";
       masters {
              85.209.163.249;
    };
};

2. Restart BIND to reload the updated config.

sudo systemctl restart named

Also open another tab to check the logs.

sudo tail -f /var/log/named/bind.log

Confirm that the log shows Transfer status: success















3. Open primarydns and update the authoritative servers in the zonefile.

sudo vi /etc/bind/master/db.herdiansah-lab

Press i to insert text

Add the secondary DNS in the next line after the primary.

@       NS      ns2.herdiansah-lab.xyz.

The record should look as follows:

$TTL 300
@       SOA     NS.herdiansah-lab.xyz.  herdiansah54.gmail.com. (
                                 2025082209  ;serial no.
                                 3600        ;refresh
                                 1800        ;retry
                                 86400       ;expire
                                 10800       ;negative cache ttl
                                  );
@       NS      ns1.herdiansah-lab.xyz.
@       NS      ns2.herdiansah-lab.xyz.

Then add an A record for ns2.

ns2     A       109.105.194.68

Increment the serial to signify that the content of this zone file has been updated. The secondary DNS will compare this value with his local copy before pulling the new zone file.

To save and exit, press ESC key and type :wq

Check for any errors and fix.

named-checkzone herdiansah-lab.xyz db.herdiansah-lab






4. Restart BIND

sudo systemctl restart named
sudo systemctl status named

5. Check the logs on both primary and secondary if zone transfer starts and is successful. 

sudo tail -f /var/log/named/bind.log

 The output looks like this from primarydns:


















The output looks like this from secondarydns:














Notice that it should show the transfer has started and completed.

AXFR started (serial 2025082209)
AXFR ended

6. Fom the secondarydns, check that the zonefile has been copied.

ls -alh /var/cache/bind/slave/

There should be a file called db.dnslab in this folder. Named dumps the zone content in raw or binary format during zone transfer instead of text format.

7. Use dig to query for authoritative answers from either the primary or secondary DNS.

dig @85.209.163.249 www.herdiansah-lab.xyz

Apart from the answer, notice the flags in the dig response.

flags: qr aa rd ra


 The flags in a DNS response indicate the following: * QR - query or response * AA - authoritative answer * RD - recursion desired * RA - recursion available * TC - truncation * CD - checking disabled (for DNSSEC)


Since the response is directly from the authoritative server, the AA flag is set.

Also check the nameservers for this domain


dig herdiansah-lab.xyz -t NS

There should be two nameservers listed (pri and sec).

herdiansah-lab.xyz.     300     IN      NS      ns2.herdiansah-lab.xyz.
herdiansah-lab.xyz.     300     IN      NS      ns1.herdiansah-lab.xyz.

Their IP addresses are listed in the additional section.

ns1.herdiansah-lab.xyz. 300     IN      A       85.209.163.249
ns2.herdiansah-lab.xyz. 300     IN      A       109.105.194.68


























Part 3 - Reverse DNS

So far in Parts 1 & 2, you are working on Forward DNS. This part focuses on Reverse DNS, which is the mapping from IP addresses to domain names.

There are 1 steps in this part:
  • Step 1 - Reverse Zone for IPv4

Step 1 - Reverse Zone for IPv4

1. Create the domain for the IPv4 address assigned. We have two /24 blocks. The fully-qualified domain (FQDN) for these reverse zones are shown below:








2. Configure the server to add the reverse zone for the IP block 85.209.163.0/24.

From the primarydns, add:

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

At the end of the file, press o and insert the following in a new line.

zone "163.209.85.in-addr.arpa" {
       type master;
       file "/etc/bind/master/db.85.209.163";
};

To save and exit, press ESC key and type :wq

Check for any syntax error and fix.

named-checkconf /etc/bind/named.conf

From the secondarydns, add:

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

Press i to insert text

zone "163.209.85.in-addr.arpa" {
       type slave;
       file "/var/cache/bind/slave/db.85.209.163";
       masters {
              85.209.163.249;
    };
};

To save and exit, press ESC key and type :wq

3. Create the zonefile for db.192.168.1 in the primary DNS.

From the primarydns.

sudo vi /etc/bind/master/db.85.209.163

Then add the following content.

Press i to insert text

$TTL 300
@       SOA     NS.herdiansah-lab.xyz.  herdiansah54.gmail.com. (
                                  2025082209  ;serial no.
                                  3600        ;refresh
                                  1800        ;retry
                                  86400       ;expire
                                  10800       ;negative cache ttl
                                  );
@       NS      ns1.herdiansah-lab.xyz.
@       NS      ns2.herdiansah-lab.xyz.

249      PTR    ns1.herdiansah-lab.xyz.

If you created A records in Part 2, you must also add the corresponding PTR records here.

260     PTR     www.herdiansah-lab.xyz.
271     PTR     mail01.herdiansah-lab.xyz.
272     PTR     mail02.herdiansah-lab.xyz.


To save and exit, press ESC key and type :wq

Check for any errors and fix.

named-checkzone 163.209.85.in-addr.arpa db.85.209.163






4. Restart BIND on both servers.

From primarydns.

sudo systemctl restart bind9
sudo systemctl status bind9

From secondarydns.

sudo systemctl restart bind9
sudo systemctl status bind9

Like before, always check the logs for errors and make sure the zone has loaded.

sudo tail -f /var/log/named/bind.log

5. Check that zone transfer is successful.

Check the logs to see if transfer is successful.

sudo tail -f /var/log/named/bind.log
































From secondarydns, the zone file should be copied in this directory.

ls /var/cache/bind/slave

6. Test and execute some dig commands. The -x option is used for reverse lookup.

dig -x 85.209.163.249

The answer is a PTR record pointing to ns1.herdiansah-lab.xyz.





















You can also query using the FQDN of the IP address.

dig 249.163.209.85.in-addr.arpa -t PTR





















7. Now create a zone statement for IP address block 192.168.2.0/24. Let's switch roles and make the secondary server as primary for this zone.

From the secondarydns, add:

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

Press i to insert text

zone "194.105.109.in-addr.arpa" {
       type master;
       file "/etc/bind/master/db.109.105.194";
};

To save and exit, press ESC key and type :wq

From the primarydns, add:

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

Press i to insert text

zone "194.105.109.in-addr.arpa" {
       type slave;
       file "/var/cache/bind/slave/db.109.105.194";
       masters {
              109.105.194.68;
       };
       masterfile-format text;
};

To save and exit, press ESC key and type :wq

Check for any errors and fix.

named-checkconf /etc/bind/named.conf

8. Create the zonefile for db.109.105.194 in the secondary DNS.

From the secondarydns.

sudo vi /etc/bind/master/db.109.105.194

Then add the following content.

Press i to insert text

$TTL 300
@       SOA     NS.herdiansah-lab.xyz.  herdiansah54.gmail.com. (
                                  2025082011  ;serial no.
                                  3600             ;refresh
                                  1800             ;retry
                                  86400            ;expire
                                  10800            ;negative cache ttl
                                   );
@       NS      ns1.herdiansah-lab.xyz.
@       NS      ns2.herdiansah-lab.xyz.

68      PTR     ns2.herdiansah-lab.xyz.

To save and exit, press ESC key and type :wq

Check for errors and fix.

named-checkzone 194.105.109.in-addr.arpa db.109.105.194






9. Restart BIND on both servers.

From primarydns.

sudo systemctl restart bind9

From secondarydns.

sudo systemctl restart bind9

Like before, check that the zonefile loaded successfully and there are no errors.

sudo tail -f /var/log/named/bind.log

10. Check that zone transfers occured.

Check the logs to confirm that transfer is successful.

sudo tail -f /var/log/named/bind.log

From the primarydns, the file should be copied in this directory.

ls /var/cache/bind/slave

11. Test and execute some dig commands. The -x option is used for reverse lookup.

From either the primary or secondary DNS, execute the following dig command.

dig -x 109.105.194.68



















Comments