CIQ

Part 3B: BIND on Rocky Linux: Advanced Guide for Configuring Your Own DNS Server

Part 3B: BIND on Rocky Linux: Advanced Guide for Configuring Your Own DNS Server
Wale SoyinkaDecember 5, 2024

Introduction

We pick up from where we left off in our previous Basic BIND DNS server guide in this advanced DNS guide.

As a quick refresher, we went over DNS classes and DNS record types, we walked through how to install and configure BIND on a Rocky Linux server, we also covered common DNS daemon management tasks.

The BIND project is very mature and thus supports a rich set of features that can easily serve the needs of even the most demanding of environments. So much so that, a compendium of hard-back covered textbooks will be needed to showcase the full capabilities of the BIND software! Thankfully this is not a textbook and we’ll be able to share some quick cookbook style recipes showcasing some popular but advanced features of BIND in the following sections.

Installing BIND on Rocky Linux

If you’re following along on your own Rocky Linux from CIQ (RLC) server and you haven’t already installed the BIND application as described here - “Part 3a: BIND on Rocky Linux: A Basic Guide to Configuring Your Own DNS Server”, you can use the DNF command to install BIND. Type:

sudo dnf install bind

With BIND installed, the advanced features can be configured and enabled by turning on various knobs-and-dials in BIND’s main configuration file /etc/named.conf as well as in the appropriate zone configuration file(s) - (such as /var/named/example.com.zone). Let's go.

Basic BIND Configuration

For your convenience, we’ll re-present a basic plain vanilla /etc/named.conf here again. This is the base configuration that we’ll be building upon.

Basic /etc/named.conf file.

; Basic BIND configuration


options { 
   directory "/var/named"; 
   allow-query { any; }; 
   recursion yes; 
};


zone "example.com" IN { 
   type master; 
   file "/var/named/example.com.zone"; 
};

Basic Zone file

And the corresponding basic zone file defining the DNS records for the example.com zone looks like this:

$TTL 86400 
@   IN  SOA ns1.example.com. admin.example.com. ( 
       2025110101 ; Serial 
       3600       ; Refresh 
       1800       ; Retry 
       1209600    ; Expire 
       86400 )    ; Minimum TTL


; This is a comment line


; Nameservers 
   IN  NS  ns1.example.com.


; "A" record for example.com 
@   IN  A   172.16.1.1


; "A" records for ns1 and www hostnames 
ns1 IN  A   172.16.1.10 
www IN  A   172.16.1.20

Starting, Stopping and enabling the named daemon

After creating and vetting the configuration files for BIND, you should enable the service to make it start automatically with system boot. Enable and simultaneously start the BIND daemon by running:

sudo systemctl enable –-now named 

Finally, make sure any running host based firewall sub-system allows DNS traffic on port 53 (both TCP and UDP):

sudo firewall-cmd --add-port=53/udp --permanent 
sudo firewall-cmd --add-port=53/tcp --permanent 
sudo firewall-cmd --reload

Advanced BIND features and configuration

The following sections cover some advanced BIND features. These features are often necessary in larger network environments needing enterprise grade DNS features and functionality.

DNSSEC

We didn’t take any particular measures to secure or protect basic BIND DNS server setup and so we’ll start off our advanced configuration guide by addressing that with DNSSEC.

DNSSEC (Domain Name System Security Extensions) is like the bouncer at the club who checks IDs to ensure everyone is who they say they are. When you sign your zone with DNSSEC, you're essentially saying, "Trust me (and my zones), I’m the real deal!" By signing your DNS records, you prevent attackers from tampering with your DNS data and ensure clients get authentic, untampered responses.

You have a couple of options available to you for implementing DNSSEC on your BIND-powered DNS server running on RLC. It can be done manually by managing the key generation and signing process yourself Or you can let BIND auto-magically manage things for you in the background. For the manual approach, you'll need a couple of tools: dnssec-keygen to generate your keys, and dnssec-signzone to sign your zone files. Both tools come bundled with BIND, so you don’t need to go hunting for them. We’ll let BIND automatically manage DNSSEC for us in this section.

Configuring DNSSEC in BIND

For the automatic DNSSEC management approach you need to add a single directive in the named.conf for the zone you want to enable DNSSEC for. The directive is:

dnssec-policy default;

Here is an updated and complete /etc/named.conf file showing the dnssec-policy directive. Use any text editor to create the entry Or copy and paste the configuration file to test things on your server.

options { 
   directory "/var/named"; 
   allow-query { any; }; 
   recursion yes; 
};

zone "example.com" IN { 
   type master; 
   file "/var/named/example.com.zone";
   dnssec-policy default; 
};

After making the change, restart the BIND server by running:

sudo systemctl restart named

Once the named daemon successfully restarts, you’ll notice that 2 important DNSSEC related files have been created and added under the /var/named/ directory.

The files are:

Kexample.com..key

This is the public key file automatically generated by dnssec-keygen for your domain (in this case, example.com). It contains the public part of the DNSSEC key pair, which is used by resolvers (DNS clients) to verify the authenticity of DNS records for the zone. The public key is used in DNS responses, specifically in DNSKEY records, and is published in your zone file to allow DNSSEC validation. This key is meant to be shared with anyone querying the zone to validate the DNSSEC signatures.

Kexample.com..private

This is the private key file generated by dnssec-keygen for your domain. It contains the private part of the DNSSEC key pair, which is used to sign the DNS zone.

The private key is used to sign the DNS records in your zone, creating RRSIG (Resource Record Signature) records. This file must be kept secure because anyone who has access to it can sign records for your domain, potentially compromising its integrity. So...guard it like it’s your secret stash of chocolate.

These two files work together as part of the DNSSEC mechanism: the private key signs the zone, and the public key is used to verify that the signed records are valid and have not been tampered with.

Testing DNSSEC

With DNSSEC now enabled for the example.com zone, you can test or query your BIND DNS server for DNSSEC specific records.

For example to query the server for DNSSEC info for the A record associated with ns1.example.com type:

dig +dnssec +short @localhost A ns1.example.com

Sample output

172.16.1.10

A 13 3 86400 20241129200344 20241121155708 49625 example.com. UOj6fmmDbCBIQ+qCzgVi25RjFRMN4zCfofCg6ONfVQ5/i0g8+1CYGg/L KM7+SO/y79H/UyVWhe2FSnZ/tSEIbA==

The output from dig +dnssec +short @localhost A ns1.example.com provides two main pieces of information:

IP Address (172.16.1.10): This is the A record for ns1.example.com, which maps the hostname to its corresponding IP address.

RRSIG (DNSSEC Signature): The second line contains the RRSIG record for the A record, which is a DNSSEC signature. It includes:

13: The DNSSEC algorithm used (RSASHA256). 3: The number of signatures. 86400: The time-to-live (TTL) in seconds. 20241129200344 and 20241121155708: The signature validity period (start and end). 49625: The key ID. example.com.: The zone where the record belongs. The rest (UOj6…..tSEIbA==) is the signature (base64-encoded) validating the authenticity of the DNS record. This means the A record is signed with DNSSEC, and the signature ensures the integrity of the A record for ns1.example.com.

TIP: If you’re still wondering, "Why go through all this trouble?"—think of DNSSEC as your internet security guard - it ensures that the information clients receive from your DNS server is the real deal and hasn’t been hijacked. Yes, it adds a little complexity, but the payoff in security is worth it.

Forwarding and Caching

You can configure BIND to forward DNS queries to other DNS servers. This can improve resolution speed by caching frequently requested domains.

Add the following to your options block in /etc/named.conf:

forwarders { 
   8.8.8.8; 
   1.1.1.1; 
};


This configuration will forward any queries that BIND cannot resolve locally to Google’s and Cloudflare’s public DNS servers.

Access Control Lists (ACLs)

BIND allows you to define ACLs to control which clients can query or make changes to your DNS server. This is a good thing if your DNS server is exposed to the internet and your intention is not to be a DNS server for the whole world!

Here’s an example:

options {
    directory "/var/named";
    allow-query { trusted; };
    recursion yes;
};


acl "trusted" { 
   172.16.1.0/24; 
   localhost; 
};


...<TRUNCATED FOR BREVITY>...

Note that we’ve built upon our basic /etc/named.conf file by changing the allow-query directive from “ allow-query { any; };” to “allow-query { trusted; };”

In this example, only clients from the 172.16.1.0/24 subnet and the localhost are allowed to query the DNS server.

Don’t forget to restart the named daemon after changing named.conf configuration to implement ACLs.

Zone transfers

The concept of Zone transfers allows DNS zone information to be replicated from a primary DNS server to one or more secondary DNS servers. This redundancy ensures that if the primary server goes down, the secondary servers can still handle queries for the domain, thereby providing both high availability and load balancing. WHen correctly implemented, zone transfers ensure that DNS queries are resolved correctly, no matter which server handles the request.

There are two main types of zone transfers in BIND:

AXFR (Full Zone Transfer): An AXFR transfer replicates the entire zone file from the primary to the secondary server. Typically used when a new secondary server is being set up or when the entire zone has undergone significant changes.

IXFR (Incremental Zone Transfer): An IXFR style transfer only sends the changes (incremental updates) since the last transfer. This is in contrast to AXFR style transfers where the entire zone is sent. IXFR is thus more efficient than AXFR because it reduces the amount of data transferred, especially for zones with frequent updates.

If you have multiple DNS servers, you can configure zone transfers to ensure consistency. Here’s an example of an “example.com” zone configuration section allowing transfers to a secondary DNS server with the IP address 172.16.1.15:

zone "example.com" IN { 
   type master; 
   file "/var/named/example.com.zone"; 
   allow-transfer { 172.16.1.15; }; 
};

This configuration allows a secondary server at 172.16.1.15 to receive zone transfers, thereby ensuring it has up-to-date DNS information.

TIP: Protecting zone transfers Enabling BIND’s zone transfer features can introduce security risks if not properly controlled. A bad-actor could gain access to sensitive DNS records (such as internal names, IP addresses) by intercepting a zone transfer. To mitigate this risk, it’s crucial to restrict zone transfers to trusted IP addresses using allow-transfer. You can also use TSIG (Transaction Signature) to secure zone transfers with digital signatures, ensuring that both the source and the destination servers can authenticate each other.

Dynamic DNS with BIND

Dynamic DNS (DDNS) with BIND allows DNS records to be automatically updated without manual intervention (i.e. editing zone files). BIND supports Dynamic DNS (DDNS). This feature is particularly useful in environments where IP addresses change frequently, such as in networks with DHCP servers. It’s particularly useful in large HPC environments.

Configuring Dynamic DNS

For Dynamic DNS, you'll need to modify your zone file settings to allow updates and create an update policy. And because we don’t want any bogus DDNS clients tainting our DNS database, we use the transaction signature (TSIG) protocol to ensure that updates to the DNS database are authenticated.

Start by using the tsig-keygen to generate the key to be used for TSIG signing. FOr convenience, we name/label the key ddns.example.com-key. Type:

tsig-keygen ddns.example.com-key | tee -a /etc/named.conf > /var/named/ddns.example.com-key

Next create the target zone in named.conf to allow updates from DDNS clients that present the appropriate TSIG key. For this we’ll create a new sub-domain named “ddns.example.com” for our DDNS clients.

zone "ddns.example.com" IN { 
   type master; 
   file "/var/named/dynamic/ddns.example.com.zone"; 
   allow-update { key "ddns.example.com-key"; }; 
};
  • allow-update: This directive specifies which key can be used to update the zone dynamically. That matches the key file generated using the trusty tsig-keygen utility.

First create the directory that will be used for storing the zone database file for the sub-domain.

mkdir /var/named/dynamic

Finally create a minimal zone file named /var/named/dynamic/ddns.example.com.zone for the ddns.example.com zone. Create the file using a text editor or copy & paste the configuration to follow along on your server.

$TTL 86400      ; 1 day
@       IN SOA  ns1.example.com. admin.example.com. (
                                2025110105 ; serial
                                3600       ; refresh (1 hour)
                                1800       ; retry (30 minutes)
                                1209600    ; expire (2 weeks)
                                86400      ; minimum (1 day)
                                )

; Nameservers
   IN  NS  ns1.example.com.

Run some quick sanity and syntax checks on the configuration files that we just hand-crafted:

Check the /etc/named.conf configuration file:

named-checkconf /etc/named.conf

Check the zone file by running:

named-checkzone dynamic.example.com /var/named/dynamic/ddns.example.com.zone

If no glaring errors are returned, then you can rest assured that your zone files have passed the basic snuff tests.

After making DDNS configuration changes, restart the named daemon by running:

sudo systemctl restart named

Updating DNS Records Dynamically

Once configured, you can use the nsupdate utility to test making dynamic changes to your DNS records. Here’s an example of adding a new “A” type record for the hostname foo.ddns.example.com:

nsupdate -k 
> server localhost 
> update add foo.ddns.example.com. 86400 A 172.16.1.72 
> send

This sequence of commands adds an A record for foo.ddns.example.com pointing to 172.16.1.72. The change is applied immediately without needing to edit the zone file manually.

TIP: DHCP Servers, Clients, iPXE and DNS Integration: Dynamic DNS is often used in conjunction with DHCP servers, especially in environments where devices frequently connect and disconnect from the network, such as in high-performance computing (HPC) clusters.

DHCP Servers and Clients

A DHCP server dynamically assigns IP addresses to clients on the network. Besides assigning and managing IP addresses in its own local database, the DHCP server can be further configured to update a DNS server with relevant records. This means that whenever it leases an IP address to a new client, it can pass on that information to a supported DNS server - thereby ensuring that the DNS records are always up to date.

If you haven’t already done so, please check out our How to Install and Configure a DHCP Server on Rocky Linux guide

Assuming you have installed and are using ISC DHCP server, here’s an example of configuring the ISC DHCP server to work with BIND:

In /etc/dhcp/dhcpd.conf, add:

zone example.com. { 
   primary 127.0.0.1; 
   key rndc-key; 
}


subnet 172.16.1.0 netmask 255.255.255.0 { 
   range 172.16.1.10 172.16.1.100; 
   option domain-name-servers 172.16.1.1; 
   option domain-name "example.com"; 
   option routers 172.16.1.1; 
   update-static-leases on; 
}

This configuration allows the DHCP server to automatically update the BIND DNS server with new records as IP addresses are leased to clients.

iPXE Boot and DNS

iPXE is a network bootloader firmware that allows machines to boot over the network using standard protocols like HTTP, TFTP, or DNS. In an HPC environment, iPXE can be used to provision compute nodes by booting them from a centralized server. For example, when a new node boots via iPXE, the DHCP server assigns it an IP address and updates the BIND server with the node's hostname. This ensures that other nodes and management tools can resolve the new node's hostname and integrate it seamlessly into the cluster.

DNS plays a role in this setup, as each node must be able to resolve the server’s hostname to download the boot image. By integrating BIND with DHCP and iPXE, you can create a highly automated provisioning environment for your HPC nodes or you can use a turn-key cluster provisioning solution like Warewulf to do it all for you!

Wrapping Up

You made it to the end of this Advanced BIND DNS Guide—congratulations! 🎉

We covered a lot: DNSSEC, forwarding, ACLs, zone transfers, DDNS, Caching — and yet, we’ve barely scratched the surface of BIND’s capabilities. Speaking of caching and stale DNS records, don’t miss Greg Sowell’s short and brilliant video on Troubleshooting Stale DNS With Ascender Ledger Pro.

Oh, and speaking of Ascender—stay tuned! We can’t wait to share the next installment of our DNS series with you. It's BIND bound to be a deep dive into the wonderfully nerdy world of automating the deployment and management of DNS with Ascender. 🚀

Related posts

2023 Holiday Gift Guide for Rocky Linux Users

2023 Holiday Gift Guide for Rocky Linux Users

Dec 19, 2023

Rocky Linux

Why Rocky Linux Is a Rock-Solid Choice in an Economic Downturn

Why Rocky Linux Is a Rock-Solid Choice in an Economic Downturn

Jan 18, 2023

Rocky Linux

6 Signs That It's Time to Move to Rocky Linux

6 Signs That It's Time to Move to Rocky Linux

Feb 23, 2023

Rocky Linux

123
54
>>>