Configuring & Changing Setting in DNS server on Linux
— ny_wk

To configure a DNS server on Linux you install BIND (the named daemon), define your zones in /etc/named.conf, write forward and reverse zone files with SOA, NS, A and PTR records, then validate, start, and open the firewall on port 53. This guide walks through a complete, working name server on a modern RHEL, Rocky, AlmaLinux, or CentOS Stream box, then shows how to point any Linux client at it.
A DNS server on Linux turns human-friendly names like www.example.com into IP addresses such as 192.168.10.2, and back again. The Domain Name System is the directory service of the internet: instead of memorizing numeric addresses for every host you visit, you remember a name, and a resolver looks up the address for you. BIND (the Berkeley Internet Name Domain) is the most widely deployed implementation of that service, and its daemon is called named. By the end of this walkthrough you will have an authoritative name server that answers both forward and reverse queries for your own internal domain.
The problem: names vs. numbers
Every host on a network is reachable by an IP address, for example 192.168.10.2. Numbers are easy for machines but hard for people. Think of DNS as a phone book: you want "Joe's Bookstore," you look it up, and the directory tells you it sits at 123 Main Street. DNS does the same thing for hosts, mapping a fully qualified domain name (FQDN) to an address. Two lookups matter:
- Forward lookup — name to IP (an
Arecord for IPv4,AAAAfor IPv6). - Reverse lookup — IP to name (a
PTRrecord, stored in a specialin-addr.arpazone).
Running your own internal DNS gives you fast, private name resolution for a LAN, a lab, or a server fleet without leaking internal hostnames to the public internet.
The solution: BIND and the named daemon
BIND ships in every major Linux distribution. The core pieces you will touch are:
/etc/named.conf— the main configuration file: global options, logging, and azonestanza per domain.- Zone files in
/var/named/— the actual records (SOA, NS, A, PTR) for each zone. rndc— the remote name daemon control utility for reloading and managingnamed.named-checkconfandnamed-checkzone— validators that catch syntax errors before they take the server down.
The example below uses the domain example.lan and a server at 192.168.10.2. Substitute your own domain and addressing throughout.
Test scenario
| Item | Value |
| Operating system | RHEL 9 / Rocky 9 / AlmaLinux 9 (works on 8 too) |
| Server IP | 192.168.10.2 / 24 |
| Server hostname | ns1.example.lan |
| Domain (forward zone) | example.lan |
| Reverse zone | 10.168.192.in-addr.arpa |
| Client host | client.example.lan = 192.168.10.10 |
Step 1: Install BIND
On modern Red Hat-family systems use dnf (older releases used yum; the syntax is identical):
- Install the server and its utilities:
sudo dnf install -y bind bind-utils - Confirm the package and binary version:
named -v
On Debian or Ubuntu the package is named differently: sudo apt install -y bind9 bind9-utils dnsutils, the config lives under /etc/bind/, and the service is named (aliased as bind9). The concepts that follow are the same; only the paths change.
Step 2: Configure /etc/named.conf
Edit the main configuration file:
sudo vim /etc/named.conf
In the options block, tell named which addresses to listen on and which clients may query it. The stock file listens only on 127.0.0.1, which means nothing on your LAN can reach it — widen it:
options {
listen-on port 53 { 127.0.0.1; 192.168.10.2; };
listen-on-v6 port 53 { ::1; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
allow-query { localhost; 192.168.10.0/24; };
allow-transfer { none; };
recursion yes;
dnssec-validation auto;
};
A few notes on these directives:
allow-queryrestricts who may ask questions. Limit it to your LAN subnet so the server is not an open resolver exposed to the internet.recursion yeslets the server resolve names it is not authoritative for (good for an internal resolver). If this box should only answer for its own zones, setrecursion noto avoid being abused in amplification attacks.allow-transfershould benoneunless you run a secondary (slave) server, in which case list only that secondary's IP.dnssec-validation autois the modern, correct setting. The olddnssec-enableanddnssec-lookasideoptions were removed in BIND 9.16+ and will causenamedto refuse to start if you copy them from an old tutorial.
Set up forwarders (optional but recommended)
A forwarder tells your server to hand off any query it cannot answer locally to an upstream resolver instead of walking the root servers itself. This speeds up resolution and works well behind firewalls. Add this inside the options block:
forwarders { 1.1.1.1; 8.8.8.8; };
forward only;
forward only means "never try to resolve directly, always use the forwarders"; forward first tries the forwarders and falls back to recursion. With recursion yes and a cache, your server now doubles as a fast caching resolver for the LAN.
Declare the zones
At the end of /etc/named.conf (or in the included /etc/named.rfc1912.zones file), add one stanza for the forward zone and one for the reverse zone:
zone "example.lan" IN {
type master;
file "example.lan.forward";
allow-update { none; };
};
zone "10.168.192.in-addr.arpa" IN {
type master;
file "example.lan.reverse";
allow-update { none; };
};
Note the reverse zone name: the network 192.168.10.0/24 becomes 10.168.192.in-addr.arpa — the first three octets reversed, with .in-addr.arpa appended. This trips up many beginners, so write it out carefully.
Before going further, validate the configuration syntax:
sudo named-checkconf
No output means the file is syntactically valid. Fix any reported errors before continuing.
Step 3: Build the forward zone file
Create /var/named/example.lan.forward. This file maps names to addresses:
$TTL 1D
@ IN SOA ns1.example.lan. admin.example.lan. (
2026062801 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
@ IN NS ns1.example.lan.
ns1 IN A 192.168.10.2
client IN A 192.168.10.10
Reading the records:
$TTLsets the default time-to-live (how long resolvers may cache answers).SOA(Start of Authority) names the primary server and the admin contact. The contactadmin.example.lan.is an email address with the@replaced by a dot — it meansadmin@example.lan. The trailing dots make these names fully qualified; omitting a trailing dot causes BIND to append the zone name, a classic source of mangled records.- The serial uses the
YYYYMMDDnnconvention. You must increase this number every time you edit the file, or secondaries (and your own reloads) will ignore the changes. NSdeclares the authoritative name server for the zone.Arecords map a hostname to an IPv4 address. UseAAAAfor IPv6.
Step 4: Build the reverse zone file
Create /var/named/example.lan.reverse. This file maps addresses back to names using PTR records:
$TTL 1D
@ IN SOA ns1.example.lan. admin.example.lan. (
2026062801 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
@ IN NS ns1.example.lan.
2 IN PTR ns1.example.lan.
10 IN PTR client.example.lan.
The number on the left of each PTR line is the final octet of the host's address. Because the zone is 10.168.192.in-addr.arpa, the bare 2 expands to 2.10.168.192.in-addr.arpa, which is 192.168.10.2. The right-hand name must end in a trailing dot so it is treated as fully qualified. Every host you give an A record in the forward zone should normally get a matching PTR here.
Step 5: Permissions, SELinux, and validation
BIND runs as the unprivileged named user, so it must be able to read its zone files. Set the group and tighten the mode:
- Set ownership so
namedcan read the files:sudo chown root:named /var/named/example.lan.forward /var/named/example.lan.reverse - Restrict the mode:
sudo chmod 640 /var/named/example.lan.forward /var/named/example.lan.reverse - Restore SELinux context (essential on RHEL-family systems, or
namedis denied access):sudo restorecon -Rv /var/named - Validate each zone file — this catches missing dots, bad serials, and typos before a restart:
sudo named-checkzone example.lan /var/named/example.lan.forwardsudo named-checkzone 10.168.192.in-addr.arpa /var/named/example.lan.reverse
A healthy zone prints OK and the loaded serial. If SELinux is in enforcing mode and you skip restorecon, named will fail to load the zones with permission-denied errors even though the file modes look correct — check with sudo ausearch -m avc -ts recent if something refuses to load.
Step 6: Start, enable, and open the firewall
Modern Linux uses systemd to manage services and firewalld for the firewall. The old service named start and chkconfig named on commands are deprecated; use:
- Start the daemon now and enable it at boot:
sudo systemctl enable --now named - Confirm it is running:
sudo systemctl status named - Open DNS in the firewall (port 53, both TCP and UDP):
sudo firewall-cmd --permanent --add-service=dnssudo firewall-cmd --reload
After editing a zone later, you do not need a full restart — bump the serial, then reload with rndc:
- Reload everything:
sudo rndc reload - Reload a single zone:
sudo rndc reload example.lan - Flush the cache after a record change:
sudo rndc flush
DNS listens on both UDP and TCP port 53 — UDP for ordinary queries and TCP for large responses and zone transfers — so make sure both are allowed (the dns service handles both).
Common pitfalls to avoid
- Forgetting to bump the serial. If you edit a zone but leave the serial unchanged,
namedserves the old data and secondaries never sync. Increment it on every edit. - Missing trailing dots. A name without a trailing dot gets the zone name appended, turning
ns1.example.lanintons1.example.lan.example.lan. Always end FQDNs with a dot in zone files. - SELinux and permissions. Wrong ownership or a stale SELinux context silently blocks
namedfrom reading zone files. Runchown root:namedandrestorecon -Rv /var/named. - Glue records. When a zone's name servers live inside that same zone, the parent must publish
Arecords (glue) for them, or resolvers cannot find the server that holds the zone. For internal labs this matters once you delegate subdomains. - Copying obsolete options.
dnssec-enable,dnssec-lookaside, andbindkeys-filewere removed in current BIND. Leaving them innamed.confstops the daemon from starting —named-checkconfwill flag them. - Open resolver. Leaving
allow-query { any; }with recursion enabled on a public-facing box turns your server into a tool for DNS amplification attacks. Scope queries to your LAN.
Verify your DNS server
Use dig (from bind-utils) to test against the server directly. The @192.168.10.2 argument forces the query to your new server:
- Forward lookup:
dig @192.168.10.2 client.example.lan
Look forstatus: NOERRORand anANSWER SECTIONshowingclient.example.lan. ... A 192.168.10.10. - Reverse lookup:
dig @192.168.10.2 -x 192.168.10.2
The answer should be aPTRpointing tons1.example.lan. - Quick check with nslookup (also handy on Windows clients):
nslookup client.example.lan 192.168.10.2 - Tail the log if a query fails:
sudo journalctl -u named -f
The presence of the aa flag in dig output means the answer is authoritative — proof your server owns the zone.
Point a Linux client at your new server
A client decides which resolvers to use from /etc/resolv.conf. Each nameserver line lists one DNS server by IP address, tried in order. Use IP addresses, never names — the system cannot resolve a name until it already knows how to reach a resolver.
- Edit the file:
sudo nano /etc/resolv.conf - Add your server (and a public fallback):
search example.lannameserver 192.168.10.2nameserver 1.1.1.1 - Test resolution:
ping -c 3 client.example.lan
On systems managed by NetworkManager or systemd-resolved, /etc/resolv.conf is regenerated automatically and your hand edits may be overwritten on reboot. Set the DNS server on the connection instead, for example:
sudo nmcli con mod "System eth0" ipv4.dns "192.168.10.2"
sudo nmcli con up "System eth0"
If you also run IPv6, add the server's IPv6 address as another nameserver line and test with ping6 instead of ping. You can discover whether an upstream resolver has an IPv6 address with host <name>, which reports any AAAA record alongside the A record.
Key Takeaways
- Install BIND with
dnf install bind bind-utils, then drive everything through/etc/named.confand the zone files in/var/named/. - Every zone needs an SOA, at least one NS, plus A/PTR records — and you must increment the SOA serial on every edit.
- Validate before you reload using
named-checkconfandnamed-checkzone; they catch the errors that otherwise crashnamed. - Use modern tooling:
systemctl enable --now named,firewall-cmd --add-service=dns, andrndc reload— and drop the removeddnssec-enable/dnssec-lookasideoptions. - Watch SELinux, file permissions, and trailing dots; these three issues account for most "my zone won't load" problems.
Frequently Asked Questions
What is the difference between a forward and a reverse zone?
A forward zone holds A/AAAA records that map names to IP addresses, so a query for client.example.lan returns an address. A reverse zone lives under in-addr.arpa and holds PTR records that map an IP address back to a name, which mail servers and logging tools rely on. You typically maintain both, with one matching the other.
Why won't named start after I edit named.conf?
The most common causes are a syntax error or an obsolete directive copied from an old guide (such as dnssec-enable or dnssec-lookaside, removed in BIND 9.16+). Run sudo named-checkconf to pinpoint the line, then check sudo journalctl -u named -f for the exact failure.
How do I apply zone changes without restarting the server?
Increment the SOA serial in the zone file, run named-checkzone to validate it, then run sudo rndc reload <zone>. The rndc utility reloads only what changed, with no downtime, and sudo rndc flush clears cached answers if needed.
Is my DNS server safe to expose to the internet?
Not by default. Keep allow-query scoped to your LAN and set recursion no (or restrict recursion) on any public-facing authoritative server, otherwise it can be abused in DNS amplification attacks. An internal resolver with recursion should never be reachable from the public internet.
Want more hands-on Linux and self-hosting walkthroughs? Subscribe to @explorenystream on YouTube.