How to install a DNS server on Ubuntu 19.04

Posted on

A DNS server allows the translation of domain names to IP addresses and vice versa. Powering more than 79% of name servers on the Internet, BIND is the popular DNS software.

In this tutorial, we will see how to install and configure Bind on an Ubuntu 19.04 server. Here’s the environment used:

  • Ubuntu 19.04 running on VirtualBox
  • Domain: webhostinghero.lan
  • Master name server: ubuntu01.webhostinghero.lan (
  • Slaver name server: ubuntu02.webhostinghero.lan (
  • Web and mail server: ubuntu3.webhostinghero.lan (

Before you install a name server, always make sure that it has a static IP address.

How to Install BIND on Ubuntu 19.04

Use the apt command to install BIND9 and related packages:

sudo apt install bind9 bind9utils bind9-doc dnsutils -y

You can now enable the “bind” service when the server starts:

sudo systemctl enable bind9

If UFW (Uncomplicated Firewall) is active on your Ubuntu server, open the necessary ports:

sudo ufw allow bind9

The installation is complete. Let’s move to the configuration part.

Configuring a DNS Forwarder

A DNS server can serve exclusively as a relay between clients and other DNS servers. Moreover, this type of use is standard on private networks. A DNS forwarder is also used to cache DNS zones for faster response times.

To configure a DNS forwarder, edit the configuration file:

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

Set the options as shown below:

options {
        directory "/var/cache/bind";
        listen-on port 53 {;; };
        allow-query { localhost;; };
        allow-recursion { localhost;; };
        forwarders {; };
        recursion yes;
        dnssec-enable yes;
        dnssec-validation auto;

Start the bind service:

sudo systemctl restart bind9

Now let’s do some testing:

The DNS server has successfully resolved the requested domain name.

Warning: It is important to note that recursion on a DNS server is necessary for caching. However, this makes the server vulnerable to false queries that would overload it to the point of no longer responding. Therefore, if you enable recursion, it is essential to restrict access to the IP address range of the private network only.

If you only need a DNS caching server or relay, no need to read further, you’re all set.

Master DNS Server Configuration

The master server is the one on which you make all the zone file changes. These changes are then synchronized to the slave servers. The master name server is known as the “authoritative server.”

For this tutorial, we’ll set up a master and a slave server. On the master DNS server, edit the named.conf.options configuration file.

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

Configure the options as follow:

options {
        directory "/var/cache/bind";
        listen-on port 53 { any; };
        allow-query { any; };
        allow-transfer {; };
        recursion no;
        dnssec-enable yes;
        dnssec-validation auto;
        auth-nxdomain no;

Now let’s create the DNS zone for the “webhostinghero.lan” domain. Edit /etc/bin/named.conf.local and append the following lines:

zone    "webhostinghero.lan"    { 
        type master;
        notify yes;
        also-notify {; };
        file "/etc/bind/zones/webhostinghero.lan.db";

Save the file and exit the editor. Create the directory in which we’ll put the zone files:

sudo mkdir /etc/bind/zones

We can now create a new zone file:

sudo nano /etc/bind/zones/webhostinghero.lan.db

Insert the following lines to the zone file:

; Start of the DNS zone file
$ORIGIN webhostinghero.lan.
; Default cache expiration time for resource records
$TTL    86400
@       IN      SOA     ns1.webhostinghero.lan. ubuntu01.webhostinghero.lan. (
                2019042204      ; Serial number
                6h              ; Slave DNS refresh cycle
                1h              ; Slave DNS retry cycle
                1w              ; Slave DNS expiration time
                1d              ; Minimum caching time if resolution failed
; Domain IP Address
@                       IN      A     

; Name Servers
webhostinghero.lan.     IN      NS              ns1.webhostinghero.lan.
webhostinghero.lan.     IN      NS              ns2.webhostinghero.lan.

; IP Adresses for Name Servers
ns1                     IN      A     
ns2                     IN      A     

; Email server
webhostinghero.lan.     IN      MX      10      mail.webhostinghero.lan.
mail                    IN      A     

; Canonical names
www                     IN      CNAME           webhostinghero.lan.
ftp                     IN      CNAME           webhostinghero.lan.

Note that every time you change a DNS zone file, the serial number value must be incremented for the changes to be taken into account.

Restart the bind service:

sudo systemctl restart bind9

Test the new DNS zone:

If all is well configured, the server will respond to DNS queries for the domain webhostinghero.lan.

Validating Configuration and DNS Zone Files

If you encounter some problems after modifying the configuration files and restarting the service, type the following command to get the status:

sudo systemctl status bind9

With a bit of luck, you might find some information that will help you solve the issue. Unfortunately, this command doesn’t provide a lot of details. Type this command to validate the configuration files:

sudo named-checkconf

If you don’t pass any parameter to the command, the default configuration will be verified. If the command returns nothing, the configuration files are valid.

To validate the DNS zones, use the named-checkzone command as follows:

sudo named-checkzone webhostinghero.lan /etc/bind/zones/webhostinghero.lan.db

Correct the errors if there are any and restart the “bind9” service.

Slave DNS Server Configuration

A primary DNS server can work alone; it is not necessary to have a secondary server. However, if you are hosting a public DNS zone, you must have at least two DNS servers.

On the secondary DNS server, edit the /etc/bind/named.conf.options file and replace its content with this one:

options { 
        directory "/var/cache/bind";
        listen-on port 53 {;;; };
        allow-query { any; };
        allow-new-zones yes;
        recursion no;
        allow-transfer { none; };
        dnssec-enable yes;
        dnssec-validation auto;
        auth-nxdomain no;
        allow-notify {; };

Still, on the secondary DNS server, open the /etc/bind/named.conf.local configuration file to add the zone webhostinghero.lan:

zone "webhostinghero.lan" { 
       type slave; 
       masters {; }; 
       file "/etc/bind/slaves/webhostinghero.lan.db"; 

Create a directory to contain the slave zone files:

sudo mkdir /etc/bind/slaves
sudo chmod 0775 /etc/bind/slaves

If apparmor enabled on your Ubuntu server, you must allow writing permissions on the folder:

sudo nano /etc/apparmor.d/usr.sbin.named

Add the following line:

/etc/bind/** r, 
/etc/bind/slaves/** rw,
/var/lib/bind/** rw, 
/var/lib/bind/ rw, 
/var/cache/bind/** lrw, 
/var/cache/bind/ rw,

Restart apparmor and bind9:

sudo systemctl restart apparmor
sudo systemctl restart bind9

Check the contents of the /etc/bind/slaves folder. If the zone transfer is successful between the primary and the secondary server, the DNS zone file webhostinghero.lan.db will be there.

Use the dig command to test the secondary DNS server:

If all is going well, the secondary DNS server can now respond to queries for the webhostinghero.lan domain.

Ubuntu DNS Server Log Files

By default, bind events will be logged in /var/log/syslog. For bind to have its log file, create the directory as follows:

sudo mkdir /var/log/named
sudo chown root.bind /var/log/named
sudo chmod 0775 /var/log/named/

Insert the following lines into /etc/bind/named.conf.local:

logging { 
       channel dnslog { 
               file "/var/log/named/named.log"; 
               severity dynamic; 
               print-time yes; 
               print-category yes; 
               print-severity yes; 

       category queries { dnslog; }; 
       category default { dnslog; }; 

If you need a higher level of logging, use:

severity debug;

Restart bind. You can now display the log file in real time by using this command:

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

Troubleshooting Ubuntu DNS Servers

If you’re having trouble synchronizing DNS servers, here are some things you can try.

Start by checking the connection to port 53 from the primary server to the secondary server, and vice versa using the nc command:

nc -zv 53

If the connection fails, there is probably a firewall problem.

If the connection is successful, but synchronization still does not work, test the zone transfer manually. From the secondary DNS server, type the command:

dig axfr @ webhostinghero.lan

If the request fails, then there is a configuration problem on the primary DNS server side.

Leave a Reply

Your email address will not be published. Required fields are marked *