Berkeley Internet Name Domain (BIND) is an open source, standards compliant DNS server. It can be commonly used to provide:
- Caching DNS server in the local network
- Authoritative DNS server for zones
- Secondary server to provide high availability for zones
As BIND can be used in a number of capacities, including serving public-facing DNS services, it can become a target for bad actors. To help protect the service against penetration and exploitation, there are a few options available limit any potential breach:
- Protect BIND with SELinux
- Operate BIND in a change-root environment
- Run BIND in a container
This article will focus on the second option: Operating BIND in a change-root environment.
While SELinux in enforcing
mode is seen as more secure as it prevents exploitation of known BIND security vulnerabilities, SELinux can pose potential operational difficulties with other aspects of the system. Runninf BIND in a change-root environment, while not as secure as SELinux, provides a good comprimise between a bare install and SELinux protection.
The change-root feature allows an adminitrator to define an alternate root directory for a process and its sub-processes. For example /var/named/chroot
can be defined as the root directory for named. The change-root mechanism prevents the named
process from accessing files outside of /var/named/chroot/
.
BIND: Installation and first run
(adapted from the RHEL BIND guide)
On RHEL derivatives, BIND is distributed under the bind
package prefix.
dnf install -y bind bind-utils
Edit the BIND configuration in /etc/named.conf
to enable basic functionality, replacing values inside the <>
brackets:
listen-on port 53 { 127.0.0.1; <ip_address>; };
listen-on-v6 port 53 { ::1; 2001:db8:1::1; };
allow-query { localhost; <local_net>; 2001:db8:1::/64; };
allow-recursion { localhost; <local_net>; 2001:db8:1::/64; };
forwarders { 9.9.9.9; 149.112.112.112; };
Save the file and validate the config for syntax errors:
named-checkconf
Configure the firewall to accept DNS traffic:
firewall-cmd --add-service=dns
firewall-cmd --runtime-to-permanent
Start the service and verify operation:
systemctl start named
systemctl status named
dig @localhost www.example.org
# Run the same command again to confirm
# the caching function is working
# through a lower query response time
dig @localhost www.example.org
Stop the service in readiness to install the change-root package:
systemctl stop named
BIND change-root: Installation
Once the base installation of BIND has been tested, the change-root package, bind-chroot
, can be installed. Theoretically, you should be able to start with installation of bind-chroot
, but experience with starting with the change-root package has shown that it can result in unexpected behaviour and errors.
# capture the contents of /var/named.
# These files/dirs should be mounted
# in /var/named/chroot/var/named when
# named-chroot is started
ls /var/named
dnf install bind-chroot
systemctl start named-chroot
systemctl status named-chroot
dnf install bind-chroot
systemctl start named-chroot
systemctl status named-chroot
ls /var/named/chroot/var/name
If named-chroot
starts without error, you can enable the service for operation:
systemctl enable --now named-chroot
With BIND operating in a change-root environment, you continue to configure the DNS server with zones, access control and options as required.
Configuring logging
Effective logging aids in the administration and management of the service. Enable the various channels to define the BIND logging functionality.
Create the directory structure and permissions required to support the logging functions:
mkdir /var/named/log/
chown named:named /var/named/log/
chmod 700 /var/named/log/
Zone transfer logging:
logging {
...
category notify {
zone_transfer_log;
};
category xfer-in {
zone_transfer_log;
};
category xfer-out {
zone_transfer_log;
};
channel zone_transfer_log {
file "/var/named/log/transfer.log" versions 3 size 5m;
print-time yes;
print-category yes;
print-severity yes;
severity info;
};
...
};
Query logging:
logging {
...
category queries {
queries_log;
};
channel queries_log {
file "/var/named/log/querylog" versions 3 size 5m;
severity dynamic;
print-category yes;
print-time yes;
print-severity yes;
};
...
};
Validate the config for syntax errors:
named-checkconf
Configure DNSSEC
DNSSEC is used to provide zone signing and ensure authentication and data integrity.
Edit named.conf and make the following changes:
options {
...
dnssec-validation yes;
...
};
zone "example.com" {
...
dnssec-policy default;
...
};
After restarting BIND, the DNSSEC public and private keys are created and stored in the BIND base directory (/var/named
). Details of the public key will need to be added to the domain registrar to enable DNSSEC validation.
To retrieve the public key details, run:
dnssec-dsfromkey Kexample.org.+013+21093.key
example.org. IN DS 21099 13 2 5E2BE017A8282E5456896E111780D9BBD1BCC8B08D86E088FEA4
Where:
21098
is the tag name;13
is the algorithm;2
is the hash mechanism;5E2B...FEA4
is the digest
Test DNSSEC validation using dig
. Look for the flag ad
to indicate authenticated data:
dig @9.9.9.9 example.org A +dnssec +multiline
; <<>> DiG 9.16.23-RH <<>> @9.9.9.9 example.org A +dnssec +multiline
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3667
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 512
;; QUESTION SECTION:
;example.org. IN A
;; ANSWER SECTION:
example.org. 1322 IN A 93.184.215.14
example.org. 1322 IN RRSIG A 13 2 3600 (
20240624100026 20240603162239 37219 example.org.
yCihpoB50B/aKlDoS0HHxoQQQyQYTn8sKaY2GKJqw3zd
XgKPz1k8hUF0qqCrPVmc0jUe5hDXCLYVpLQnnm+XiQ== )
;; Query time: 37 msec
;; SERVER: 9.9.9.9#53(9.9.9.9)
;; WHEN: Wed Jun 05 22:16:44 AEST 2024
;; MSG SIZE rcvd: 163