Configure Dns Servers With Failover Using Bind
Date: 14 April 2023
1 Introduction
We are going to setup and confgure a DNS server with a failover and dynamic updates on RockyLinux using BIND.
named
stands for NAMEserver Daemon.
The Bind packages is called named
in the RedHat-like distribution like RockyLinux.
2 Prerequisites
Two VMs with RockyLinux with the following configurations
Hostname | IP address | Roles | SELinux | FirewallD |
---|---|---|---|---|
admin1.hl.test | 10.10.0.2/24 | Master DNS | Enforcing | Enabled |
admin2.hl.test | 10.10.0.3/24 | Backup DNS | Enforcing | Enabled |
3 The Plan
- Install the required packages on both servers
- RNDC Setup
- Configure Master DNS
- Configure Backup DNS
- Configure a client server for testing
4 Primary configuration on the nodes
On both server, install the following packages
sudo dnf install bind bind-utils -y
Let's make sure that the service is enabled at startup.
sudo systemctl enable named
Allow DNS traffic
sudo firewall-cmd --add-service=dns --permanent sudo firewall-cmd --reload
success success
Setup the log directory for named
sudo mkdir -p -m 0700 /var/log/named sudo chown named:named /var/log/named sudo ls -ldh /var/log/named
drwx------. 2 named named 6 Apr 14 14:40 /var/log/named
5 RNDC Setup
Check out this great book for more information about DNS and other System Administration stuff.
RNDC or "Remote Name Daemon Control Utility". It's a command that allows you to control you Domain Name System (DNS) without altering or modifying you DNS configuration files.
To use the rndc
command, we must first generate a key and then import it into the named
configuration file.
Let's create a key
sudo rndc-confgen -a -b 512
wrote key file "/etc/rndc.key"
We need to give it appropriate permissions.
chown root:named /etc/rndc.key chmod 0640 /etc/rndc.key
6 Master DNS configuration
We will seperate our configuration into multiple files and use include
statement to embed these files into /etc/named.conf
file.
This will help us seperate the the parts of the configuraton that are static from those that can be changed overtime.
sudo tree /etc/named --noreport
/etc/named ├── logging.conf └── zones.conf
The main configuration file
the main configuration file for named
is /etc/named.conf
, open this file and add the following content
# vim: syntax=named # Include RFC 1912 compliant zone files include "/etc/named.rfc1912.zones"; # Include root DNSSEC trust anchor key include "/etc/named.root.key"; # Include rndc key for remote control of named include "/etc/rndc.key"; # Include zones configuration file include "/etc/named/zones.conf"; # Include logging configuration file include "/etc/named/logging.conf"; # Allow rndc management on localhost using rndc-key controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; }; # Limit access to trusted networks acl "trusted" { # Allow loopback addresses 127.0.0.0/8; # Add local LAN subnet(s) 10.10.0.0/24; }; # Set global options options { # Listen on port 53 for requests from localhost and 10.10.0.2 (MASTER) listen-on port 53 { 127.0.0.1; 10.10.0.2; }; # Disable IPv6 listen-on-v6 port 53 { none; }; # Set directory for zone files, cache dump, stats, and root DNSSEC trust anchors 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"; secroots-file "/var/named/data/named.secroots"; recursing-file "/var/named/data/named.recursing"; # Disable built-in server information zones version none; hostname none; server-id none; # Enable recursion and allow queries from trusted networks only recursion yes; allow-recursion { trusted; }; allow-query { trusted; }; # Allow zone transfers from localhost and 10.10.0.3 (SLAVE) allow-transfer { localhost; 10.10.0.3; }; # Enable DNSSEC validation dnssec-validation yes; # Set directory for managed keys managed-keys-directory "/var/named/dynamic"; # Set directory for GeoIP data geoip-directory "/usr/share/GeoIP"; # Set PID file and session key file pid-file "/run/named/named.pid"; session-keyfile "/run/named/session.key"; # Include bind crypto policies configuration include "/etc/crypto-policies/back-ends/bind.config"; };
The zones configuration file
Here we define our zones; each zone must have its corresponding reverse zone
In our case, we need to setup a forward zone and a reverse zone for our local domain hl.test
. All data related to this zones is saved on /data/db.hl.test
and /data=db.0.10.10
respectively.
Of course, you can use whatever filename with the file
clause in the zone
section, here I chose to use db.hl.test
and db.0.10.10
for example.
reverse zone is indentified as follow:
<subnet ip in reverse>.in-addr.arpa
in-addr.arpa
is a fixed suffix.
# vim: syntax=named # Use the root hints file for "." zone zone "." IN { type hint; file "named.ca"; }; # Internal zone definitions zone "hl.test" { type master; file "data/db.hl.test"; # Allow updates with rndc key allow-update { key rndc-key; }; # Notify slave servers when zone changes notify yes; }; # Reverse DNS zone for 10.10.0.0/16 subnet zone "0.10.10.in-addr.arpa" { type master; file "data/db.0.10.10"; # Allow updates with rndc key allow-update { key rndc-key; }; # Notify slave servers when zone changes notify yes; };
Our DNS records are stored in files that act as a database on the primary server and called the Zones files. The secondary server fetches this data regularly for consistency.
Hence, the full path is /var/named/data/db.hl.test
As you can see from the zones configuration we used above, we ordered our server to fetch it's records data from data/db.hl.test
.
Of course, this path is relative, because we mentioned the root directory in the main configuration above with directory "/var/named"
The forward zone records.
Make sure to update the Serial
number in the zone files file every time it is modified. This allows Bind to recognize that a change has been made.
; vim: ft=bindzone
$TTL 86400 ; 1 day
@ IN SOA dns1.hl.test. root.hl.test. (
3 ; Serial
3600 ; Refresh (1 hour)
3600 ; Retry (1 hour)
604800 ; Expire (1 week)
3600 ; Minimum (1 hour)
)
; name servers -- NS records
@ IN NS ns1.hl.test.
@ IN NS ns2.hl.test.
; name servers -- A records
ns1.hl.test. IN A 10.10.0.2
ns2.hl.test. IN A 10.10.0.3
; 10.10.0.0/24 -- A records
admin1.hl.test. IN A 10.10.0.2
admin2.hl.test. IN A 10.10.0.3
And then, the reverse zone records
; vim: ft=bindzone
;
; BIND reverse data file for broadcast zone
;
$TTL 604800
@ IN SOA hl.test. root.hl.test. (
3 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
; name servers
IN NS ns1.hl.test.
IN NS ns2.hl.test.
; PTR Records
2 IN PTR ns1.hl.test. ; 10.10.0.2
3 IN PTR ns2.hl.test. ; 10.10.0.2
2 IN PTR admin1.hl.test. ; 10.10.0.2
3 IN PTR admin2.hl.test. ; 10.10.0.2
The logging configuration file
And the logging configuration file
# vim: syntax=named # Logging configuration logging { # Default debug channel channel default_debug { file "data/named.run"; severity dynamic; }; # Common log channel channel "common_log" { file "/var/log/named/named.log" versions 10 size 5m; severity dynamic; print-category yes; print-severity yes; print-time yes; }; # Categories for logging category default { "common_log"; }; category general { "common_log"; }; category queries { "common_log"; }; category client { "common_log"; }; category security { "common_log"; }; category query-errors { "common_log"; }; category lame-servers { null; }; };
7 Backup DNS configuration
The main configuration file
Now with the backup DNS configuration
# vim: syntax=named # Include RFC 1912 compliant zone files include "/etc/named.rfc1912.zones"; # Include root DNSSEC trust anchor key include "/etc/named.root.key"; # Include zones configuration file include "/etc/named/zones.conf"; # Include logging configuration file include "/etc/named/logging.conf"; # Limit access to trusted networks acl "trusted" { # Allow loopback addresses 127.0.0.0/8; # Add local LAN subnet(s) 10.10.0.0/24; }; # Set global options options { # Listen on port 53 for requests from localhost and 10.10.0.3 (SLAVE) listen-on port 53 { 127.0.0.1; 10.10.0.3; }; # Disable IPv6 listen-on-v6 port 53 { none; }; # Set directory for zone files, cache dump, stats, and root DNSSEC trust anchors 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"; secroots-file "/var/named/data/named.secroots"; recursing-file "/var/named/data/named.recursing"; # Disable built-in server information zones version none; hostname none; server-id none; # Enable recursion and allow queries from trusted networks only recursion yes; allow-recursion { trusted; }; allow-query { trusted; }; allow-transfer { none }; # Enable DNSSEC validation dnssec-validation yes; # Set directory for managed keys managed-keys-directory "/var/named/dynamic"; # Set directory for GeoIP data geoip-directory "/usr/share/GeoIP"; # Set PID file and session key file pid-file "/run/named/named.pid"; session-keyfile "/run/named/session.key"; # Include bind crypto policies configuration include "/etc/crypto-policies/back-ends/bind.config"; };
The zones configuration file
# vim: syntax=named # Use the root hints file for "." zone zone "." IN { type hint; file "named.ca"; }; # Internal zone definitions zone "hl.test" { type slave; file "data/db.hl.test"; masters { 10.10.0.2; }; allow-notify { 10.10.0.2; }; }; zone "0.10.10.in-addr.arpa" { type slave; file "data/db.0.10.10"; masters { 10.10.0.2; }; allow-notify { 10.10.0.2; }; };
The logging configuration file
And then the logging configuration file.
# vim: syntax=named # Logging configuration logging { # Default debug channel channel default_debug { file "data/named.run"; severity dynamic; }; # Common log channel channel "common_log" { file "/var/log/named/named.log" versions 10 size 5m; severity dynamic; print-category yes; print-severity yes; print-time yes; }; # Categories for logging category default { "common_log"; }; category general { "common_log"; }; category queries { "common_log"; }; category client { "common_log"; }; category security { "common_log"; }; category query-errors { "common_log"; }; category lame-servers { null; }; };
8 Configure a client server
- The number of nameservers allowed on
/etc/resolv.conf
are 3. - The first request are tried against the first nameserver, if the query was timed out, it will move to the next.
- Each nameserver is tried 4 times.
To configure the client, all we need to do is to update the /etc/resolv.conf
file with the IP addresses of our new local DNS server.
sudo nmcli c mod eth0 ipv4.dns '10.10.0.2 10.10.0.3'
cat /etc/resolv.conf
# Generated by NetworkManager nameserver 10.10.0.2 nameserver 10.10.0.3