Setup BIND DNS Server in Rocky Linux 8 [Step-by-Step]

In this guide, we shall demonstrate how to install and configure BIND DNS server running in a chroot environment. BIND, also known as named, is the widely used DNS server application across the internet. BIND however when installed with the default method poses some vulnerabilities such as exposing the root filesystem in case of a security breach. In this guide, we shall be configuring BIND in a chroot environment. What this mechanism does is to "Jail" a program to a certain path and configure it as the root directory. This in turn prevents the process to access other parts of the system. This makes running the application more secure since you are assured that in case of a breach, the attacker will not be able to access the rest of the filesystem.

 

Lab Environment

I am using my existing Rocky Linux setup to demonstrate this article. Following are the details of my Lab Environment:

Advertisement

Server Machine:
OS: Rocky Linux release 8.4 (Green Obsidian)
Hostname: rockylinux
IP Address: 172.29.10.4/24

Client Machine:
OS: Rocky Linux release 8.4 (Green Obsidian)
Hostname: rockylinux-lab
IP Address: 172.29.10.6/24

 

Step-1: Install BIND Chroot

On Rocky Linux 8, install BIND Chroot with the command below:

[root@rockylinux ~]# dnf install -y bind bind-chroot
Rocky Linux 8 - AppStream                                                                                                                                                          3.5 kB/s | 4.8 kB     00:01    
Rocky Linux 8 - AppStream                                                                                                                                                          262 kB/s | 8.2 MB     00:31    
Rocky Linux 8 - BaseOS                                                                                                                                                             3.8 kB/s | 4.3 kB     00:01    
Rocky Linux 8 - BaseOS                                                                                                                                                             2.2 MB/s | 4.5 MB     00:01    
Rocky Linux 8 - Extras                                                                                                                                                             2.5 kB/s | 3.1 kB     00:01    
Rocky Linux 8 - Extras                                                                                                                                                             2.7 kB/s | 3.8 kB     00:01    
...
Total download size: 2.2 M
Installed size: 4.5 M
Downloading Packages:
(1/2): bind-chroot-9.11.26-4.el8_4.x86_64.rpm                                                                                                                                       48 kB/s | 103 kB     00:02    
(2/2): bind-9.11.26-4.el8_4.x86_64.rpm                                                                                                                                             419 kB/s | 2.1 MB     00:05    

...
Installed:
  bind-32:9.11.26-4.el8_4.x86_64                                                                       bind-chroot-32:9.11.26-4.el8_4.x86_64                                                                      

Complete!

Verify that the packages are installed as below:

[root@rockylinux ~]# rpm -qa| grep bind
bind-9.11.26-4.el8_4.x86_64
bind-export-libs-9.11.26-4.el8_4.x86_64
bind-libs-lite-9.11.26-4.el8_4.x86_64
bind-chroot-9.11.26-4.el8_4.x86_64
bind-libs-9.11.26-4.el8_4.x86_64
bind-license-9.11.26-4.el8_4.noarch
python3-bind-9.11.26-4.el8_4.noarch
bind-utils-9.11.26-4.el8_4.x86_64

The directories below will be created once you successfully install bind-chroot

[root@rockylinux ~]# ls -l /var/named/chroot/
total 0
drwxr-x---. 2 root named  6 Jun 11 03:18 dev
drwxr-x---. 5 root named 53 Aug  7 10:35 etc
drwxr-x---. 3 root named 19 Aug  7 10:35 run
drwxr-xr-x. 4 root root  32 Aug  7 10:35 usr
drwxr-x---. 5 root named 52 Aug  7 10:35 var

 

Step-2: Turn ON BIND-Chroot Environment

To turn on the bind-chroot environment, run the initialization script located at  /usr/libexec/setup-named-chroot.sh then specify the directory at which you want to jail the bind process.

Advertisement
[root@rockylinux ~]# /usr/libexec/setup-named-chroot.sh /var/named/chroot on

The command above mounts all BIND configuration files into the chroot location. This means that you don't have to copy any files to the chroot directory.

Verify that the paths have been mounted at /var/named/chroot

[root@rockylinux-lab network-scripts]# mount | grep chroot
/dev/mapper/rl-root on /var/named/chroot/etc/localtime type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/named.root.key type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/named.conf type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/named.rfc1912.zones type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/crypto-policies/back-ends/bind.config type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/protocols type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/services type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/named type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/usr/lib64/bind type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/usr/share/GeoIP type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
tmpfs on /var/named/chroot/run/named type tmpfs (rw,nosuid,nodev,seclabel,mode=755)
/dev/mapper/rl-root on /var/named/chroot/var/named type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)

 

Step-3: Configure DNS Server (named.conf)

Edit the /etc/named.conf file and make the changes at listen-on port 53, allow-query and allow-query-cache. This is as shown below:

[root@rockylinux ~]# cat /etc/named.conf

options {
        listen-on port 53 { 127.0.0.1; any; };
        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; any; };
        allow-query-cache { localhost; any; };

        recursion yes;

        dnssec-enable yes;
        dnssec-validation yes;

        /* Path to ISC DLV key */
        bindkeys-file "/etc/named.iscdlv.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";

 

Step-4: Configure DNS Zones

We need to create the DNS zone for our environment. To achieve this, we need to edit the file /etc/named.rfc1912.zones.Before that, we need to check our network interfaces and choose the IP that will be used for the DNS configuration. This IP should be a static IP.

In my setup, I'll use 172.29.10.4/24 IP for DNS configuration.

To check the IP, run the ip a command and obtain the output.
Setup BIND DNS Server in Rocky Linux 8 [Step-by-Step]

Add the following lines to  /etc/named.rfc1912.zones to create the forward and reverse zones;

zone "example.com" IN {
        type master;
        file "example.com.zone";
        allow-update { none; };
};

zone "10.29.172.in-addr.arpa" IN {
        type master;
        file "example.com.rzone";
        allow-update { none; };
};

In the above config, example.comis the forward zone while 10.29.172.in-addr.arpais the reverse zone.  Make sure you use the correct details for your environment.

Advertisement

NOTE:

For the reverse zone, since our IP is 172.29.10.4, we have used 10.29.172.in-addr.arpa. Make sure you use the same syntax in your environment. For example, if your IP is 192.168.100.X, you should use 100.168.192.in-addr.arpa

 

4.1: Configure Forward DNS Zone File

We need to configure the forward DNS zone files where we shall be adding entries for domain name resolution.

Navigate to /var/named/.This is where we shall configure the DNS zone files.

[root@rockylinux ~]# cd /var/named

Verify that there exist DNS files;

# ls -l
total 16
drwxr-x---. 7 root  named   61 Aug  7 10:35 chroot
drwxrwx---. 2 named named    6 Jun 11 03:18 data
drwxrwx---. 2 named named    6 Jun 11 03:18 dynamic
-rw-r-----. 1 root  named 2253 Jun 11 03:18 named.ca
-rw-r-----. 1 root  named  152 Jun 11 03:18 named.empty
-rw-r-----. 1 root  named  152 Jun 11 03:18 named.localhost
-rw-r-----. 1 root  named  168 Jun 11 03:18 named.loopback
drwxrwx---. 2 named named    6 Jun 11 03:18 slaves

Copy the named.loopback contents to example.com.zoneto create the forward zone file.

[root@rockylinux named]# cp named.loopback  example.com.zone

Assign the correct permissions to the file created

[root@rockylinux named]# chmod 644 example.com.zone
[root@rockylinux named]# chown root:named example.com.zone

Edit the forward zone file created to update the entries. In this file, you will be required to configure the A records for your hosts and their respective IPs. A sample entry as shown below:

[root@rockylinux named]# cat example.com.zone 
$TTL 1D
@	IN SOA	example.com     root (
					0	; serial
					1D	; refresh
					1H	; retry
					1W	; expire
					3H )	; minimum
		IN  NS	localhost
localhost	IN A	127.0.0.1
ns-master       IN A    172.29.10.4
server1         IN A    172.29.10.5
server2         IN A    172.29.10.6

 

4.2: Create a Reverse DNS Zone File

Create a reverse DNS zone file using named.localhost

[root@rockylinux named]# cat named.localhost > example.com.rzone

Grant the correct permissions to the file created

[root@rockylinux named]# chmod 644 example.com.rzone
[root@rockylinux named]# chown root:named example.com.rzone

Update the reverse DNS records, increasing the serial number for every record you add.

[root@rockylinux named]# cat example.com.rzone 
$TTL 1D
@	IN SOA	example.com. root.example.com. (
					0	; serial
					1D	; refresh
					1H	; retry
					1W	; expire
					3H )	; minimum
        IN NS   localhost.
4      IN PTR  ns-master.example.com.
5      IN PTR  server1.example.com.
6      IN PTR  server2.example.com.


 

Step-5: Verify BIND chroot configuration

Verify bind configuration and confirm that you don't have any syntax errors.

[root@rockylinux named]# named-checkconf -t /var/named/ etc/named.conf

If you get an error such as open: etc/named.conf: file not found, verify that the contents of /var/namedare mounted at /var/named/chroot. Below is how to check and the sample output;

[root@rockylinux named]# mount | grep chroot
/dev/mapper/rl-root on /var/named/chroot/etc/named type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/usr/lib64/bind type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
tmpfs on /var/named/chroot/run/named type tmpfs (rw,nosuid,nodev,mode=755)
/dev/mapper/rl-root on /var/named/chroot/etc/localtime type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/named.root.key type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/named.conf type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/named.rfc1912.zones type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/rndc.key type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/crypto-policies/back-ends/bind.config type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/protocols type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/services type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/etc/named type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/usr/lib64/bind type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
/dev/mapper/rl-root on /var/named/chroot/usr/share/GeoIP type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
tmpfs on /var/named/chroot/run/named type tmpfs (rw,nosuid,nodev,mode=755)
/dev/mapper/rl-root on /var/named/chroot/var/named type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)

If you can't see any path mounted, re-run the named-chroot script as shown below:

[root@rockylinux ~]# /usr/libexec/setup-named-chroot.sh /var/named/chroot off
[root@rockylinux ~]# /usr/libexec/setup-named-chroot.sh /var/named/chroot on

 

Step-6: Start named-chroot service

The named-chroot service runs the same way as the default bind service, other than the fact that it is running in a jail environment. Before we can start the named-chroot service, make sure you have stopped and disabled the default named service.

[root@rockylinux named]# systemctl stop named
[root@rockylinux named]# systemctl disable named

Start and enable the named-chroot service

[root@rockylinux named]# systemctl enable --now named-chroot

Verify that the service has started successfully and is running

[root@rockylinux-lab named]# systemctl status named-chroot
● named-chroot.service - Berkeley Internet Name Domain (DNS)
   Loaded: loaded (/usr/lib/systemd/system/named-chroot.service; disabled; vendor preset: disabled)
   Active: active (running) since Sat 2021-08-07 12:53:50 EAT; 14s ago
  Process: 1726 ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} -t /var/named/chroot $OPTIONS (code=exited, status=0/SUCCESS)
  Process: 1721 ExecStartPre=/bin/bash -c if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -t /var/named/chroot -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi (cod>
 Main PID: 1728 (named)
    Tasks: 7 (limit: 4942)
   Memory: 64.0M
   CGroup: /system.slice/named-chroot.service
           └─1728 /usr/sbin/named -u named -c /etc/named.conf -t /var/named/chroot

Aug 07 12:53:50 rockylinux-lab named[1728]: network unreachable resolving './NS/IN': 2001:7fd::1#53
Aug 07 12:53:50 rockylinux-lab named[1728]: network unreachable resolving './DNSKEY/IN': 2001:503:c27::2:30#53
Aug 07 12:53:50 rockylinux-lab named[1728]: network unreachable resolving './NS/IN': 2001:503:c27::2:30#53
Aug 07 12:53:50 rockylinux-lab named[1728]: network unreachable resolving './DNSKEY/IN': 2001:500:9f::42#53
Aug 07 12:53:50 rockylinux-lab named[1728]: network unreachable resolving './NS/IN': 2001:500:9f::42#53
Aug 07 12:53:50 rockylinux-lab named[1728]: network unreachable resolving './DNSKEY/IN': 2001:500:a8::e#53
Aug 07 12:53:50 rockylinux-lab named[1728]: network unreachable resolving './DNSKEY/IN': 2001:dc3::35#53
Aug 07 12:53:50 rockylinux-lab named[1728]: managed-keys-zone: Key 20326 for zone . acceptance timer complete: key now trusted
Aug 07 12:53:50 rockylinux-lab named[1728]: network unreachable resolving './DNSKEY/IN': 2001:500:9f::42#53
Aug 07 12:53:51 rockylinux-lab named[1728]: resolver priming query complete

 

Step-7: Configure Rocky Linux 8 node as DNS Client

We can now configure the DNS server on Rocky Linux to verify domain resolution.

Add a DNS entry to /etc/resolv.conf file as shown below:

[root@rockylinux-lab named]# echo "nameserver 172.29.10.4" >> /etc/resolv.conf

Remember to use the IP of the DNS server we configured above.

 

Step-8: Test DNS Configuration from Client

8.1: Test forward lookup zone

We can now check domain name resolution using our DNS server as shown below:

[root@rockylinux-lab named]# nslookup server1.example.com
Server:		172.29.10.4
Address:	172.29.10.4#53

Name:	server1.example.com
Address: 172.29.10.5

 

8.2: Test reverse lookup zone

We can also use the dig command to get the reverse DNS information about the domain name as below. Look out for ANSWER section:

[root@rockylinux-lab ~]# dig -x 172.29.10.5

; <<>> DiG 9.11.26-RedHat-9.11.26-4.el8_4 <<>> -x 172.29.10.5
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23231
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 3

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: db03e58df53932aa0d10867c610e842dd8934fbd301f97fb (good)
;; QUESTION SECTION:
;5.10.29.172.in-addr.arpa.	IN	PTR

;; ANSWER SECTION:
5.10.29.172.in-addr.arpa. 86400	IN	PTR	server1.example.com.

;; AUTHORITY SECTION:
10.29.172.in-addr.arpa.	86400	IN	NS	localhost.

;; ADDITIONAL SECTION:
localhost.		86400	IN	A	127.0.0.1
localhost.		86400	IN	AAAA	::1

;; Query time: 1 msec
;; SERVER: 172.29.10.4#53(172.29.10.4)
;; WHEN: Sat Aug 07 16:01:33 EAT 2021
;; MSG SIZE  rcvd: 181

As we can see, name resolution is working, just as expected.

 

Conclusion

I hope this article has been elaborate enough, we have configured bind-chroot DNS server on Rocky Linux 8. Feel free to reach out in the comment section in case you have any concerns.

 

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment