LPIC-2 DNS: BIND Server, Zone Files, and Securing DNS
- Describe how BIND's `named` daemon loads zones from `named.conf` and validate a config before reloading
- Author a forward zone with a correct SOA, NS records, and the trailing dots that make or break it
- Build a reverse zone with PTR records in the in-addr.arpa namespace
- Harden an authoritative server: restrict queries and recursion, lock transfers with TSIG, and reason about views, chroot, and DNSSEC
Why DNS needs an authoritative server
Frame BIND as the program that answers the question 'what is the IP for this name?' and meet the daemon and its config.
Every time someone types
www.example.com, something has to translate that name into an IP address a packet can be routed to. DNS is that translation layer, and an authoritative server is the system that holds the official answers for a domain you own.Think of DNS as a giant, distributed phone book. You look people up by name and get back a number. An authoritative server is the publisher of one section of that book — you are responsible for the
example.compages, and the rest of the world trusts your pages for those names.On Linux, the classic authoritative (and recursive) server is BIND. The piece that actually runs is the daemon `named` ("name daemon"). You tell
namedwhat domains it is responsible for in its main config file, `named.conf`, which in turn points at zone files — one per domain — that hold the actual records.Example — not runnable on your lab box
grep -n 'zone' /etc/named.conf31:zone "example.com" IN { 32: type master; 33: file "/var/named/example.com.zone"; 34:};- -n
- Prefix each match with its line number, so you can jump straight to the block in an editor.
This is the definition half. The zone "example.com"block says "I am authoritative for example.com",type master;means this server holds the primary, editable copy, andfilepoints at the zone file that holds the records. On Debian the path is often/etc/bind/named.conf.localinstead of/etc/named.conf, but the block looks the same.Validate before you reload
Catch config and zone-file mistakes with the checker tools instead of with a crashed daemon.
Here is the operations golden rule applied to DNS: never reload a config you haven't checked. A single typo in
named.confcan stopnamedfrom starting at all, and a broken zone file can leave a whole domain unresolvable. BIND ships two checkers precisely so you can fail on your terminal instead of in production.named-checkconfparsesnamed.conf(and the files it includes) for syntax errors.named-checkzoneparses one zone file and verifies it actually makes sense for its origin.
Example — not runnable on your lab box
named-checkconfLike many Unix tools, silence is success — no output means named.confparsed cleanly. If there were an error it would print the file, line number, and what it choked on. Run this every time before reloading; it costs a second and saves an outage.Example — not runnable on your lab box
named-checkzone example.com /var/named/example.com.zonezone example.com/IN: loaded serial 2026062301 OK
- example.com
- The zone's ORIGIN — the name records are relative to. The checker uses it to expand any non-dotted names.
- /var/named/example.com.zone
- The zone file to parse. Same file the matching named.conf block points at.
The first argument is the origin (the domain), the second is the file. loaded serial 2026062301echoes the SOA serial it read, and `OK` is your green light. If the SOA or an NS record were missing, or a name had a bad trailing dot, this is where you'd find out — by name and line — before any client ever queried.Once both checks pass, you make
namedpick up the change. The control utility is `rndc` (Remote Name Daemon Control), and the verb isreload.Example — not runnable on your lab box
sudo rndc reload example.comzone reload up-to-date
- reload
- Re-read zone files from disk without restarting the whole daemon. Naming a zone reloads just that zone.
- reconfig
- Re-read named.conf for ADDED or REMOVED zones without reloading every existing zone — use when you add a new zone block.
rndc reloadtells the running daemon to re-read zone data — nosystemctl restart, no dropped service. Reaching for a full restart whenreloadwould do is a common over-correction; reserve restarts for changesnamedonly reads at startup, like options blocks it can't hot-apply.Check yourself
Which command parses a single zone file against its origin to confirm it has a valid SOA and NS before you reload?
The SOA and NS: every zone's spine
Read an SOA record, understand why the serial must be bumped on every edit, and see what NS records declare.
Two record types are mandatory in every zone. The SOA (Start of Authority) is the zone's header: it names the primary server, the admin contact, and the timers that govern how secondary (slave) servers stay in sync. At least one NS (Name Server) record then lists the servers that are authoritative for the zone.
The single field that causes the most real-world grief is the SOA serial number. Treat it like the edition number on a printed book: a slave only knows it has the latest data by comparing edition numbers. If you change the contents but leave the edition number the same, every slave looks at its copy, sees a matching number, and concludes "I'm already up to date" — so your edits never propagate.
Example — not runnable on your lab box
head -n 10 /var/named/example.com.zone$TTL 86400 @ IN SOA ns1.example.com. admin.example.com. ( 2026062301 ; serial (YYYYMMDDnn) 3600 ; refresh (how often slaves check) 900 ; retry (wait after a failed check) 1209600 ; expire (give up serving if primary unreachable) 86400 ) ; minimum (negative-answer cache TTL) @ IN NS ns1.example.com. @ IN NS ns2.example.com.- $TTL 86400
- Default time-to-live (seconds) resolvers may cache records from this zone.
- @
- Shorthand for the zone origin itself (example.com.). Saves retyping the domain on every line.
- admin.example.com.
- The admin email, with the first dot standing in for @ — so this means admin@example.com.
Read the SOA top to bottom: primary server ns1.example.com., contactadmin@example.com, then the serial2026062301(date-based: 23 June 2026, edit 01), then the slave timers. The two NS lines below declare thatns1andns2are the authoritative servers. Note the trailing dots on every fully-qualified name — the next step explains why they are not optional.Check yourself
You change an A record on the primary and reload, but slave servers still return the old IP for two days. What did you most likely forget?
Trailing dots and forward-zone records
Author the resolving records — A, AAAA, CNAME, MX — and avoid the classic missing-dot bug.
A forward zone answers the common question — name to address — and uses a small set of record types:
- A maps a name to an IPv4 address.
- AAAA maps a name to an IPv6 address.
- CNAME makes one name an alias for another name.
- MX names the mail server(s) for the domain, with a preference number.
The rule that bites everyone at least once: in a zone file, a name without a trailing dot is treated as relative to the origin, and BIND appends the zone name to it.
wwwbecomeswww.example.com.— which you want. Butmail.example.comwithout a trailing dot becomesmail.example.com.example.com.— which you very much do not.Example — not runnable on your lab box
tail -n 6 /var/named/example.com.zonewww IN A 192.0.2.10 web IN AAAA 2001:db8::10 ftp IN CNAME www.example.com. shop IN CNAME www @ IN MX 10 mail.example.com. mail IN A 192.0.2.20
- www IN A 192.0.2.10
- Relative name 'www' (no dot) expands to www.example.com. and resolves to the doc-range IPv4 192.0.2.10.
- ftp IN CNAME www.example.com.
- Fully-qualified target WITH trailing dot — ftp.example.com is an alias for www.example.com.
- @ IN MX 10 mail.example.com.
- Mail for the apex domain goes to mail.example.com.; 10 is the preference (lower = preferred).
Notice the two CNAME styles. ftppoints atwww.example.com.with the dot — an absolute target.shoppoints at barewww, which BIND expands relative to the origin towww.example.com.— also correct here because the target is inside this zone. The MX targetmail.example.com.carries the dot because it is an absolute name; the10is its preference. Every address uses the 192.0.2.0/24 documentation range, reserved exactly so examples never collide with real hosts.Check yourself
In a zone file for example.com you write
web IN CNAME host.example.orgwith no trailing dot. What name does BIND actually store as the target?Reverse zones: PTR and in-addr.arpa
Map IP addresses back to names with PTR records in a reversed in-addr.arpa zone.
Forward DNS answers name to address. Reverse DNS answers the opposite — address to name — which mail servers and logging tools use to ask "who actually owns this IP?". Reverse lookups live in a special namespace, `in-addr.arpa` for IPv4, and they use one record type: PTR (pointer).
The twist that confuses everyone: the IP is written backwards. For the network
192.0.2.0/24, the reverse zone is2.0.192.in-addr.arpa. Why reversed? DNS gets more specific as you read right to left (.comthenexamplethenwww), but IP addresses get more specific left to right. Reversing the octets lines the IP up with the DNS hierarchy so the network prefix sits at the top, just like a domain suffix does.Example — not runnable on your lab box
cat /var/named/2.0.192.in-addr.arpa.zone$TTL 86400 @ IN SOA ns1.example.com. admin.example.com. ( 2026062301 3600 900 1209600 86400 ) @ IN NS ns1.example.com. 10 IN PTR www.example.com. 20 IN PTR mail.example.com.- 10 IN PTR www.example.com.
- The bare '10' is the host octet; it expands against the origin 2.0.192.in-addr.arpa to 10.2.0.192.in-addr.arpa, i.e. the reverse of 192.0.2.10.
- PTR www.example.com.
- Points the address back to a name. The target is fully qualified — note the trailing dot, mandatory here as in any zone.
This reverse zone still needs its own SOA and NS, exactly like a forward zone — they are not optional just because it's reverse. The 10 IN PTR www.example.com.line says "the address ending in .10 belongs to www.example.com", reversing the forwardwww IN A 192.0.2.10you wrote earlier. Forward and reverse are separate zones you maintain by hand; an A record does not auto-create its PTR.Check yourself
What is the reverse-zone name for the IPv4 network 192.0.2.0/24?
Harden the server
Lock down who can query, recurse, and transfer — and place views, chroot, and DNSSEC in the threat model.
A working server is not a safe server. An authoritative BIND on the public internet is a target, and the defaults are deliberately permissive. Hardening is about answering only the questions you should, to only the people who should ask:
- `allow-query` — who may ask this server anything at all.
- `recursion` — whether this server will chase down answers for names it isn't authoritative for. An authoritative server should almost always say no.
- `allow-transfer` — who may pull an entire copy of a zone (a zone transfer, AXFR). Lock this to your real slaves, authenticated with a TSIG key.
Example — not runnable on your lab box
grep -nE 'allow-query|recursion|allow-transfer' /etc/named.conf12: recursion no; 13: allow-query { any; }; 34: allow-transfer { key "xfer-key"; };- -n
- Show line numbers so you can locate each directive in the file.
- -E
- Extended regex, so the | alternation matches any of the three directive names in one pass.
Read as a policy: `recursion no` means this box refuses to resolve arbitrary names for strangers — it only answers for its own zones. `allow-query { any; }` is fine for a public authoritative server (the world must be able to look up your domain). `allow-transfer { key "xfer-key"; }` restricts full-zone copies to clients holding the TSIG key named xfer-key, not just to an IP that can be spoofed.Three more defenses round out the LPIC-2 picture:
- Views serve different answers to different clients from one daemon — internal users see private RFC 1918 addresses, the internet sees public ones. This is split-horizon DNS, and it's how you avoid leaking internal hostnames.
- chroot runs
namedinside a restricted directory tree so that even if the daemon is compromised, the attacker is boxed into a fake filesystem root and can't reach the rest of the host. - DNSSEC signs your zones cryptographically so resolvers can verify an answer really came from you and wasn't forged in transit — defending against cache poisoning, which TSIG (server-to-server auth) does not address.
Check yourself
Which single named.conf setting most directly prevents your authoritative server from becoming an open resolver usable in amplification attacks?
Try it in your live terminal
Run safe, read-only DNS checks yourself on the sandbox to your right.
You have a real shell. These commands are all read-only — they query DNS and check config, they never modify a zone. Run them in order. Lab boxes have no internet access, so a public name like example.com cannot resolve here: you will see what a failed lookup looks like in
dig, and how the system resolver can still answer from/etc/hostswhen DNS can't. There may not be a BIND server here either; the goal is to make the moves reflexive so they're automatic when you're staring at a broken zone in the exam or in production.grep nameserver /etc/resolv.confWhich server will dig(and every other program) ask? Thenameserverlines, tried in order. Check this first whenever names stop resolving: a lookup can only be as good as the server it goes to.dig example.com +time=2 +tries=1; echo "dig exit code: $?"Ask that server for example.com's A record, giving up after 2 seconds. On this box the query cannot get an answer from the internet, so expect one of two failures: a reply whose header says status: SERVFAIL(orREFUSED) with no ANSWER SECTION, or no reply at all, which printsno servers could be reachedand exits 9. On a connected host you would seestatus: NOERRORand an A record. Read thestatus:field, not just the exit code: dig exits 0 for any reply, even a failed one.dig +short example.com +time=2 +tries=1The same query with +short, which strips everything but the answer. When the lookup works, that is the fastest 'what does this name resolve to?' check (dig SOA <zone> +shortgives a zone's serial and timers on one line the same way). Here it prints nothing, or only a;;error line. That is the trap: empty+shortoutput does not mean the name has no record. It can mean the lookup failed, so drop+shortand read the status before you conclude anything.named-checkconf 2>/dev/null && echo OK || echo 'no bind'If BIND is installed, this validates named.conf and prints OK on success; if named-checkconfisn't present, the||branch prints 'no bind' instead of an error. A safe way to probe for a working BIND install.getent hosts localhost "$(hostname)"; echo "--- example.com ---"; getent hosts example.com; echo "getent exit code: $?"Resolve names through the system's full resolver stack (nsswitch: /etc/hosts, then DNS) instead of DNS alone.localhostand this box's own hostname both answer, from/etc/hosts, even though DNS just failed. example.com has no/etc/hostsentry, so getent falls through to DNS, prints nothing and exits 2 (not found). That is whygetentanddigcan disagree: dig only ever asks the nameserver, while getent shows what the operating system sees,/etc/hostsoverrides included.
- BIND's daemon is
named; declare zones innamed.conf, then alwaysnamed-checkconf+named-checkzoneBEFORErndc reload. - Every zone needs an SOA and at least one NS. Bump the SOA serial on every single edit or slaves never update.
- Fully-qualified names in zone files need a trailing dot; omit it and BIND appends the origin (host.example.com → host.example.com.example.com).
- Forward zones resolve names (A/AAAA/CNAME/MX); reverse zones resolve IPs (PTR) in a reversed in-addr.arpa zone, maintained separately.
- Harden by setting
recursion noon authoritative servers, restricting allow-query, locking allow-transfer with TSIG, and adding views, chroot, and DNSSEC.
| Record | Zone | Maps | Example |
|---|---|---|---|
SOA | Both | Zone header: primary, contact, serial, slave timers | @ IN SOA ns1.example.com. admin.example.com. (...) |
NS | Both | Names an authoritative server for the zone | @ IN NS ns1.example.com. |
A | Forward | Name → IPv4 address | www IN A 192.0.2.10 |
AAAA | Forward | Name → IPv6 address | web IN AAAA 2001:db8::10 |
CNAME | Forward | Name → another name (alias) | ftp IN CNAME www.example.com. |
MX | Forward | Domain → mail server (with preference) | @ IN MX 10 mail.example.com. |
PTR | Reverse | IP address → name (in-addr.arpa) | 10 IN PTR www.example.com. |
