Setup Master-Slave DNS Server using BIND on CentOS 7

|
Last Updated:
|
|

Welcome gurus to this very tutorial on how to setup Master-Slave DNS Server using BIND on CentOS 7. BIND, Berkeley Internet Name Domain, can be configured to function as both Master and Slave DNS server. There are different open-source packages that can be used to configure DNS nameservers. Some of these packages include BIND, dnsmasq, and unbound. In this tutorial, we are going to use BIND package to configure our local DNS server. BIND is an open-source software that is used to implement DNS protocols that defines how networked devices can locate one another based on their hostnames.

Setting up Master-Slave DNS Server using BIND on CentOS

Deployment Architecture

In this tutorial, we will be using three CentOS 7 servers configured as follows:

ServerHostnameIP AddressRole
Server1ns1.kifarunix-demo.com192.168.122.10Master DNS Server
Server2ns2.kifarunix-demo.com192.168.122.11Slave DNS Server
Server3fileserver.kifarunix-demo.com192.168.122.20Client Server

Configure Master DNS Server using BIND on CentOS

Install Required Bind Packages

In all the servers, we have to install BIND packages before we proceed with configurations;

yum install -y bind bind-utils

Once the package is installed, let us get to work.

Create DNS Access Control List (ACL)

We would want to allow specific hosts to access the DNS server. Therefore, we will create an Access Control List called allowed containing IP addresses of the hosts to be allowed to query our DNS servers before the options sections in the configuration file, /etc/named.conf;

Before you can proceed, this is the default /etc/named.conf configurations;

cat /etc/named.conf

//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//
// See the BIND Administrator's Reference Manual (ARM) for details about the
// configuration located in /usr/share/doc/bind-{version}/Bv9ARM.html

options {
	listen-on port 53 { 127.0.0.1; };
	listen-on-v6 port 53 { ::1; };
	directory 	"/var/named";
	dump-file 	"/var/named/data/cache_dump.db";
	statistics-file "/var/named/data/named_stats.txt";
	memstatistics-file "/var/named/data/named_mem_stats.txt";
	recursing-file  "/var/named/data/named.recursing";
	secroots-file   "/var/named/data/named.secroots";
	allow-query     { localhost; };

	/* 
	 - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
	 - If you are building a RECURSIVE (caching) DNS server, you need to enable 
	   recursion. 
	 - If your recursive DNS server has a public IP address, you MUST enable access 
	   control to limit queries to your legitimate users. Failing to do so will
	   cause your server to become part of large scale DNS amplification 
	   attacks. Implementing BCP38 within your network would greatly
	   reduce such attack surface 
	*/
	recursion yes;

	dnssec-enable yes;
	dnssec-validation yes;

	/* Path to ISC DLV key */
	bindkeys-file "/etc/named.root.key";

	managed-keys-directory "/var/named/dynamic";

	pid-file "/run/named/named.pid";
	session-keyfile "/run/named/session.key";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "." IN {
	type hint;
	file "named.ca";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

Thus, let’s begin by creating an ACL;

vim /etc/named.conf

//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//
// See the BIND Administrator's Reference Manual (ARM) for details about the
// configuration located in /usr/share/doc/bind-{version}/Bv9ARM.html

# Create an access control list called allowed 
acl "allowed" {
        192.168.122.10;
        192.168.122.11;
        192.168.122.20;
};
options {
        listen-on port 53 ...

In the above, we have only limited access to DNS queries to three hosts.

Apart from defining the allowed system IP addresses, there are default BIND ACLs that you can use if it suit your needs;

  • none: Matches no hosts.
  • any: Matches all hosts.
  • localhost: Matches the loopback addresses 127.0.0.1 and ::1, as well as the IP addresses of all interfaces on the server that runs BIND.
  • localnets: Matches the loopback addresses 127.0.0.1 and ::1, as well as all subnets the server that runs BIND is directly connected to.

Define DNS Server Global Options

The “options” section in the BIND configuration file (named.conf) specifies global options for the DNS server.



# Create an access control list called allowed 
acl "allowed" {
        192.168.122.10;
        192.168.122.11;
        192.168.122.20;
};
options {
        listen-on port 53 { 127.0.0.1; 192.168.122.10; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
        allow-query     { localhost; allowed; };
        allow-transfer  { 192.168.122.11; };
        recursion yes;
        dnssec-enable yes;
        dnssec-validation yes;
        bindkeys-file "/etc/named.root.key";
        managed-keys-directory "/var/named/dynamic";
        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";
};

These options are explained below;

  • listen-on: Specifies the IP address(es) and port number(s) that the DNS server should listen on for incoming requests. The default port for DNS is 53.
  • directory: Specifies the directory where the DNS server should store its zone files, key files, and other data.
  • dump-file: Specifies the file where the DNS server should dump its cache database when it shuts down.
  • statistics-file: Specifies the file where the DNS server should log statistics about its performance and activity.
  • memstatistics-file: Specifies the file where the DNS server should log detailed memory usage statistics.
  • recursing-file: Specifies the file where the DNS server should log queries that it has forwarded to other DNS servers when performing recursive lookups.
  • secroots-file: Specifies the file where the DNS server should store trusted DNSSEC root keys.
  • allow-query: Specifies which hosts are allowed to query the DNS server. By default, the DNS server will only allow queries from localhost.
  • allow-transfer: Specifies which hosts are allowed to transfer zone data from the DNS server. By default, zone transfers are not allowed.
  • recursion: Enables or disables recursion. Recursion is the process by which a DNS server queries other DNS servers to resolve a DNS query.
  • dnssec-enable: Enables or disables DNSSEC validation. DNSSEC is a security protocol that is used to verify the authenticity of DNS data.
  • dnssec-validation: Enables or disables DNSSEC validation.
  • bindkeys-file: Specifies the file where the DNS server should look for the DNSSEC root key.
  • managed-keys-directory: Specifies the directory where the DNS server should store managed keys.
  • pid-file: Specifies the file where the DNS server should write its process ID.
  • session-keyfile: Specifies the file where the DNS server should store session keys.

Create Forward and Reverse Zone Statements

Create zone statements for both forward and reverse DNS lookups.


# Zone statement for forward DNS lookup
zone "kifarunix-demo.com" IN {
        type master;                           # type of zone
        file "/var/named/forward.kifarunix-demo.com"; # location of forward zone file
        allow-update { none; };
};
# Zone statement for reverse DNS lookup
zone    "122.168.192.in-addr.arpa" IN {
        type master;                    
        file "/var/named/reverse.kifarunix-demo.com"; # location of reverse zone file
        allow-update { none; };
};

After that, save the configuration file and exit.

  • The first zone statement defines the forward zone for the domain kifarunix-demo.com
  • The “type master” specifies that this DNS server is the master server for this zone, meaning that it is the authoritative source for the DNS records in this zone.
  • The “file” parameter specifies the location of the zone file that contains the DNS records for this zone. In this case, the file is “/var/named/forward.example.com”.
  • The “allow-update” parameter specifies who is allowed to update the DNS records in this zone. In this case, the value “none” means that no one is allowed to update the DNS records in these zones. This is a common setting for master DNS servers that do not allow dynamic updates from clients.

This is the named.conf file with no comment lines;

grep -vE '^//|^$' /etc/named.conf

acl "allowed" {
        192.168.122.10;
        192.168.122.11;
        192.168.122.20;
};
options {
        listen-on port 53 { 127.0.0.1; 192.168.122.10; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
        allow-query     { localhost; allowed; };
        allow-transfer  { 192.168.122.11; };
        recursion yes;
        dnssec-enable yes;
        dnssec-validation yes;
        bindkeys-file "/etc/named.root.key";
        managed-keys-directory "/var/named/dynamic";
        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";
};
logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};
# Zone statement for forward DNS lookup
zone "kifarunix-demo.com" IN {
        type master;                           # type of zone
        file "/var/named/forward.kifarunix-demo.com"; # location of forward zone file
        allow-update { none; };
};
# Zone statement for reverse DNS lookup
zone    "122.168.192.in-addr.arpa" IN {
        type master;                    
        file "/var/named/reverse.kifarunix-demo.com"; # location of reverse zone file
        allow-update { none; };
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

Next, create Zone files for both the forward and reverse zone statements created in the /etc/named.conf

Create Forward zone file

As specified in the zone statement in the /etc/named.conf file, forward zone file is located /var/named/forward.kifarunix-demo.com. Open the file and edit it as follows;

vim /var/named/forward.kifarunix-demo.com

$ORIGIN kifarunix-demo.com.
$TTL 86400
@   IN  SOA ns1.kifarunix-demo.com. admin.kifarunix-demo.com. (
        2023051301   ; serial
        3600         ; refresh
        1800         ; retry
        604800       ; expire
        86400 )      ; minimum TTL
;
; define nameservers
    IN  NS  ns1.kifarunix-demo.com.
    IN  NS  ns2.kifarunix-demo.com.
;
; IP addresses and hostnames
ns1 IN  A   192.168.122.10
ns2 IN  A   192.168.122.11
;
; client records
fileserver IN  A   192.168.122.20

Save the file and exit the editor.

Explanation of some options used;

  • $ORIGIN is a directive in a DNS zone file that sets the base domain name for relative domain names defined in the file. It specifies the domain name that will be appended to any domain name that does not end with a trailing period. This directive is usually used at the beginning of a zone file to simplify the specification of domain names within the zone file.
  • $TTL 86400: Sets the default TTL (time-to-live) value to 86400 seconds (1 day).
  • The SOA line defines the Start of Authority (SOA) record for the zone. It specifies the primary name server ns1.kifarunix-demo.com and the email address of the responsible person admin.kifarunix-demo.com. The numbers in parentheses are the;
    • serial number,
    • refresh time,
    • retry time,
    • expiry time,
    • minimum TTL value for the zone, respectively.
  • The "IN NS" specifies the nameservers for the zone, using the NS resource record type. These records indicate which nameservers are authoritative for the zone.
  • The "IN A" define the A records that maps domain names/hostnames to IP addresses.

Create Reverse Zone file

vim /var/named/reverse.kifarunix-demo.com

$ORIGIN 122.168.192.in-addr.arpa.
$TTL    86400
@   IN  SOA ns1.kifarunix-demo.com.    admin.kifarunix-demo.com. (
        2017020402  ; serial
        3600        ; refresh
        1800        ; retry
        604800      ; expire
        86400 )     ; minimum TTL
;
;nameservers
    IN  NS  ns1.kifarunix-demo.com.
    IN  NS  ns2.kifarunix-demo.com.
;
;nameserver IP addresses
    IN  A   192.168.122.10
    IN  A   192.168.122.11
;
; client IP Address
    IN  A   192.168.122.20
; nameserver PTR records
10  IN  PTR ns1.kifarunix-demo.com.
11  IN  PTR ns2.kifarunix-demo.com.
;
; client PTR records
20  IN  PTR fileserver.kifarunix-demo.com.

Save the file and exit the editor.

Explanation of some options;

  • $ORIGIN 122.168.192.in-addr.arpa.: sets the default origin for the zone to 122.168.192.in-addr.arpa. This means that any hostname without a trailing dot will be assumed to be relative to this origin.
  • The "IN PTR" specifies the reverse DNS lookup records for the nameservers, using the PTR (pointer) resource record type. These records map each IP address to its corresponding hostname.

Check BIND Configuration for Syntax Errors

Before starting BIND i.e named service, check that there are no syntactic errors in your configuration files using the following command;

named-checkconf

If the configuration file has no error, the command will return nothing, exit status 0.

Verify Forward Zone Syntax

To verify the syntax of the forward zone file run the following command;

named-checkzone kifarunix-demo.com /var/named/forward.kifarunix-demo.com
zone kifarunix-demo.com/IN: loaded serial 2023051301
OK

Verify Reverse Zone Syntax

To verify the syntax of the reverse zone file, run the command.

named-checkzone 122.168.192.in-addr.arpa /var/named/reverse.kifarunix-demo.com
zone 122.168.192.in-addr.arpa/IN: loaded serial 2023051301
OK

Start BIND DNS Service

Since there are no errors, we can start BIND and enable it to start on boot.

systemctl enable --now named

Confirm the status;

systemctl status named

● named.service - Berkeley Internet Name Domain (DNS)
   Loaded: loaded (/usr/lib/systemd/system/named.service; enabled; vendor preset: disabled)
   Active: active (running) since Sat 2023-05-13 13:37:27 EDT; 5s ago
  Process: 1801 ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} $OPTIONS (code=exited, status=0/SUCCESS)
  Process: 1799 ExecStartPre=/bin/bash -c if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi (code=exited, status=0/SUCCESS)
 Main PID: 1803 (named)
   CGroup: /system.slice/named.service
           └─1803 /usr/sbin/named -u named -c /etc/named.conf

May 13 13:37:27 ns1.kifarunix-demo.com named[1803]: network unreachable resolving './DNSKEY/IN': 2001:500:1::53#53
May 13 13:37:27 ns1.kifarunix-demo.com named[1803]: network unreachable resolving './NS/IN': 2001:500:1::53#53
May 13 13:37:27 ns1.kifarunix-demo.com named[1803]: network unreachable resolving './DNSKEY/IN': 2001:500:200::b#53
May 13 13:37:27 ns1.kifarunix-demo.com named[1803]: network unreachable resolving './NS/IN': 2001:500:200::b#53
May 13 13:37:27 ns1.kifarunix-demo.com named[1803]: network unreachable resolving './DNSKEY/IN': 2001:503:c27::2:30#53
May 13 13:37:27 ns1.kifarunix-demo.com named[1803]: network unreachable resolving './NS/IN': 2001:503:c27::2:30#53
May 13 13:37:27 ns1.kifarunix-demo.com named[1803]: network unreachable resolving './DNSKEY/IN': 2001:500:2d::d#53
May 13 13:37:27 ns1.kifarunix-demo.com named[1803]: network unreachable resolving './NS/IN': 2001:500:2d::d#53
May 13 13:37:28 ns1.kifarunix-demo.com named[1803]: managed-keys-zone: Key 20326 for zone . acceptance timer complete: key now trusted
May 13 13:37:28 ns1.kifarunix-demo.com named[1803]: resolver priming query complete
ss -alnp | grep :53

udp    UNCONN     0      0      192.168.122.10:53                    *:*                   users:(("named",pid=1803,fd=513))
udp    UNCONN     0      0      127.0.0.1:53                    *:*                   users:(("named",pid=1803,fd=512))
tcp    LISTEN     0      10     192.168.122.10:53                    *:*                   users:(("named",pid=1803,fd=22))
tcp    LISTEN     0      10     127.0.0.1:53                    *:*                   users:(("named",pid=1803,fd=21))

Open DNS Ports on Firewall

If firewall is running, enable dns service through it and reload the firewall.

firewall-cmd --add-service=dns --permanent;firewall-cmd --reload

Update Master DNS Server Address

Change DNS server of the master to that of its own by editing the /etc/resolv.conf file and adding the nameserver IP address

vim /etc/resolv.conf

Add the line:

nameserver 192.168.122.10
nameserver 8.8.8.8

Change the dns server details on the network interface. My network interface is enp0s8.

nmcli con mod enp0s8 ipv4.dns 192.168.122.10 8.8.8.8
nmcli con reload

Verify DNS Records on Master DNS Server

After that, test to check if the hostnames or addresses are being resolved.

To check name resolution:

dig ns1.kifarunix-demo.com

To check hostname resolution;

dig -x 192.168.122.10

Configure Slave DNS server Using BIND on CentOS 7

Install Required Bind Packages

Install BIND package.

yum install bind bind-utils -y

Define Slave DNS Settings

Edit the /etc/named.conf file and make the adjustments as shown below.

vim /etc/named.conf

acl "allowed" {
        192.168.122.10;
        192.168.122.11;
        192.168.122.20;
};
options {
        listen-on port 53 { 127.0.0.1; 192.168.122.11; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
        allow-query     { localhost; allowed; };
        allow-transfer  { none; };
        recursion no;
        dnssec-enable yes;
        dnssec-validation yes;
        bindkeys-file "/etc/named.root.key";
        managed-keys-directory "/var/named/dynamic";
        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";
};
logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};
# zone statement for forward dns lookup
zone "kifarunix-demo.com" IN {
        type slave;
        file "slaves/forward.kifarunix-demo.com";
        masters { 192.168.122.10; };
};
# zone statement for reverse dns lookup
zone  "122.168.192.in-addr.arpa" IN {
        type slave;
        file "slaves/reverse.kifarunix-demo.com";
        masters { 192.168.122.10; };
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

Save the file and exit.

Verify BIND Configuration for any errors

Verify the DNS configs;

named-checkconf

Start BIND DNS Service

Restart the DNS service and enable to run on boot;

systemctl restart named
systemctl enable named

Check the status;

systemctl status named

● named.service - Berkeley Internet Name Domain (DNS)
   Loaded: loaded (/usr/lib/systemd/system/named.service; disabled; vendor preset: disabled)
   Active: active (running) since Sat 2023-05-13 14:18:49 EDT; 5s ago
  Process: 2101 ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} $OPTIONS (code=exited, status=0/SUCCESS)
  Process: 2099 ExecStartPre=/bin/bash -c if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi (code=exited, status=0/SUCCESS)
 Main PID: 2103 (named)
   CGroup: /system.slice/named.service
           └─2103 /usr/sbin/named -u named -c /etc/named.conf

May 13 14:18:49 ns2.kifarunix-demo.com named[2103]: transfer of 'kifarunix-demo.com/IN' from 192.168.122.10#53: Transfer completed: 1 messages, 7 records, 209 b...ytes/sec)
May 13 14:18:49 ns2.kifarunix-demo.com named[2103]: zone kifarunix-demo.com/IN: sending notifies (serial 2023051301)
May 13 14:18:49 ns2.kifarunix-demo.com named[2103]: managed-keys-zone: Key 20326 for zone . acceptance timer complete: key now trusted
May 13 14:18:49 ns2.kifarunix-demo.com named[2103]: resolver priming query complete
May 13 14:18:49 ns2.kifarunix-demo.com named[2103]: zone 122.168.192.in-addr.arpa/IN: Transfer started.
May 13 14:18:49 ns2.kifarunix-demo.com named[2103]: transfer of '122.168.192.in-addr.arpa/IN' from 192.168.122.10#53: connected using 192.168.122.11#58456
May 13 14:18:49 ns2.kifarunix-demo.com named[2103]: zone 122.168.192.in-addr.arpa/IN: transferred serial 2023051301
May 13 14:18:49 ns2.kifarunix-demo.com named[2103]: transfer of '122.168.192.in-addr.arpa/IN' from 192.168.122.10#53: Transfer status: success
May 13 14:18:49 ns2.kifarunix-demo.com named[2103]: transfer of '122.168.192.in-addr.arpa/IN' from 192.168.122.10#53: Transfer completed: 1 messages, 10 records...ytes/sec)
May 13 14:18:49 ns2.kifarunix-demo.com named[2103]: zone 122.168.192.in-addr.arpa/IN: sending notifies (serial 2023051301)
Hint: Some lines were ellipsized, use -l to show in full.

Change the DNS server details on your network interface. In this case, we will add both DNS servers and restart the interface.

nmcli con mod enp0s8 +ipv4.dns "192.168.122.10 192.168.122.11"
nmcli con reload

Edit the /etc/resolv.conf file by adding the following lines.

nameserver 192.168.122.10
nameserver 192.168.122.11

Allow DNS service through firewall and reload firewall.

firewall-cmd --add-service=dns --permanent;firewall-cmd --reload

Test the DNS server, if everything goes well, proceed to configure the client.

Configure Nodes to use DNS Server

Install DNS Utilities

On Debian Systems and similar derivatives;

apt install dnsutils

On CentOS and similar derivatives;

yum install bind-utils

Update DNS Server Entries

Log into the client and edit the /etc/resolv.conf file. Add the IP addresses of both the primary and secondary nameserver.

vim /etc/resolv.conf
nameserver 192.168.122.10
nameserver 192.168.122.11

Verify DNS Resolution

Test for forward lookup;

nslookup fileserver
Server:		192.168.122.10
Address:	192.168.122.10#53

Name:	fileserver.kifarunix-demo.com
Address: 192.168.122.20

Test the reverse lookup;

nslookup 192.168.122.20
20.122.168.192.in-addr.arpa	name = fileserver.kifarunix-demo.com.

Magnificent, your local DNS server is now set up and operational.

And that is marks the end of our guide on how to configure Master-Slave DNS Server using BIND on CentOS 7.

Configure Local DNS Server using Dnsmasq on Ubuntu 20.04

Setup Caching-Only DNS Server using BIND9 on Ubuntu 20.04

Configure BIND DNS Server using Webmin on CentOS 8

Setup Bind DNS Using Webmin on Debian 10

Configure BIND as Slave DNS Server on Ubuntu 18.04

SUPPORT US VIA A VIRTUAL CUP OF COFFEE

We're passionate about sharing our knowledge and experiences with you through our blog. If you appreciate our efforts, consider buying us a virtual coffee. Your support keeps us motivated and enables us to continually improve, ensuring that we can provide you with the best content possible. Thank you for being a coffee-fueled champion of our work!

Photo of author
koromicha
I am the Co-founder of Kifarunix.com, Linux and the whole FOSS enthusiast, Linux System Admin and a Blue Teamer who loves to share technological tips and hacks with others as a way of sharing knowledge as: "In vain have you acquired knowledge if you have not imparted it to others".

Leave a Comment