DNS (Domain Name System) is one of the most critical internet infrastructure services — it translates human-readable hostnames into IP addresses. Without DNS, you would need to memorise IP addresses for every website and service. For RHCA, you must be able to configure a fully functional BIND DNS server, create forward and reverse zones, manage DNS records, and troubleshoot DNS resolution failures.
How DNS Works — The Complete Resolution Path
When you type www.google.com in your browser, a complex distributed lookup system springs into action. Understanding this is essential for DNS troubleshooting.
The DNS Hierarchy
Root Zone (.)
└── Top Level Domains (.com, .org, .net, .in, .uk)
└── Second Level Domains (google.com, redhat.com)
└── Subdomains (www.google.com, mail.google.com)
The DNS namespace is a tree. The root zone (.) is at the top, managed by ICANN. Each node in the tree delegates authority for subtrees to other name servers.
Resolution Step by Step
- Local cache check: Browser and OS check their local DNS cache. If the answer is cached (and not expired), query stops here.
- Hosts file: OS checks
/etc/hosts. If a match is found, that answer is used. (Controlled by/etc/nsswitch.conf— hosts order:hosts: files dns) - Recursive resolver (ISP/local DNS): If no local answer, OS sends query to the configured DNS server (from
/etc/resolv.conf). This is usually your ISP's resolver or an internal corporate DNS server. - Root name servers: If the recursive resolver doesn't have the answer cached, it asks a root name server (there are 13 root server clusters worldwide). The root server responds: "I don't know www.google.com, but the .com TLD servers are at these IPs."
- TLD name servers: The recursive resolver asks the .com TLD server. It responds: "I don't know www.google.com, but google.com is authoritative at ns1.google.com."
- Authoritative name server: The recursive resolver asks ns1.google.com directly. This is Google's own DNS server — it has the definitive answer: "www.google.com = 142.250.195.196".
- Cache and respond: The recursive resolver caches the answer (for the TTL duration) and returns it to the client.
Recursive vs Authoritative Servers
| Type | Function | Knows About | Example |
|---|---|---|---|
| Recursive (caching) resolver | Performs full lookup on behalf of clients, caches results | Everything (by querying authoritative servers) | 8.8.8.8, 1.1.1.1, your ISP |
| Authoritative name server | Provides definitive answers for specific zones | Only its own zones | ns1.google.com, your company BIND server |
DNS Record Types — Complete Reference
| Record | Full Name | Purpose | Example |
|---|---|---|---|
| SOA | Start of Authority | Zone admin info: primary NS, admin email, serial, refresh, retry, expire, minimum TTL | Required — one per zone |
| A | Address | Hostname → IPv4 address (forward lookup) | www A 192.168.1.10 |
| AAAA | IPv6 Address | Hostname → IPv6 address | www AAAA 2001:db8::1 |
| PTR | Pointer | IP address → Hostname (reverse lookup) | 10 PTR www.example.com. |
| NS | Name Server | Identifies authoritative DNS servers for a zone | example.com NS ns1.example.com. |
| MX | Mail Exchange | Mail server for domain (with priority) | example.com MX 10 mail.example.com. |
| CNAME | Canonical Name | Alias — maps one hostname to another hostname | www CNAME server9.example.com. |
| TXT | Text | Arbitrary text — used for SPF, DKIM, site verification | example.com TXT "v=spf1 mx ~all" |
| SRV | Service | Location of specific services (used by SIP, XMPP, Kerberos) | _kerberos._tcp SRV 0 5 88 kdc.example.com. |
The SOA Record in Detail
@ IN SOA ns1.example.com. admin.example.com. (
2026060701 ; Serial — YYYYMMDDNN format. MUST increment on every change.
; Slaves use this to detect zone updates.
3600 ; Refresh — seconds between slave checks for updates
900 ; Retry — seconds to wait if refresh fails
604800 ; Expire — seconds slave serves zone without successful refresh
300 ) ; Minimum TTL — default TTL for negative caching (NXDOMAIN)
BIND Configuration — Step by Step
named.conf Structure
# /etc/named.conf is the main BIND configuration file
# It consists of configuration statements ended by semicolons
options {
listen-on port 53 { 127.0.0.1; 192.168.1.11; }; # bind to these IPs
listen-on-v6 port 53 { ::1; };
directory "/var/named"; # zone files location
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
allow-query { localhost; 192.168.1.0/24; }; # who can query us
recursion yes; # allow recursive queries
allow-recursion { localhost; 192.168.1.0/24; }; # who can recurse
dnssec-enable yes;
dnssec-validation yes;
};
# Logging:
logging {
channel default_debug {
file "data/named.run";
severity dynamic;
};
};
# Include zone configuration:
include "/etc/named.rfc1912.zones";
Zone Configuration in named.rfc1912.zones
# Forward zone:
zone "example.com" IN {
type master; # this is the authoritative (master) server
file "named.forward"; # zone file in /var/named/
allow-update { none; }; # no dynamic updates
allow-transfer { 192.168.1.12; }; # allow zone transfer to slave
};
# Reverse zone (PTR records):
zone "1.168.192.in-addr.arpa" IN {
type master;
file "named.reverse";
allow-update { none; };
};
# Slave zone (receive zone from master):
zone "example.com" IN {
type slave;
masters { 192.168.1.11; }; # get zone from this master
file "slaves/named.forward";
};
Zone File — Forward Lookup Zone
# /var/named/named.forward
$TTL 86400 ; default TTL: 24 hours
; SOA record (note trailing dots on FQDNs):
@ IN SOA ns1.example.com. admin.example.com. (
2026060701 ; serial
3600 ; refresh
900 ; retry
604800 ; expire
300 ) ; minimum TTL
; Name servers:
@ IN NS ns1.example.com.
@ IN NS ns2.example.com. ; secondary NS (optional)
; A records (name → IP):
@ IN A 192.168.1.11 ; example.com itself
ns1 IN A 192.168.1.11 ; name server
ns2 IN A 192.168.1.12
server9 IN A 192.168.1.11
client9 IN A 192.168.1.10
client10 IN A 192.168.1.20
mail IN A 192.168.1.30
; CNAME (alias → canonical name, NOTE trailing dot):
www IN CNAME server9.example.com.
ftp IN CNAME server9.example.com.
; MX record (mail exchange with priority):
@ IN MX 10 mail.example.com. ; priority 10 (lower = preferred)
Zone File — Reverse Lookup Zone
# /var/named/named.reverse
$TTL 86400
@ IN SOA ns1.example.com. admin.example.com. (
2026060701 3600 900 604800 300 )
@ IN NS ns1.example.com.
; PTR records (last octet → FQDN, NOTE trailing dot):
11 IN PTR server9.example.com.
10 IN PTR client9.example.com.
20 IN PTR client10.example.com.
30 IN PTR mail.example.com.
File Permissions for Zone Files
# Zone files must be readable by the named daemon (runs as 'named' user):
# chown named:named /var/named/named.forward
# chown named:named /var/named/named.reverse
# chmod 640 /var/named/named.forward
# chmod 640 /var/named/named.reverse
# Or use ACL (xfs/ext4 with ACL support):
# setfacl -m u:named:r /var/named/named.forward
Validating and Starting BIND
# Validate main config:
# named-checkconf /etc/named.conf
# named-checkconf /etc/named.rfc1912.zones
# Validate zone files:
# named-checkzone example.com /var/named/named.forward
# named-checkzone 1.168.192.in-addr.arpa /var/named/named.reverse
# Success output: "zone example.com/IN: loaded serial 2026060701 OK"
# Any error must be fixed before starting
# Start and enable:
# systemctl start named
# systemctl enable named
# Reload zone files without restart (after zone file changes):
# systemctl reload named
# rndc reload # BIND management tool
# rndc reload example.com # reload specific zone only
DNS Client Configuration
# /etc/resolv.conf — DNS client configuration:
search example.com company.local # domain search suffixes (tried in order)
nameserver 192.168.1.11 # primary DNS server
nameserver 8.8.8.8 # fallback DNS server
# /etc/nsswitch.conf — controls lookup order:
hosts: files dns # check /etc/hosts first, then DNS
# files = /etc/hosts
# dns = use nameservers in /etc/resolv.conf
# myhostname = systemd-resolved (RHEL 7+)
# Configure via nmcli (RHEL 7+, changes survive reboot):
# nmcli con mod "System eth0" ipv4.dns "192.168.1.11 8.8.8.8"
# nmcli con mod "System eth0" ipv4.dns-search "example.com"
# nmcli con up "System eth0"
DNS Testing and Troubleshooting
# Test with dig (most powerful DNS tool):
# dig @192.168.1.11 server9.example.com # query specific server
# dig server9.example.com A # specific record type
# dig -x 192.168.1.11 # reverse lookup
# dig example.com NS # name server records
# dig example.com MX # mail exchange records
# dig example.com ANY # all records
# dig output analysis:
# ;; ANSWER SECTION: → the actual answer
# ;; AUTHORITY SECTION: → which server is authoritative
# ;; flags: qr aa rd ra → qr=query response, aa=authoritative answer
# ;; Query time: 5 msec → response time (should be <100ms for local)
# Test with nslookup (interactive):
# nslookup server9.example.com
# nslookup 192.168.1.11 # reverse lookup
# Test with host (simple):
# host server9.example.com # A record
# host -t mx example.com # MX records
# Check DNS propagation:
# dig @ns1.example.com example.com A # ask authoritative server
# dig @8.8.8.8 example.com A # ask external resolver
# Flush DNS cache:
# systemctl restart nscd # flush nscd cache (if using nscd)
# systemd-resolve --flush-caches # RHEL 7+ systemd-resolved
# BIND rndc commands:
# rndc status # server status
# rndc stats # write statistics to file
# rndc flush # flush all caches
# rndc flush example.com # flush specific zone from cache
# rndc dumpdb -cache # dump cache to file
Common DNS Problems and Solutions
| Symptom | Likely Cause | Solution |
|---|---|---|
| NXDOMAIN for existing host | Missing A record, wrong zone file, serial not incremented | Check zone file, increment serial, reload named |
| Reverse lookup fails | Missing PTR record, wrong reverse zone name | Add PTR record, verify zone name matches IP range |
| Named won't start | Config syntax error, zone file error, port 53 in use | named-checkconf, check journal, ss -tulnp |
| Clients can't resolve | Firewall blocking port 53, named not listening on right IP | Check firewall (UDP+TCP 53), check listen-on in named.conf |
| Stale records | Long TTL, cached old answer | Reduce TTL before changes, rndc flush to clear cache |