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.
Table of Contents
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:
Server | Hostname | IP Address | Role |
Server1 | ns1.kifarunix-demo.com | 192.168.122.10 | Master DNS Server |
Server2 | ns2.kifarunix-demo.com | 192.168.122.11 | Slave DNS Server |
Server3 | fileserver.kifarunix-demo.com | 192.168.122.20 | Client 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 addresses127.0.0.1
and::1
, as well as the IP addresses of all interfaces on the server that runs BIND.localnets
: Matches the loopback addresses127.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 personadmin.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 theNS
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 to122.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 thePTR
(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.
Related Tutorials
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