Installing the DNS server on Ubuntu

DNS, also known as name server, is a service on the Internet that provides mapping between IP addresses and domain names and vice versa. DNS maintains a database of names and related IP addresses. When an application queries with a domain name, DNS responds with a mapped IP address. Applications can also ask for a domain name by providing an IP address.

DNS is quite a big topic, and an entire chapter can be written just on the DNS setup. This recipe assumes some basic understanding of the working of the DNS protocol. We will cover the installation of BIND, installation of DNS server application, configuration of BIND as a caching DNS, and setup of Primary Master and Secondary Master. We will also cover some best practices to secure your DNS server.

Prerequisites

In this article, I will be using four servers. You can create virtual machines if you want to simply test the setup:

ns1: Name server one/Primary Master

ns2: Name server two/Secondary Master

host1: Host system one

host2: Host system two, optional

All servers should be configured in a private network. I have used the 10.0.2.0/24 network

We need root privileges on all servers.

Install BIND and set up a caching name server through the following steps:

  • On ns1, install BIND and dnsutils with the following command:
$ sudo apt-get update 
$ sudo apt-get install bind9 dnsutils
  • Open /etc/bind/named.conf.optoins, enable the forwarders section, and add your preferred DNS servers:
forwarders { 	8.8.8.8; 	8.8.4.4; };
  • Now restart BIND to apply a new configuration:
$ sudo service bind9 restart
  • Check whether the BIND server is up and running:
$ dig -x 127.0.0.1
  • You should get an output similar to the following code:
;; Query time: 1 msec 
;; SERVER: 10.0.2.53#53(10.0.2.53)
  • Use dig to external domain and check the query time:
;; Query time: 91 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Sun May 16 11:25:20 IST 2021
;; MSG SIZE  rcvd: 52
  • Dig the same domain again and cross check the query time. It should be less than the first query:
;; Query time: 27 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Sun May 16 11:25:18 IST 2021
;; MSG SIZE  rcvd: 52

Set up Primary Master through the following steps:

  • On the ns1 server, edit /etc/bind/named.conf.options and add the acl block above the options block:
acl "local" { 
	10.0.2.0/24; # local network 
};
  • Add the following lines under the options block:
recursion yes; 
allow-recursion { local; }; 
listen-on { 10.0.2.53; }; # ns1 IP address 
allow-transfer { none; };
  • Open the /etc/bind/named.conf.local file to add forward and reverse zones:
$ sudo nano /etc/bind/named.conf.local
  • Add the forward zone:
zone "example.com" { 
	type master; 
	file "/etc/bind/zones/db.example.com"; 
};
  • Add the reverse zone:
zone "2.0.10.in-addr.arpa" { 
	type master; 
	file "/etc/bind/zones/db.10"; 
};
  • Create the zones directory under /etc/bind/:
$ sudo mkdir /etc/bind/zones
  • Create the forward zone file using the existing zone file, db.local, as a template:
$ cd /etc/bind/ $ sudo cp db.local zones/db.example.com
  • The default file should look similar to the following image:
db local bind
  • Edit the SOA entry and replace localhost with FQDN of your server.
  • Increment the serial number (you can use the current date time as the serial number, 201507071100)
  • Remove entries for localhost127.0.0.1 and ::1.
  • Add new records:
; name server - NS records 
@ IN NS ns.exmple.com 
; name server A records 
ns IN A 10.0.2.53 
; local - A records 
host1 IN A 10.0.2.58
  • Save the changes and exit the nano editor. The final file should look similar to the following image:
bind zone
  • Now create the reverse zone file using /etc/bind/db.127 as a template:
$ sudo cp db.127 zones/db.10
  • The default file should look similar to the following screenshot:
Bind db
  • Change the SOA record and increment the serial number.
  • Remove NS and PTR records for localhost.
  • Add NSPTR, and host records:
; NS records 
@ IN NS ns.example.com 
; PTR records 
53 IN PTR ns.example.com 
; host records 
58 IN PTR host1.example.com
  • Save the changes. The final file should look similar to the following image:
bind zone db
  • Check the configuration files for syntax errors. It should end with no output:
$ sudo named-checkconf
  • Check zone files for syntax errors:
$ sudo named-checkzone example.com /etc/bind/zones/db.example.com
  • If there are no errors, you should see an output similar to the following:
zone example.com/IN: loaded serial 3 OK
  • Check the reverse zone file, zones/db.10:
$ sudo named-checkzone example.com /etc/bind/zones/db.10
  • If there are no errors, you should see output similar to the following:
zone example.com/IN: loaded serial 3 OK
  • Now restart the DNS server bind:
$ sudo service bind9 restart
  • Log in to host2 and configure it to use ns.example.com as a DNS server. Add ns.example.com to /etc/resolve.conf on host2.
  • Test forward lookup with the nslookup command:
$ nslookup host1.example.com 
  • You should see an output similar to following:
$ nslookup host1.example.com 
Server: 10.0.2.53 
Address: 10.0.2.53#53 
Name: host1.example.com 
Address: 10.0.2.58
  • Now test the reverse lookup:
$ nslookup 10.0.2.58
  • It should output something similar to the following:
$ nslookup 10.0.2.58 
Server: 10.0.2.53 
Address: 10.0.2.53#53 
58.2.0.10.in-addr.arpa name = host1.example.com

Set up Secondary Master through the following steps:

  • First, allow zone transfer on Primary Master by setting the allow-transfer option in /etc/bind/named.conf.local:
zone "example.com" { 
	type master; 
	file "/etc/bind/zones/db.example.com"; 
	allow-transfer { 10.0.2.54; }; 
}; 
zone "2.0.10.in-addr.arpa" { 
	type master; 
	file "/etc/bind/zones/db.10"; 
	allow-transfer { 10.0.2.54; }; 
};
  • Restart BIND9 on Primary Master:
$ sudo service bind9 restart
  • On Secondary Master (ns2), install the BIND package.
  • Edit /etc/bind/named.conf.local to add zone declarations as follows:
zone "example.com" { 
	type slave; 
	file "db.example.com"; 
	masters { 10.0.2.53; }; 
}; 
zone "2.0.10.in-addr.arpa" { 
	type slave; 
	file "db.10"; 
	masters { 10.0.2.53; }; 
};
  • Save the changes made to named.conf.local.
  • Restart the BIND server on Secondary Master:
$ sudo service bind9 restart
  • This will initiate the transfer of all zones configured on Primary Master. You can check the logs on Secondary Master at /var/log/syslog to verify the zone transfer.

How DNS Server works

In the first section, we have installed the BIND server and enabled a simple caching DNS server. A caching server helps to reduce bandwidth and latency in name resolution. The server will try to resolve queries locally from the cache. If the entry is not available in the cache, the query will be forwarded to external DNS servers and the result will be cached.

In the second and third sections, we have set Primary Master and Secondary Master respectively. Primary Master is the first DNS server. Secondary Master will be used as an alternate server in case the Primary server becomes unavailable.

Under Primary Master, we have declared a forward zone and reverse zone for the example.com domain. The forward zone is declared with domain name as the identifier and contains the type and filename for the database file. On Primary Master, we have set type to master. The reverse zone is declared with similar attributes and uses part of an IP address as an identifier. As we are using a 24-bit network address (10.0.2.0/24), we have included the first three octets of the IP address in reverse order (2.0.10) for the reverse zone name.

Lastly, we have created zone files by using existing files as templates. Zone files are the actual database that contains records of the IP address mapped to FQDN and vice versa. It contains SOA record, A records, and NS records. An SOA record defines the domain for this zone; A records and AAAA records are used to map the hostname to the IP address.

When the DNS server receives a query for the example.com domain, it checks for zone files for that domain. After finding the zone file, the host part from the query will be used to find the actual IP address to be returned as a result for query. Similarly, when a query with an IP address is received, the DNS server will look for a reverse zone file matching with the queried IP address.

0 Comments

Submit a Comment

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

Related Articles