Table of Contents
Overview
This chapter focuses on installing and configuring BIND (Berkeley Internet Name Domain) as an authoritative and/or caching DNS server on Linux. Concepts like DNS basics, record types, and general terminology are assumed from the parent “DNS and DHCP” section; here we focus on the practical setup.
Most examples target a common scenario:
- Authoritative server for zone
example.com - Server IP:
192.0.2.53 - Using a typical Linux distribution layout (Debian/Ubuntu and RHEL/CentOS/Alma/Rocky notes where they differ)
Adjust paths, package names, and IPs to your environment.
Installing BIND
On most distributions, the BIND package is called bind9 or named:
- Debian/Ubuntu:
sudo apt update
sudo apt install bind9 bind9-utils- RHEL/CentOS/Alma/Rocky:
sudo dnf install bind bind-utilsKey components:
named— BIND daemonrndc— remote name daemon control tool- Configuration files — usually under
/etc/bind(Debian/Ubuntu) or/etc/named*(RHEL-based)
Common service name:
sudo systemctl enable --now named # RHEL-based
sudo systemctl enable --now bind9 # Debian/UbuntuCore Configuration Files
Typical files:
- Main configuration:
- Debian/Ubuntu:
/etc/bind/named.conf - RHEL-based:
/etc/named.conf - Included files (names vary):
named.conf.options— global options (listen, recursion, forwarders, etc.)named.conf.localornamed.conf.default-zones— local zones- Zone files:
- Often in
/var/named/(RHEL-based) or/etc/bind/(Debian/Ubuntu), or a subdirectory
The main file includes the others; you mostly edit the included files, not the base distro defaults.
Basic Global Configuration
Global settings control how BIND behaves as a server.
Example `named.conf` (RHEL-like layout)
Minimal example:
options {
directory "/var/named";
pid-file "/run/named/named.pid";
// Listen on IPv4 localhost and a specific external interface
listen-on port 53 { 127.0.0.1; 192.0.2.53; };
// Listen on IPv6 localhost (optional)
listen-on-v6 { ::1; };
// Restrict which clients may query this server
allow-query { localhost; 192.0.2.0/24; };
// Enable recursion only for trusted clients
recursion yes;
allow-recursion { localhost; 192.0.2.0/24; };
// Forward unknown queries to upstream resolvers (optional)
forwarders { 1.1.1.1; 8.8.8.8; };
// DNSSEC validation (modern default)
dnssec-validation auto;
};
// Include local zones
include "/etc/named.rfc1912.zones";
include "/etc/named.example-zones.conf";Key options:
directory— working directory for zone fileslisten-on/listen-on-v6— IPs/ports to bind toallow-query— who can make DNS queriesrecursion,allow-recursion— recursive-resolver behaviorforwarders— upstream DNS servers for recursive usednssec-validation— DNSSEC verification
On Debian/Ubuntu, similar settings often go in /etc/bind/named.conf.options.
Defining Zones
Zones describe authoritative data for domains.
Common types:
type master;— primary authoritative server (maintains zone file)type slave;— secondary authoritative server (gets data via zone transfers)type hint;— root hints (for recursive resolvers)
Authoritative Zone for `example.com`
Add to a local zones file (e.g. /etc/bind/named.conf.local or /etc/named.example-zones.conf):
zone "example.com" IN {
type master;
file "example.com.zone";
allow-transfer { 198.51.100.53; }; // example secondary server
};Here:
file "example.com.zone";is relative todirectoryset inoptions.allow-transfercontrols which hosts can perform zone transfers (AXFR/IXFR).
Reverse Zone
For reverse lookups of 192.0.2.0/24, add:
zone "2.0.192.in-addr.arpa" IN {
type master;
file "2.0.192.in-addr.arpa.zone";
allow-transfer { 198.51.100.53; };
};Reverse zone naming follows the in-addr.arpa / ip6.arpa scheme.
Creating Zone Files
Zone files contain the actual DNS records.
Forward Zone File Example
Create /var/named/example.com.zone (RHEL) or /etc/bind/db.example.com (Debian-style). Example BIND format:
$TTL 86400 ; default TTL (1 day)
@ IN SOA ns1.example.com. admin.example.com. (
2025010101 ; serial
3600 ; refresh (1 hour)
900 ; retry (15 minutes)
604800 ; expire (1 week)
86400 ; minimum (1 day)
)
IN NS ns1.example.com.
IN NS ns2.example.com.
ns1 IN A 192.0.2.53
ns2 IN A 198.51.100.53
; Web and mail
@ IN A 192.0.2.10
www IN CNAME @
mail IN A 192.0.2.20
IN MX 10 mail.example.com.
; Internal hosts
host1 IN A 192.0.2.101
host2 IN A 192.0.2.102Notes:
$TTL— default TTL for records without an explicit TTL.SOA— Start of Authority;ns1.example.com.is primary NS,admin.example.com.is contact email with@replaced by..serial— increment this for each change to the zone (formatYYYYMMDDnnis common).@— shorthand for the zone name (example.com.).- Use FQDNs with trailing dots for names in records like
NS,MX,CNAMEtargets.
Reverse Zone File Example
For 192.0.2.0/24, create /var/named/2.0.192.in-addr.arpa.zone:
$TTL 86400
@ IN SOA ns1.example.com. admin.example.com. (
2025010101 ; serial
3600
900
604800
86400
)
IN NS ns1.example.com.
IN NS ns2.example.com.
10 IN PTR example.com.
20 IN PTR mail.example.com.
53 IN PTR ns1.example.com.
101 IN PTR host1.example.com.
102 IN PTR host2.example.com.
Left-hand side numbers are the last octet of the IP in this /24 block.
Using `named-checkconf` and `named-checkzone`
Always validate configs before restarting BIND.
Check Main Configuration
sudo named-checkconf /etc/named.conf
# or
sudo named-checkconf /etc/bind/named.confNo output generally means success.
Check Zone Files
sudo named-checkzone example.com /var/named/example.com.zone
sudo named-checkzone 2.0.192.in-addr.arpa /var/named/2.0.192.in-addr.arpa.zoneThese tools catch syntax errors and common mistakes (duplicate records, missing SOA, etc.).
Starting and Testing BIND
Start/Restart Service
sudo systemctl restart named # or bind9
sudo systemctl status namedFix any errors reported in logs, typically via:
- systemd journal:
journalctl -u namedorjournalctl -u bind9 - Traditional logs:
/var/log/messages,/var/log/syslogdepending on distro
Local DNS Queries
Use dig or host:
dig @127.0.0.1 example.com
dig @127.0.0.1 www.example.com
dig @127.0.0.1 -x 192.0.2.10Look for:
status: NOERRORANSWER SECTIONwith expected recordsaa(authoritative answer) flag when querying your own zones
Setting Up a Secondary (Slave) BIND Server
Secondary servers increase availability and distribute load.
Primary (Master) Configuration
On the master, ensure allow-transfer and also-notify are configured:
zone "example.com" IN {
type master;
file "example.com.zone";
allow-transfer { 198.51.100.53; }; // secondary's IP
also-notify { 198.51.100.53; }; // send NOTIFY on changes
};
Consider using allow-transfer with an ACL for better manageability.
Secondary (Slave) Configuration
On the secondary (IP 198.51.100.53), define:
zone "example.com" IN {
type slave;
masters { 192.0.2.53; }; // master's IP
file "slaves/example.com.zone"; // local copy, managed by BIND
};
BIND will request a zone transfer (AXFR or IXFR) from the master and keep the local copy up to date based on SOA serial.
Testing Zone Transfers
From the secondary, after starting named:
sudo rndc reload
sudo ls /var/named/slaves/ # check if zone file is created
dig @198.51.100.53 example.com
If transfers fail, check both servers’ logs and verify allow-transfer, firewalls, and serial values.
Access Control and Security Basics
BIND is powerful and exposed on the network, so lock it down.
Limiting Recursion vs Authoritative Service
Authoritative public servers should usually not be open recursive resolvers.
Example:
options {
recursion no; // disable recursion for public authoritative DNS
allow-query { any; }; // allow everyone to query authoritative data
};For internal recursive resolvers, combine:
options {
recursion yes;
allow-query { 192.0.2.0/24; localhost; };
allow-recursion { 192.0.2.0/24; localhost; };
};Firewall Considerations
DNS uses:
- UDP port 53 — typical queries
- TCP port 53 — zone transfers, large responses, DNS over TCP
Open only what you need. Example with firewalld:
sudo firewall-cmd --add-service=dns --permanent
sudo firewall-cmd --reload
Or with iptables (simplified):
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -j ACCEPTRunning as a Non-Root User and Chroot
Most distros configure BIND to run as user named or bind; this is usually preconfigured in the package.
Chroot jails and SELinux/AppArmor profiles are often enabled by the distro; adapt paths and logs accordingly and avoid changing them unless you know the implications.
Using `rndc` for Control
rndc lets you control BIND without restarting the service.
Common `rndc` Commands
- Reload configuration and zones:
sudo rndc reload- Reload a single zone:
sudo rndc reload example.com- Flush cache (for recursive resolvers):
sudo rndc flush- View server status:
sudo rndc status`rndc` Configuration
Typically:
- BIND automatically configures
rndckeys viarndc-confgenduring installation. - Debian:
/etc/bind/rndc.keyandcontrolssection innamed.conf. - RHEL:
/etc/rndc.keyand correspondingincludeinnamed.conf.
If rndc complains about no key, generate one:
sudo rndc-confgen -a
sudo systemctl restart namedLogging and Troubleshooting
BIND logs are crucial when something breaks.
Enabling Custom Logging Channels
In named.conf:
logging {
channel default_log {
file "/var/log/named/default.log" versions 5 size 10m;
severity info;
print-time yes;
print-category yes;
};
channel query_log {
file "/var/log/named/queries.log" versions 3 size 5m;
severity info;
print-time yes;
};
category default { default_log; };
category queries { query_log; };
};Remember to:
- Create log directory:
sudo mkdir -p /var/log/named - Set permissions:
sudo chown named:named /var/log/named - Reload BIND:
sudo rndc reload
Common Problems
- BIND won’t start:
- Run
named-checkconf. - Check logs for syntax errors or permission issues on zone files.
- Zone not loading:
- Run
named-checkzone. - Validate
SOAandNSrecords, serial format, and TTL syntax. - Old data being served:
- Serial not incremented; always increase serial in
SOAwhen you edit zone data. - After changing, run
rndc reloadand ensure secondary servers receive the updated zone. - Clients can’t query server:
- Check
allow-query,listen-on, firewall, and network routes.
Basic Caching/Forwarding Resolver Setup
If you want BIND as an internal caching resolver:
Minimal configuration (no authoritative zones):
options {
directory "/var/named";
listen-on port 53 { 127.0.0.1; 192.0.2.53; };
allow-query { localhost; 192.0.2.0/24; };
recursion yes;
allow-recursion { localhost; 192.0.2.0/24; };
forwarders { 1.1.1.1; 8.8.8.8; };
forward only; // optional: only use forwarders, do not recurse to root
};
Point clients’ /etc/resolv.conf or DHCP configuration at 192.0.2.53 as their DNS server.
Best Practices and Operational Tips
- Keep BIND updated; security advisories for DNS software are frequent.
- Use a meaningful
SOAserial scheme and document your change process. - Separate internal and external views (split-horizon) when you have different data for internal vs public clients (done with BIND “views”).
- Harden access:
- Restrict
allow-query,allow-transfer,allow-recursion. - Avoid being an open resolver on the public Internet.
- Automate zone backups; zone files are plain text but represent critical infrastructure data.
- Monitor:
- Service status via systemd.
- Query volume and errors via logs.
- Zone transfer failures between master and secondary servers.
This establishes a working BIND installation you can expand with additional zones, DNSSEC, views, and more advanced features as needed.