Domain Name System (in short, DNS) is an internet service that is used to resolve Domain Name to IP Address and vice versa.

BIND (Berkeley Internet Name Domain) provides the functionality of name to ip conversion.

This post will help you configure DNS server on Debian 9 / Ubuntu 16.04.

Environment

Domain: itzgeek.local

Primary DNS server:  (It is the master server, and DNS records are created here.)

Server Name: ns1.itzgeek.local

IP Address: 192.168.1.10

Secondary DNS server: (It is the slave server, gets DNS records from the Master server. It acts as a backup DNS server for the primary server if the primary server goes down.)

Server Name: ns2.itzgeek.local

IP Address: 192.168.1.20

In this post, we set up only the primary DNS server. In case if you are planning to implement secondary server then take a look at configuring slave DNS server on Debian 9 / Ubuntu 16.04.

Prerequisites

Switch to the root user.

su -

OR

sudo su -

Update the repository index.

apt-get update

Make sure both primary and secondary server has a static IP address.

READ: How to configure static ip address in Debian / Ubuntu / LinuxMint

Install DNS Server

The package name of DNS in Debian / Ubuntu is bind9 and is available in the base repository. You can use apt command to install bind9 package.

apt-get install -y bind9 bind9utils bind9-doc dnsutils

Configure DNS Server

/etc/bind/ is the configuration directory of bind9, holds configuration files and zone lookup files. Global configuration file is /etc/bind/named.conf.

Create Zone’s

Let us begin with creating forward zone for your domain.

You should not use the global configuration file for local DNS zone rather you can use /etc/bind/named.conf.local file.

nano /etc/bind/named.conf.local

Forward Zone:

The following is the forward zone entry for the itzgeek.local domain in the named.conf.local file.

zone "itzgeek.local" IN { //Domain name
     type master; //Primary DNS
     file "/etc/bind/fwd.itzgeek.local.db"; //Forward lookup file
     allow-update { none; }; // Since this is the primary DNS, it should be none.
};

Reverse Zone:

The following is for the reverse zone in the named.conf.local file.

zone "1.168.192.in-addr.arpa" IN { //Reverse lookup name, should match your network in reverse order
     type master; // Primary DNS
     file "/etc/bind/rev.itzgeek.local.db"; //Reverse lookup file
     allow-update { none; }; //Since this is the primary DNS, it should be none.
};

Create Zone lookup file

Once zones are created, you can go ahead and create zone data files for the forward zone and reverse zone.

Forward Zone lookup file:

Copy the sample entries to zone file called fwd.itzgeek.local.db for forward zone under /etc/bind directory.

Record types in zone file,

SOA – Start of Authority
NS – Name Server
A – A record
MX – Mail for Exchange
CN – Canonical Name

Domain names should end with a dot (.).

cp /etc/bind/db.local /etc/bind/fwd.itzgeek.local.db

Edit the zone.

nano /etc/bind/fwd.itzgeek.local.db

Update the content shown like below. Whenever you change any records in the lookup file, make sure you update the serial number to some random number, higher than current.

;
; BIND data file for local loopback interface
;
$TTL    604800
@       IN      SOA     ns1.itzgeek.local. root.itzgeek.local. (
                             20         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
;@      IN      NS      localhost.
;@      IN      A       127.0.0.1
;@      IN      AAAA    ::1

;Name Server Information
       IN      NS      ns1.itzgeek.local.
       IN      NS      ns2.itzgeek.local.
;IP address of Name Server
ns1     IN      A       192.168.1.10
ns2     IN      A       192.168.1.20

;Mail Exchanger
itzgeek.local.   IN     MX   10   mail.itzgeek.local.

;A - Record HostName To Ip Address
www     IN       A      192.168.1.100
mail    IN       A      192.168.1.150
@       IN       A      192.168.1.200
;CNAME record
ftp     IN      CNAME   www.itgeek.local.

Reverse Zone lookup file:

Copy the sample entries to zone file called rev.itzgeek.local.db for reverse zone under /etc/bind directory and create reverse pointers for the above forward zone records.

PTR – Pointer
SOA – Start of Authority

cp /etc/bind/db.127 /etc/bind/rev.itzgeek.local.db

Edit the reverse zone file.

nano /etc/bind/rev.itzgeek.local.db

Update the content shown like below. Whenever you change any records in the lookup file, make sure you update the serial number to some random number, higher than current.

;
; BIND reverse data file for local loopback interface
;
$TTL    604800
@       IN      SOA     itzgeek.local. root.itzgeek.local. (
                             20         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
;@      IN      NS      localhost.
;1.0.0  IN      PTR     localhost.

;Name Server Information
       IN      NS     ns1.itzgeek.local.
       IN      NS     ns2.itzgeek.local.
;Reverse lookup for Name Server
10      IN      PTR    ns1.itzgeek.local.
20      IN      PTR    ns2.itzgeek.local.
;PTR Record IP address to HostName
100     IN      PTR    www.itzgeek.local.
150     IN      PTR    mail.itzgeek.local.
200     IN      PTR    itzgeek.local.

Check BIND Configuration Syntax

Use named-checkconf command to check the syntax of named.conf* files for any errors.

named-checkconf

Command will return to the shell if there are no errors.

Also, you can use named-checkzone to check the syntax errors in zone files.

For foward zone:

named-checkzone itzgeek.local /etc/bind/fwd.itzgeek.local.db

Output:

zone itzgeek.local/IN: loaded serial 20
OK

For reverse zone:

named-checkzone 1.168.192.in-addr.arpa /etc/bind/rev.itzgeek.local.db

Output:

zone 1.168.192.in-addr.arpa/IN: loaded serial 20
OK

Restart bind service.

systemctl restart bind9

Enable it on system startup.

systemctl enable bind9

Check the status of bind9 service.

systemctl status bind9

Output:

 bind9.service - BIND Domain Name Server
   Loaded: loaded (/lib/systemd/system/bind9.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2017-10-09 13:31:54 EDT; 1min 51s ago
     Docs: man:named(8)
 Main PID: 778 (named)
    Tasks: 4 (limit: 4915)
   CGroup: /system.slice/bind9.service
           └─778 /usr/sbin/named -f -u bind

Oct 09 13:31:55 ns1.itzgeek.local named[778]: managed-keys-zone: loaded serial 4
Oct 09 13:31:55 ns1.itzgeek.local named[778]: zone 0.in-addr.arpa/IN: loaded serial 1
Oct 09 13:31:55 ns1.itzgeek.local named[778]: zone 127.in-addr.arpa/IN: loaded serial 1
Oct 09 13:31:55 ns1.itzgeek.local named[778]: zone localhost/IN: loaded serial 2
Oct 09 13:31:55 ns1.itzgeek.local named[778]: zone 1.168.192.in-addr.arpa/IN: loaded serial 20
Oct 09 13:31:55 ns1.itzgeek.local named[778]: zone itzgeek.local/IN: loaded serial 20
Oct 09 13:31:55 ns1.itzgeek.local named[778]: zone 255.in-addr.arpa/IN: loaded serial 1
Oct 09 13:31:55 ns1.itzgeek.local named[778]: all zones loaded
Oct 09 13:31:55 ns1.itzgeek.local named[778]: running
Oct 09 13:31:55 ns1.itzgeek.local named[778]: zone 1.168.192.in-addr.arpa/IN: sending notifies (serial 20)

Verify DNS

Go to any client machine and add our new DNS server IP Address in /etc/resolv.conf file.

nano /etc/resolv.conf

Make an entry like below.

nameserver 192.168.1.10

OR

Follow the below tutorial to add DNS server IP in Ubuntu / Debian.

READ: How to add DNS IP address in Debian / Ubuntu / LinuxMint

You can either use nslookup or dig command to verify the DNS server.

Use the dig command to verify the forward lookup.

dig www.itzgeek.local

If you get command not found, install bind-utils package.

Output:

; <<>> DiG 9.10.3-P4-Debian <<>> www.itzgeek.local @192.168.1.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13117
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.itzgeek.local.             IN      A

;; ANSWER SECTION:
www.itzgeek.local.      604800  IN      A       192.168.1.100

;; AUTHORITY SECTION:
itzgeek.local.          604800  IN      NS      ns1.itzgeek.local.

;; ADDITIONAL SECTION:
ns1.itzgeek.local.      604800  IN      A       192.168.1.10

;; Query time: 0 msec
;; SERVER: 192.168.1.10#53(192.168.1.10)
;; WHEN: Mon Oct 09 13:14:22 EDT 2017
;; MSG SIZE  rcvd: 96

The DNS server’s answer for forward lookup: 192.168.1.100 as IP address for www.itzgeek.local.

Confirm the reverse lookup with dig command.

dig -x 192.168.1.100

Output:

; <<>> DiG 9.10.3-P4-Debian <<>> -x 192.168.1.100 @192.168.1.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39795
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;100.1.168.192.in-addr.arpa.    IN      PTR

;; ANSWER SECTION:
100.1.168.192.in-addr.arpa. 604800 IN   PTR     www.itzgeek.local.

;; AUTHORITY SECTION:
1.168.192.in-addr.arpa. 604800  IN      NS      ns1.itzgeek.local.

;; ADDITIONAL SECTION:
ns1.itzgeek.local.      604800  IN      A       192.168.1.10

;; Query time: 0 msec
;; SERVER: 192.168.1.10#53(192.168.1.10)
;; WHEN: Mon Oct 09 13:15:32 EDT 2017
;; MSG SIZE  rcvd: 120

The DNS server’s answer for reverse lookup: www.itzgeek.local as a name for 192.168.1.100.

This result confirms that both forward and reverse zone lookups are working fine.

That’s All. You have successfully installed BIND on Debian 9 / Ubuntu 16.04 as a master server. In our next article, we will configure Slave DNS server on Debian 9 / Ubuntu 16.04.