| |

LFCE 34 ๐Ÿง DNS Server โ€” What BIND9 Does

โฑ๏ธ Estimated read: 11 min | |

BIND9 is the reference implementation of the Domain Name System protocol on Linux, and its daemon named is the software that answers DNS queries. It is not a single-purpose tool with one fixed behavior. A BIND9 instance can be an authoritative name server for zones you control, a recursive resolver that looks up names on behalf of clients, a forwarder that passes queries upstream, or a combination of these roles. The configuration determines which role the server performs, and the security implications of each role are different.

This chapter examines what BIND9 actually does: the authoritative and recursive functions, the configuration directives that enable each, the distinction between allow-query and allow-recursion, and the tools that validate and control the running server. It builds the conceptual foundation for the configuration chapters that follow.

Key point: BIND9’s behavior is determined by the recursion directive and the presence or absence of zone statements, not by the binary itself. An authoritative server has recursion no and at least one zone . A resolver has recursion yes and allow-recursion restricted to trusted clients. An open resolverโ€”allow-recursion { any; }โ€”is an amplification vector and must never be exposed to the internet.


Why BIND9 exists

The protocol-reference problem.

DNS is defined by a set of RFCs, but a specification is not an implementation. BIND9 provides a complete, portable implementation of the wire format, query/response logic, zone transfer mechanisms, and caching algorithms. It is maintained by the Internet Systems Consortium (ISC) and is distributed as the bind9 package on most Linux distributions. The authoritative reference for every configuration statement is the BIND 9 Administrator Reference Manual (ARM).

The authoritative-versus-recursive problem.

These are distinct functions. An authoritative server holds the definitive records for a zone and sets the AA (Authoritative Answer) bit in its responses. It does not ask other servers for the answer because it has the answer in its configuration . A recursive resolver does not hold the records; it walks the DNS hierarchy from the root down, caching answers according to their TTL. BIND9 implements both, and the configuration determines which function a given instance performs.

The zone-transfer problem.

DNS data must be replicated across multiple servers for redundancy. BIND9 implements the primary/secondary model: the primary holds the master copy of the zone data, and secondaries receive the data through zone transfers (AXFR or IXFR). This replication is not optional for production DNS; a single server is a single point of failure. BIND9’s zone transfer implementation, including authentication through TSIG, is a core part of what the software does.


a. The authoritative name server role

An authoritative server holds the zone files for one or more domains and answers queries about those domains. It does not need to ask any other server for the answer because it has the answer in its configuration.

# A minimal authoritative configuration in named.conf
options {
    directory "/var/cache/bind";
    recursion no;                    # Authoritative only; do not resolve other names
    allow-query { any; };            # Answer queries from anyone
};

zone "example.com" {
    type primary;                    # This server is the primary master for the zone
    file "/etc/bind/zones/example.com.zone";
};

The recursion no directive is the defining characteristic of an authoritative-only server . It tells BIND9 not to perform recursive lookups for clients. If a query arrives for a name outside the zones this server is authoritative for, BIND9 returns a referral or an error, not an answer from its cache. The type primary statement identifies this server as the master copy of the zone data.


b. The recursive resolver role

A recursive resolver performs the iterative lookups needed to answer a query. It starts at the root, follows referrals down the hierarchy, and caches the results according to their TTL. It does not hold authoritative data for the names it resolves.

# A minimal resolver configuration in named.conf
options {
    directory "/var/cache/bind";
    recursion yes;                   # Enable recursive resolution
    allow-recursion { localnets; };  # Only allow trusted clients to recurse
};

The recursion yes directive enables the resolver behavior. The allow-recursion statement is critical for security: it restricts which clients are permitted to use the server as a resolver. An open resolver that allows recursion from any address is a DNS amplification vector and should never be exposed to the internet. The localnets ACL is a safe default for a server that only serves its local network.


c. The combined role and its risks

BIND9 can serve both roles simultaneously. A common configuration is an internal server that is authoritative for internal zones and also resolves external names for internal clients.

options {
    directory "/var/cache/bind";
    recursion yes;
    allow-recursion { internal; };    # Only internal clients may recurse
    allow-query { any; };             # Anyone may query authoritative zones
};

acl "internal" {
    192.168.0.0/16;
    10.0.0.0/8;
};

The distinction between allow-query and allow-recursion is what makes the combined role safe. allow-query controls who can ask questions about the zones this server is authoritative for. allow-recursion controls who can ask the server to resolve names it is not authoritative for. An external client can query example.com if this server is authoritative for it, but cannot ask this server to resolve google.com because that would require recursion.

The risk of the combined role is that a misconfiguration of allow-recursion turns the server into an open resolver. The default configuration must be hardened deliberately.


Complete Example Session

# ============================================
# PART 1: INSTALL BIND9
# ============================================
# On Debian/Ubuntu:
apt install bind9 bind9utils

# Verify the service is installed
named -v
# Output: BIND 9.20.x

# ============================================
# PART 2: INSPECT THE DEFAULT CONFIGURATION
# ============================================
cat /etc/bind/named.conf
# The default configuration includes options, local zones, and a default zones file

# ============================================
# PART 3: CONFIGURE AN AUTHORITATIVE ZONE
# ============================================
cat > /etc/bind/zones/example.com.zone <<'EOF'
$TTL 3600
@   IN  SOA ns1.example.com. admin.example.com. (
        2025010101 ; serial
        3600       ; refresh
        900        ; retry
        604800     ; expire
        300        ; negative TTL
)
@   IN  NS  ns1.example.com.
ns1 IN  A   192.168.1.10
www IN  A   192.168.1.20
EOF

cat >> /etc/bind/named.conf.local <<'EOF'
zone "example.com" {
    type primary;
    file "/etc/bind/zones/example.com.zone";
};
EOF

# ============================================
# PART 4: DISABLE RECURSION (AUTHORITATIVE ONLY)
# ============================================
# Edit the options block in named.conf.options
# Set recursion no and allow-query any
# This server only answers for example.com

# ============================================
# PART 5: VALIDATE THE CONFIGURATION
# ============================================
named-checkconf
named-checkzone example.com /etc/bind/zones/example.com.zone
# Both commands return no output on success

# ============================================
# PART 6: START AND TEST
# ============================================
systemctl restart named
dig @localhost www.example.com
# Output: www.example.com. 3600 IN A 192.168.1.20

# ============================================
# PART 7: VERIFY THE AUTHORITATIVE FLAG
# ============================================
dig @localhost www.example.com | grep flags
# Output includes: flags: qr aa rd
# The "aa" flag confirms the answer is authoritative

# ============================================
# PART 8: TEST RECURSION IS DISABLED
# ============================================
dig @localhost google.com
# Output: status: REFUSED or a referral, not an answer
# The server does not resolve names outside its zones

# ============================================
# PART 9: CONFIGURE A RESOLVER ON A SEPARATE INSTANCE
# ============================================
# On a different server (or a different view):
# options { recursion yes; allow-recursion { localnets; }; };
# No zone statements for external domains

# ============================================
# PART 10: CHECK THE CONTROL CHANNEL
# ============================================
rndc status
# Output shows the server version, uptime, and number of zones

The ten parts demonstrate the authoritative role from configuration through verification. The critical distinction is in Parts 7 and 8: the aa flag confirms authoritative answers, and the REFUSED response for google.com confirms that recursion is disabled. A resolver would return an answer for google.com from its cache or iterative lookup; this server does not.


Quick Reference

BIND9 Roles

RoleConfigurationBehavior
Authoritative onlyrecursion no; + zone statementsAnswers only for configured zones
Recursive resolverrecursion yes; + allow-recursionResolves any name for allowed clients
Forwarderforwarders { ... }; + forward only;Passes queries to another resolver
Combinedrecursion yes; + zones + ACLBoth roles, restricted by ACL

Key Configuration Statements

StatementPurpose
recursion yes/noEnables or disables recursive resolution
allow-queryWho may query the server
allow-recursionWho may use the server as a resolver
zone "name" { type primary; file "..."; }Defines an authoritative zone
forwarders { ip; }Upstream resolver for forwarding

Verification Commands

CommandPurpose
named-checkconfValidate named.conf syntax
named-checkzoneValidate a zone file
dig @server nameQuery the server directly
rndc statusShow server status
dig ... | grep flagsCheck the aa (authoritative) flag

Best Practices

โœ… Do This:

# Disable recursion on authoritative-only servers
recursion no;                                                # โœ…

# Restrict recursion to trusted networks
allow-recursion { localnets; };                              # โœ…

# Validate configuration before restarting
named-checkconf; named-checkzone <zone> <file>               # โœ…

# Use separate servers for authoritative and recursive roles when possible
# Reduces the attack surface                                      # โœ…

# Keep BIND9 updated
apt update && apt upgrade bind9                              # โœ…

โŒ Don’t Do This:

# Run an open resolver on the internet
allow-recursion { any; };    # Amplification vector             # โŒ

# Assume BIND9 is only a resolver or only authoritative
# It is both; the configuration determines the role             # โŒ

# Skip zone validation before restart
systemctl restart named    # Syntax errors cause outage         # โŒ

# Expose the version string
version "not disclosed";    # Harden if public-facing           # โŒ

Common Pitfalls

PitfallWhy It HappensFix
Queries for external names return REFUSEDrecursion no on authoritative serverExpected; use a resolver for external names
Server is used as an amplification vectorallow-recursion { any; }Restrict to localnets or specific ACLs
Zone not answeringZone statement missing or file path wrongnamed-checkconf and named-checkzone
aa flag missingQuery hit a resolver, not the authoritative serverQuery the authoritative server directly
Configuration syntax errorTypo in named.confnamed-checkconf before restart

Real-World Examples

1. Authoritative-only server

options { recursion no; allow-query { any; }; };
zone "example.com" { type primary; file "/etc/bind/zones/example.com.zone"; };

2. Recursive resolver

options { recursion yes; allow-recursion { localnets; }; };

3. Combined server with ACL

acl "internal" { 192.168.0.0/16; };
options { recursion yes; allow-recursion { internal; }; };

4. Forwarder

options { forwarders { 8.8.8.8; 1.1.1.1; }; forward only; };

5. Validate configuration

named-checkconf

6. Validate zone

named-checkzone example.com /etc/bind/zones/example.com.zone

7. Test authoritative answer

dig @localhost www.example.com

8. Check aa flag

dig @localhost www.example.com | grep flags

9. Reload without restart

rndc reload

10. Check server status

rndc status

Visual

BIND9 Roles

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  BIND9 CAN BE AUTHORITATIVE, RECURSIVE, OR BOTH              โ”‚
โ”‚                                                              โ”‚
โ”‚  AUTHORITATIVE:                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ Client โ”€โ”€โ–ถ BIND9 โ”€โ”€โ–ถ Zone File                         โ”‚  โ”‚
โ”‚  โ”‚                    (answers with AA flag)              โ”‚  โ”‚
โ”‚  โ”‚                                                        โ”‚  โ”‚
โ”‚  โ”‚ Holds the records. Does not ask other servers.         โ”‚  โ”‚
โ”‚  โ”‚ recursion no;                                          โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                                              โ”‚
โ”‚  RECURSIVE RESOLVER:                                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ Client โ”€โ”€โ–ถ BIND9 โ”€โ”€โ–ถ Root โ”€โ”€โ–ถ TLD โ”€โ”€โ–ถ Authoritative    โ”‚  โ”‚
โ”‚  โ”‚                    (walks the hierarchy, caches)       โ”‚  โ”‚
โ”‚  โ”‚                                                        โ”‚  โ”‚
โ”‚  โ”‚ Does not hold the records. Asks on behalf of client.   โ”‚  โ”‚
โ”‚  โ”‚ recursion yes; allow-recursion { localnets; };         โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                                              โ”‚
โ”‚  COMBINED:                                                   โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ Internal clients โ”€โ”€โ–ถ BIND9 โ”€โ”€โ–ถ Internal zones (AA)     โ”‚  โ”‚
โ”‚  โ”‚                  โ””โ”€โ”€โ–ถ External zones (recursion)      โ”‚  โ”‚
โ”‚  โ”‚                                                        โ”‚  โ”‚
โ”‚  โ”‚ allow-query controls zone access.                      โ”‚  โ”‚
โ”‚  โ”‚ allow-recursion controls resolver access.              โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The aa Flag

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  AUTHORITATIVE ANSWERS SET THE AA FLAG                       โ”‚
โ”‚                                                              โ”‚
โ”‚  Query the authoritative server:                             โ”‚
โ”‚  # dig @192.168.1.10 www.example.com                         โ”‚
โ”‚                                                              โ”‚
โ”‚  ;; flags: qr aa rd; QUERY: 1, ANSWER: 1                     โ”‚
โ”‚              โ”‚                                               โ”‚
โ”‚              โ””โ”€โ”€ aa = Authoritative Answer                   โ”‚
โ”‚                                                              โ”‚
โ”‚  Query a resolver (cached answer):                           โ”‚
โ”‚  # dig @8.8.8.8 www.example.com                              โ”‚
โ”‚                                                              โ”‚
โ”‚  ;; flags: qr rd ra; QUERY: 1, ANSWER: 1                     โ”‚
โ”‚              โ”‚                                               โ”‚
โ”‚              โ””โ”€โ”€ no aa = not authoritative                   โ”‚
โ”‚                                                              โ”‚
โ”‚  The aa flag confirms which role answered the query.         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Open Resolver Risk

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  OPEN RESOLVER = AMPLIFICATION VECTOR                        โ”‚
โ”‚                                                              โ”‚
โ”‚  โœ… Correct:                                                 โ”‚
โ”‚  allow-recursion { localnets; };                             โ”‚
โ”‚  โ†’ Only local network can use this server as a resolver      โ”‚
โ”‚                                                              โ”‚
โ”‚  โŒ Dangerous:                                               โ”‚
โ”‚  allow-recursion { any; };                                   โ”‚
โ”‚  โ†’ Anyone on the internet can send queries                   โ”‚
โ”‚  โ†’ Attacker spoofs source IP, sends small query              โ”‚
โ”‚  โ†’ Server sends large response to victim                     โ”‚
โ”‚  โ†’ Victim is flooded with DNS responses                      โ”‚
โ”‚                                                              โ”‚
โ”‚  Rule: Never allow recursion from untrusted networks.        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
SoftwareBIND9 (Berkeley Internet Name Domain)
Daemonnamed
MaintainerInternet Systems Consortium (ISC)
Primary config/etc/bind/named.conf
RolesAuthoritative, recursive resolver, forwarder, combined
Authoritative configrecursion no; + zone statements
Resolver configrecursion yes; + allow-recursion
Zone validationnamed-checkzone
Config validationnamed-checkconf
Authoritative flagaa in dig output
DocumentationBIND 9 Administrator Reference Manual (ARM)

Key takeaways:

  • BIND9 is both an authoritative server and a recursive resolver. The recursion directive determines which role a given instance performs. An authoritative server answers from its zone files; a resolver walks the hierarchy and caches answers .
  • allow-recursion is a security boundary, not a convenience. An open resolver is an amplification vector. Restrict recursion to trusted networks with an ACL, and leave it disabled entirely on authoritative-only servers.
  • The aa flag distinguishes the roles in practice. A query answered by an authoritative server includes the aa flag. A query answered by a resolver does not, even if the answer is cached from an authoritative source.
  • Zone transfers require authentication. The primary/secondary model uses TSIG to authenticate zone transfers. Plain IP-based access control is vulnerable to spoofing.
  • The ARM is the definitive reference. The BIND 9 Administrator Reference Manual documents every configuration statement, tool, and feature.
  • Validation before restart prevents outages. named-checkconf validates the configuration syntax, and named-checkzone validates zone file contents. Both should be run before reloading the service.

Remember: BIND9 is the implementation of DNS on Linux. It does not have one fixed behavior; it has a configuration language that determines whether it acts as an authoritative server, a resolver, or both. The recursion directive is the switch between the two primary roles, and the allow-recursion ACL is the security boundary that prevents the resolver from being abused. The aa flag in dig output confirms which role answered a query. Configure the role deliberately, validate the configuration, and restrict recursion to trusted clients.


Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!