Setting up BIND9 for Internal DNS on RHEL9 #
This guide covers setting up BIND9/named for internal reverse/forward DNS resolution on a RHEL9 server. Unlike public authoritative DNS servers, internal DNS servers provide recursive resolution for your internal network and handle local domain queries.
All IP addresses, network ranges, and hostnames in this guide are examples. Replace them with your actual values.
For the entirety of the guide we’ll be running every single command as root.
All the commands are intended only for RPM and dnf/yum based systems such as Red Hat, Fedora, CentOS etc.
Installation #
Installing BIND9 #
# Install BIND9 and utilities
dnf install bind bind-utils
# Start and enable the service
systemctl start named
systemctl enable named
# Check the service status
systemctl status named
Firewall Configuration #
Open the necessary ports for DNS services:
# Allow DNS traffic on both UDP and TCP
firewall-cmd --permanent --add-port=53/udp
firewall-cmd --permanent --add-port=53/tcp
# Reload firewall rules
firewall-cmd --reload
# Verify the configuration
firewall-cmd --list-all
Network Planning #
For this internal DNS setup, I’m using the following network configuration:
- Internal network: 192.168.1.0/24
- DNS servers:
- Primary: 192.168.1.10 (dns01.domain.corp)
- Secondary: 192.168.1.11 (dns02.domain.corp)
- Internal domain: domain.corp
Main Configuration File #
The main BIND9 configuration file is /etc/named.conf. Here’s a complete internal DNS configuration:
//
// BIND9 Internal DNS Configuration
// Recursive DNS server for internal network
//
options {
// Listen on specific interfaces
listen-on port 53 { 127.0.0.1; 192.168.1.10; };
// Directory for zone files
directory "/var/named";
// Log and statistics files
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";
// Allow queries from anyone (adjust for your security needs)
allow-query { any; };
// Enable recursion for internal clients
recursion yes;
allow-recursion { 192.168.1.0/24; localhost; };
// Security settings
version "not currently available";
allow-transfer { none; };
// Disable DNSSEC validation for internal zones
dnssec-validation no;
// Enable query logging
querylog yes;
// Process and key file locations
managed-keys-directory "/var/named/dynamic";
pid-file "/run/named/named.pid";
session-keyfile "/run/named/session.key";
// Include system crypto policies
include "/etc/crypto-policies/back-ends/bind.config";
};
// Logging configuration
logging {
channel default_debug {
file "data/named.run";
severity dynamic;
};
channel zone_transfer_log {
file "data/transfer.log" versions 10 size 50m;
print-time yes;
print-category yes;
print-severity yes;
severity info;
};
// Log zone transfers
category notify { zone_transfer_log; };
category xfer-in { zone_transfer_log; };
category xfer-out { zone_transfer_log; };
};
// Root zone
zone "." IN {
type hint;
file "named.ca";
};
// Include default zones
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
// Forward zone for internal domain
zone "domain.corp" {
type master;
file "/var/named/domain.corp";
allow-transfer { 192.168.1.11; }; // Allow secondary DNS
allow-query { 192.168.1.0/24; 127.0.0.1; };
};
// Reverse zone for internal network
zone "1.168.192.in-addr.arpa" {
type master;
file "/var/named/1.168.192.in-addr.arpa";
allow-transfer { 192.168.1.11; }; // Allow secondary DNS
allow-query { 192.168.1.0/24; 127.0.0.1; };
};
Zone Files #
Forward Zone (domain.corp) #
Create /var/named/domain.corp:
$ORIGIN domain.corp.
$TTL 3600
@ IN SOA dns01.domain.corp. admin.domain.corp. (
2025070301 ; serial (YYYYMMDDNN format)
21600 ; refresh after 6 hours
3600 ; retry after 1 hour
1209600 ; expire after 2 weeks
86400 ) ; minimum TTL of 1 day
IN NS dns01.domain.corp.
IN NS dns02.domain.corp.
; Network infrastructure
gateway IN A 192.168.1.1 ; Gateway/Router
switch01 IN A 192.168.1.2 ; Network Switch 1
switch02 IN A 192.168.1.3 ; Network Switch 2
firewall IN A 192.168.1.4 ; Firewall
; DNS Servers
dns01 IN A 192.168.1.10 ; Primary DNS
dns02 IN A 192.168.1.11 ; Secondary DNS
; Domain Controllers
dc01 IN A 192.168.1.20 ; Domain Controller 1
dc02 IN A 192.168.1.21 ; Domain Controller 2
; Servers
fileserver IN A 192.168.1.30 ; File Server
mailserver IN A 192.168.1.31 ; Mail Server
webserver IN A 192.168.1.32 ; Web Server
dbserver IN A 192.168.1.33 ; Database Server
appserver IN A 192.168.1.34 ; Application Server
backupserver IN A 192.168.1.35 ; Backup Server
printserver IN A 192.168.1.36 ; Print Server
monitoring IN A 192.168.1.37 ; Monitoring Server
proxy IN A 192.168.1.38 ; Proxy Server
jumphost IN A 192.168.1.39 ; Jump Host
; Workstations
ws001 IN A 192.168.1.100 ; Workstation 001
ws002 IN A 192.168.1.101 ; Workstation 002
ws003 IN A 192.168.1.102 ; Workstation 003
; CNAME records for aliases
mail IN CNAME mailserver.domain.corp.
web IN CNAME webserver.domain.corp.
db IN CNAME dbserver.domain.corp.
files IN CNAME fileserver.domain.corp.
backup IN CNAME backupserver.domain.corp.
Reverse Zone (1.168.192.in-addr.arpa) #
Create /var/named/1.168.192.in-addr.arpa:
$ORIGIN 1.168.192.in-addr.arpa.
$TTL 3600
@ IN SOA dns01.domain.corp. admin.domain.corp. (
2025070301 ; serial (YYYYMMDDNN format)
21600 ; refresh after 6 hours
3600 ; retry after 1 hour
1209600 ; expire after 2 weeks
86400 ) ; minimum TTL of 1 day
IN NS dns01.domain.corp.
IN NS dns02.domain.corp.
; PTR records for reverse lookups
; Network infrastructure
1 IN PTR gateway.domain.corp.
2 IN PTR switch01.domain.corp.
3 IN PTR switch02.domain.corp.
4 IN PTR firewall.domain.corp.
; DNS Servers
10 IN PTR dns01.domain.corp.
11 IN PTR dns02.domain.corp.
; Domain Controllers
20 IN PTR dc01.domain.corp.
21 IN PTR dc02.domain.corp.
; Servers
30 IN PTR fileserver.domain.corp.
31 IN PTR mailserver.domain.corp.
32 IN PTR webserver.domain.corp.
33 IN PTR dbserver.domain.corp.
34 IN PTR appserver.domain.corp.
35 IN PTR backupserver.domain.corp.
36 IN PTR printserver.domain.corp.
37 IN PTR monitoring.domain.corp.
38 IN PTR proxy.domain.corp.
39 IN PTR jumphost.domain.corp.
; Workstations
100 IN PTR ws001.domain.corp.
101 IN PTR ws002.domain.corp.
102 IN PTR ws003.domain.corp.
Configuration Validation #
Syntax Validation #
Always validate your configuration before restarting the service:
# Check named.conf syntax
named-checkconf /etc/named.conf
# Check individual zone files
named-checkzone domain.corp /var/named/domain.corp
named-checkzone 1.168.192.in-addr.arpa /var/named/1.168.192.in-addr.arpa
Restart Service #
# Restart BIND9
systemctl restart named
# Check service status
systemctl status named
# View recent logs
journalctl -u named -f
DNS Testing #
Test your DNS configuration:
# Test local resolution
dig @127.0.0.1 domain.corp NS
dig @127.0.0.1 dns01.domain.corp A
# Test reverse resolution
dig @127.0.0.1 -x 192.168.1.10
# Test specific records
dig @127.0.0.1 www.domain.corp A
dig @127.0.0.1 mail.domain.corp A
Secondary DNS Server Setup #
For redundancy, configure a secondary DNS server:
Note: Complete the installation and firewall configuration steps on the secondary server (192.168.1.11) before proceeding.
On Secondary Server #
# Add zone configurations to named.conf
zone "domain.corp" {
type slave;
file "/var/named/slaves/domain.corp";
masters { 192.168.1.10; };
};
zone "1.168.192.in-addr.arpa" {
type slave;
file "/var/named/slaves/1.168.192.in-addr.arpa";
masters { 192.168.1.10; };
};
Create Slaves Directory #
# Create directory for slave zone files
mkdir -p /var/named/slaves
chown named:named /var/named/slaves
chmod 755 /var/named/slaves
Client Configuration #
Configure your clients to use your DNS server:
Linux #
Edit /etc/resolv.conf:
nameserver 192.168.1.10
nameserver 192.168.1.11
search domain.corp
Troubleshooting Common Issues #
DNS Not Resolving #
# Check if BIND9 is running
systemctl status named
# Check listening ports
netstat -tulnp | grep :53
# Test local resolution
dig @127.0.0.1 domain.corp NS
# Check firewall
firewall-cmd --list-ports