Home   >   Set Up Authoritative DNS Server on Ubuntu 18.04, 16.04 with BIND9

This tutorial will be showing you how to set up and run your own authoritative name server on Ubuntu 18.04/16.04 with the widely-used BIND 9 software.

What’s An Authoritative DNS Server?

If you own a domain name and want your own DNS server to handle name resolution for your domain name instead of using your domain registrar’s DNS server, then you will need to set up an authoritative DNS server.

An authoritative DNS server is used by domain name owners to store DNS records. It provides authoritative answers to DNS resolvers (like or, which query DNS records on behalf of end users on PC, smartphone or tablet.

About BIND

BIND (Berkeley Internet Name Domain) is an open-source, flexible and full-featured DNS software widely used on Unix/Linux due to it’s stability and high quality. It’s originally developed by UC Berkeley, and later in 1994 its development was moved to Internet Systems Consortium, Inc (ISC).

BIND can act as an authoritative DNS server for a zone and a DNS resolver at the same time. A DNS resolver can also be called a recursive name server because it performs recursive lookups for local clients. However, taking two roles at the same time isn’t advantageous. It’s a good practice to separate the two roles on two different machines


To follow this tutorial, you should have already bought a domain name. I registered my domain name at NameCheap because the price is low and they give whois privacy protection free for life.

You also need two servers. One server is for the master DNS server and the other is for the slave DNS server. Ideally the two servers should be at different physical locations. If one DNS server is offline, the other DNS server can still response to DNS queries for your domain name.

Each server needs only 512MB RAM and here are the hosting providers that I recommend. I have used all of them.

Setting the Hostname on the Name Servers

Before we get into the configuration of our name servers, we must ensure that our hostname is configured properly on both our primary and secondary DNS server.

Begin by investigating the /etc/hosts file. Open the file with sudo privileges in your text editor:

 sudo nano /etc/hosts 

We need to configure this so that it correctly identifies each server’s hostname and FQDN. For the primary name server, the file will look something like this initially:       localhost . . .  

We should modify the second line to reference our specific host and domain combination and point this to our public, static IP address. We can then add the unqualified name as an alias at the end. For the primary server in this example, you would change the second line to this:       localhost       ns1.example.com ns1 . . .  

Save and close the file when you are finished.

Install Bind on Both Name Servers

On each of your name servers, you can now install Bind, the DNS server that we will be using.

The Bind software is available within Ubuntu’s default repositories, so we just need to update our local package index and install the software using apt. We will also include the documentation and some common utilities:

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

Run this installation command on your primary and secondary DNS servers to acquire the appropriate files.

By default, BIND automatically starts after installation.You check its status with:

systemctl status bind9

If it’s not running, then start it with:

sudo systemctl start bind9

And enable auto start at boot time:

sudo systemctl enable bind9

Configure the Primary Bind Server

Now that we have the software installed, we can begin by configuring our DNS server on the primary server.

The main BIND configuration file /etc/bind/named.conf sources the settings from 3 other files.

  • /etc/bind/named.conf.options
  • /etc/bind/named.conf.local
  • /etc/bind/named.conf.default-zones

Out of the box, the BIND9 server on Ubuntu provides recursive service for localhost and local network clients. Since we are setting up an authoritative DNS server, we need to disable recursion. Edit the /etc/bind/named.conf.options file.

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

Add the following lines to this file’s options section.

 // hide version number from clients for security reasons.  version "not currently available";   // disable recursion on authoritative DNS server.  recursion no;   // enable the query log  querylog yes;   // disallow zone transfer  allow-transfer { none; }; 

Technically speaking, you only need to add recursion no; to disable recursion, but it’s a good practice to add the other 3 directives. Save and close the file. Then restart BIND.

sudo systemctl restart bind9

Master DNS Server Configuration

Pick one of the two servers as the master DNS server. We will name it ns1.example.com.

The master DNS server holds the master copy of the zone file. Changes of DNS records are made on this server. A domain can have one or more DNS zones. Each DNS zone has a zone file which contains every DNS record in that zone. For simplicity’s sake, this article assumes that you want to use a single DNS zone to manage all DNS records for your domain name.

The /etc/bind/named.conf.default-zones file defines the root zone and localhost zone. To add a zone for your domain name, edit /etc/bind/named.conf.local file.

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

Add the following lines to this file. Replace example.com with your own domain name. Replace with the IP address of slave DNS server.

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

In the above configuration, we created a new zone with the zone clause and we specified that this is the master zone. The zone file is /etc/bind/db.example.com, where we will add DNS records. Zone transfer will be only allowed for the slave DNS server.

Now let’s create the zone file.

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

You can add something like below.

 ; zone file for example.com ; hostmaster.bytebunch.com in SoA record is the email address of host. $TTL    86400		; default TTL for this zone (1 day) $ORIGIN		example.com.		;base domain name  ;start of Authority record defining they key characteristics of this zone @       IN      SOA     ns1.bytebunch.com. hostmaster.bytebunch.com. (                               2         ; Serial Number increase it when this file is changed.                          604800         ; Refresh                           86400         ; Retry                         2419200         ; Expire                           86400 )       ; Negative Cache TTL ;Name servers for this domain @       IN      NS      ns1.bytebunch.com. @       IN      NS      ns2.bytebunch.com.  ; A Records @	600		IN		A  ; CNAME Records ftp	3600	 IN		CNAME	@ www	3600	 IN		CNAME	@ 

Save and close the file. Then run the following command to check if there are syntax errors in the main configuration file. A silent output indicates no errors are found.

sudo named-checkconf

Then check the syntax of zone files.

sudo named-checkzone example.com /etc/bind/db.example.com

If no errors are found, then restart BIND9.

sudo systemctl restart bind9

If you are using the uncomplicated firewall (UFW), then open TCP and UDP port 53.

sudo ufw allow 53/tcp  sudo ufw allow 53/udp

If you are using iptables firewall directly, then run the following command.

sudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT  sudo iptables -A INPUT -p udp --dprot 53 -j ACCEPT

Slave DNS Server Configuration

Now we use the other server as the slave DNS server, which will be named ns2.example.com.

First, edit the named.conf.local file.

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

Add a zone like below. Replace with the IP address of the master DNS server.

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

In the above configuration, we specified that this is a slave DNS server for the example.com zone and it will accept zone transfers only from a trusted IP address.

Save and close the file. Then run the following command to check if there are syntax errors in the main configuration file.

sudo named-checkconf

If no errors are found, restart BIND9.

sudo systemctl restart bind9

The zone file on slave DNS server are loaded from a zone transfer, which is used to synchronize DNS record changes from master DNS server to slave DNS server. After BIND9 restarts, zone tranfer will start immediately. Check the BIND9 log with the following command.

sudo journalctl -eu bind9

You can see messages like below, which indicates the zone transfer is successful.

named[31518]: transfer of 'example.com/IN' from Transfer completed: 1 messages, 16 records, 886 bytes, 0.004 secs (221500 bytes/sec)

The zone file will be save as /var/cache/bind/db.example.com.

If you are using the uncomplicated firewall (UFW), then open TCP and UDP port 53.

sudo ufw allow 53/tcp  sudo ufw allow 53/udp

If you are using iptables firewall directly, then run the following command.

sudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT  sudo iptables -A INPUT -p udp --dprot 53 -j ACCEPT

More about Zone Transfer

The slave DNS server will contact the master again when the refresh time in SOA record is reached and if the serial number on the master is greater than that on the slave, a zone transfer will be initiated. There are two types of zone transfers:

  • Full zone transfer (AXFR): The full copy of zone file is transferred.
  • Incremental zone transfer (IXFR): Only DNS records that are changed are transferred.

Both types of zone transfer use TCP port 53. By default, BIND on the slave DNS server will request an incremental zone transfer and BIND on the master DNS server will only allow incremental zone transfer when the zone is dynamic.

The zone transfer interval is a major factor of the propagation speed of DNS record changes. Instead of waiting for the slave DNS server to make contact, the BIND master will notify the slave when changes are made to the zone. This can considerably reduce the time to propagate zone changes to the Internet.

Reverse Zone

A reverse zone contains PTR record that map an IP address to a DNS name. It is the counterpart of DNS A record. PTR record often is necessary for mail servers to pass spam filters. This record does not belong to a domain. You need to create PTR record at your hosting provider’s control panel, or ask your ISP, so I’m not going to cover creating reverse zones in BIND.

Change NS Record and Create Glue Record

Now you need to go to your domain registrar’s website to change the NS record for your domain, so the Internet would know that you are now using your own DNS server. Normally you use hostnames in the NS record like ns1.example.com and ns2.example.com.

name server 1:     ns1.example.com name server 2:     ns2.example.com

If you have a domain name example.com and you use a subdomain for the authoritative DNS servers (ns1.example.com and ns2.example.com), then you also need to create a glue record at your domain registrar, so the Internet can know the IP address of your DNS server. The glue record is an A record for ns1.example.com and ns2.example.com.

ns1.example.com        IP-address-of-master-server ns2.example.com        IP-address-of-slave-server

The above information will be sent to a registry operator who runs TLD DNS servers via the Extensible Provisioning Protocol (EPP), so that TLD DNS servers know the hostnames and IP addresses of the authoritative DNS servers for your domain name.

After the NS record and glue record have been propagated to the Internet, you DNS servers would be responding to DNS queries for your domain name. You can check the query log with:

sudo journalctl -eu bind9

Things to Know

  • The term master DNS server only implies that this server stores the master copy of the zone file. It has no higher priority when it comes to DNS resolution.
  • Always update the SOA serial number when you make changes to a zone file.

Tags: , , ,

Categorised in: Linux, Ubuntu