How to Configure a Primary Name Server in Linux

how to configure a primary name server in Linux

Every time you type a website address like example.com into your browser, something has to translate that human-readable name into a numeric IP address the network can actually route to. That translation service is provided by DNS (Domain Name System), and the primary name server (also called the master server) is the authoritative source of truth for a domain’s DNS records.

In this article, we walk through what a primary name server is, how DNS authority works, and how to configure your own primary name server on Linux using BIND9, the most widely used open-source DNS server software, complete with practical examples and troubleshooting.

Table of Contents

  1. What Is DNS and Why Do We Need Name Servers?
  2. Primary vs. Secondary Name Servers
  3. What Is BIND9?
  4. Prerequisites
  5. Step-by-Step: Installing BIND9
  6. Understanding BIND9 Configuration Files
  7. Step-by-Step: Configuring a Primary Zone
  8. Creating the Zone File
  9. Starting and Testing the Name Server
  10. Configuring Clients to Use Your Name Server
  11. Real-World Example
  12. Cisco Router DNS Configuration
  13. Python Example: Querying Your New Name Server
  14. Comparison Table: Primary vs. Secondary vs. Caching Name Servers
  15. Best Practices
  16. Troubleshooting Common Issues
  17. Conclusion

1. What Is DNS and Why Do We Need Name Servers?

DNS (Domain Name System) is often described as the “phone book of the internet.” It maps human-friendly domain names (like example.com) to machine-friendly IP addresses (like 203.0.113.10). Without DNS, you would need to memorize numeric IP addresses for every website you wanted to visit.

A name server is a server that stores DNS records and answers queries about a domain. When your browser needs to find example.com, it sends a query to a name server, which responds with the correct IP address.

2. Primary vs. Secondary Name Servers

DNS infrastructure for a domain typically involves at least two types of authoritative name servers:

  • Primary (Master) Name Server: This is the original, authoritative source of a domain’s DNS records. Zone files are created and edited directly on this server. Also historically called the “master.”
  • Secondary (Slave) Name Server: This server holds a read-only copy of the zone data, automatically synchronized (via a process called a zone transfer) from the primary server. It provides redundancy — if the primary goes down, the secondary can still answer queries.
graph LR
    P[Primary Name Server - holds original zone file] -->|Zone Transfer AXFR/IXFR| S[Secondary Name Server - read-only copy]
    C[DNS Client / Resolver] --> P
    C --> S

This article focuses specifically on setting up the primary name server, since that is where zone data is authored and managed.

3. What Is BIND9?

BIND (Berkeley Internet Name Domain), version 9, is the most widely deployed DNS server software in the world, used by ISPs, universities, and enterprises to run authoritative and caching name servers. It is open-source, highly configurable, and the de facto standard for Linux-based DNS infrastructure.

4. Prerequisites

  • A Linux server (Ubuntu, Debian, CentOS, or RHEL) with a static IP address.
  • Root or sudo access.
  • A registered domain name (or a private/internal domain for lab/testing purposes).
  • Basic understanding of DNS record types (A, CNAME, MX, NS, SOA — covered in more depth in the next article on zone files).

5. Step-by-Step: Installing BIND9

On Ubuntu/Debian:

sudo apt update
sudo apt install bind9 bind9utils bind9-doc -y

On CentOS/RHEL/Fedora:

sudo dnf install bind bind-utils -y

Enable and start the service:

sudo systemctl enable named    # CentOS/RHEL service name
sudo systemctl enable bind9    # Ubuntu/Debian service name
sudo systemctl start bind9
sudo systemctl status bind9

6. Understanding BIND9 Configuration Files

BIND9’s configuration is split across a few key files, typically located in /etc/bind/ (Ubuntu/Debian) or /etc/named.conf and /var/named/ (CentOS/RHEL):

FilePurpose
named.confMain configuration file, defines global options and includes other files
named.conf.localWhere you define your custom zones (Ubuntu/Debian convention)
named.conf.optionsGlobal server options (forwarders, recursion settings)
Zone files (e.g., db.example.com)Contain the actual DNS records for a specific domain

7. Step-by-Step: Configuring a Primary Zone

Step 1: Define the zone in named.conf.local (Ubuntu/Debian) or the zone section of named.conf (RHEL/CentOS).

sudo nano /etc/bind/named.conf.local

Add the following:

zone "example.com" {
    type master;
    file "/etc/bind/zones/db.example.com";
    allow-transfer { 203.0.113.20; };  // IP of the secondary name server
};

Here, type master; explicitly declares this server as the primary name server for the example.com zone. The allow-transfer directive restricts zone transfers to only trusted secondary servers, an important security measure.

Step 2: Create the zones directory (if it doesn’t already exist).

sudo mkdir -p /etc/bind/zones

8. Creating the Zone File

Copy the default local zone template as a starting point:

sudo cp /etc/bind/db.local /etc/bind/zones/db.example.com

Edit the zone file:

sudo nano /etc/bind/zones/db.example.com

Example zone file content:

$TTL    604800
@       IN      SOA     ns1.example.com. admin.example.com. (
                        2026072401  ; Serial (increment on every change)
                        604800      ; Refresh
                        86400       ; Retry
                        2419200     ; Expire
                        604800 )    ; Negative Cache TTL

; Name servers
@       IN      NS      ns1.example.com.

; A records
ns1     IN      A       203.0.113.10
www     IN      A       203.0.113.10
mail    IN      A       203.0.113.11

; MX record
@       IN      MX      10 mail.example.com.

We will explore each of these record types (SOA, NS, A, MX) in much greater depth in the next article on zone file formats and resource records.

Check the zone file for syntax errors:

sudo named-checkzone example.com /etc/bind/zones/db.example.com

Check the overall BIND configuration for errors:

sudo named-checkconf

9. Starting and Testing the Name Server

Restart BIND9 to apply the new zone:

sudo systemctl restart bind9

Query your new name server locally using dig:

dig @localhost example.com

Query a specific record type:

dig @localhost www.example.com A

Sample output (truncated):

;; ANSWER SECTION:
www.example.com.    604800    IN    A    203.0.113.10

If you see the correct IP address returned, your primary name server is successfully answering authoritative queries for your zone.

10. Configuring Clients to Use Your Name Server

To make devices on your network actually use your new primary name server for DNS resolution, point their DNS settings to your server’s IP address.

On a Linux client, edit /etc/resolv.conf (or use systemd-resolved/NetworkManager depending on your distro):

nameserver 203.0.113.10

Or configure it via nmcli (NetworkManager):

sudo nmcli con mod "Wired connection 1" ipv4.dns "203.0.113.10"
sudo nmcli con up "Wired connection 1"

11. Real-World Example

A small hosting company runs its own internal domain internal.company.local for managing hundreds of internal servers by hostname instead of by IP address. They configure one Linux server as the primary name server, holding the authoritative zone file, and a second Linux server elsewhere in the data center as a secondary name server for redundancy. Every internal server and workstation is configured to use these two name servers, allowing engineers to reach db-primary.internal.company.local instead of memorizing 10.20.30.5.

graph TD
    Admin[Admin edits zone file] --> Primary[Primary Name Server: ns1.internal.company.local]
    Primary -->|Zone Transfer| Secondary[Secondary Name Server: ns2.internal.company.local]
    Client1[Server A] --> Primary
    Client2[Server B] --> Secondary

12. Cisco Router DNS Configuration

Network administrators often configure Cisco routers to use a specific internal DNS server (like the primary name server just configured) for their own name resolution needs, and sometimes to act as a simple DNS relay for connected clients.

Configure a Cisco router to use your new primary name server:

Router(config)# ip domain-lookup
Router(config)# ip name-server 203.0.113.10
Router(config)# ip domain-name example.com

Verify DNS resolution from the router itself:

Router# ping www.example.com

If configured correctly, the router will resolve www.example.com using your primary name server before sending the ICMP ping.

13. Python Example: Querying Your New Name Server

The following Python script uses the dnspython library to send a DNS query directly to your newly configured primary name server, bypassing your system’s default resolver — useful for testing and automation.

import dns.resolver

def query_custom_dns(domain, record_type, dns_server_ip):
    resolver = dns.resolver.Resolver()
    resolver.nameservers = [dns_server_ip]
    try:
        answers = resolver.resolve(domain, record_type)
        for answer in answers:
            print(f"{domain} ({record_type}) -> {answer}")
    except dns.resolver.NXDOMAIN:
        print(f"{domain} does not exist on this name server.")
    except dns.exception.Timeout:
        print(f"Query to {dns_server_ip} timed out.")

# Query the primary name server directly
query_custom_dns("www.example.com", "A", "203.0.113.10")
query_custom_dns("example.com", "MX", "203.0.113.10")

Sample Output:

www.example.com (A) -> 203.0.113.10
example.com (MX) -> 10 mail.example.com.

Install the required library first:

pip install dnspython --break-system-packages

14. Comparison Table: Primary vs. Secondary vs. Caching Name Servers

Server TypeZone Data SourcePurposeEditable?
Primary (Master)Original zone file, hand-editedAuthoritative source of truthYes, directly editable
Secondary (Slave)Synced via zone transfer from primaryRedundancy, load distributionNo, read-only copy
Caching/ResolverNo authoritative zones; caches answers from other serversSpeeds up repeated queries for clientsN/A (not authoritative)

15. Best Practices

  • Always increment the Serial number in the SOA record every time you edit a zone file — secondary servers use this to detect changes.
  • Restrict zone transfers (allow-transfer) to only known, trusted secondary server IPs to prevent zone data leakage (a security practice called preventing “zone transfer attacks”).
  • Run at least one secondary name server for redundancy — never rely on a single primary name server in production.
  • Use named-checkzone and named-checkconf before every restart to catch syntax errors proactively.
  • Set reasonable TTL values — shorter TTLs (like 300 seconds) during planned migrations for faster propagation, longer TTLs (like 86400 seconds) for stable records to reduce query load.
  • Enable DNSSEC where possible to protect against DNS spoofing and cache poisoning attacks.

16. Troubleshooting Common Issues

IssueCauseFix
dig returns no answerBIND9 not running, or zone not loadedCheck systemctl status bind9, check /var/log/syslog for zone errors
“zone example.com/IN: loading from master file failed”Syntax error in zone fileRun named-checkzone example.com /path/to/zonefile to locate the error
Secondary server not syncingallow-transfer misconfigured, or firewall blocking port 53 TCPVerify allow-transfer IP, check firewall rules for TCP/53
Clients still resolving old IP after a changeHigh TTL causing cachingLower TTL before planned changes, or wait for the TTL to expire
“REFUSED” response from name serverQuery doesn’t match any configured zone, or ACL restrictionsCheck named.conf zone definitions and allow-query settings

Quick diagnostic sequence:

sudo named-checkconf                                    # Check main config syntax
sudo named-checkzone example.com /etc/bind/zones/db.example.com  # Check zone file syntax
sudo systemctl restart bind9                             # Restart after fixes
dig @localhost example.com                               # Test resolution
tail -f /var/log/syslog | grep named                     # Watch live logs (Debian/Ubuntu)

17. Conclusion

Configuring a primary name server on Linux using BIND9 gives you full control over your domain’s DNS infrastructure — whether for a public-facing website, an internal corporate network, or a lab environment. The key steps are installing BIND9, declaring your zone as type master, carefully crafting your zone file with accurate records, validating your configuration with named-checkconf and named-checkzone, and testing thoroughly with dig. In the next article, we’ll go much deeper into zone file formats and the various resource record types (SOA, A, AAAA, CNAME, MX, TXT, NS) that make DNS work.

Further Reading

Total
2
Shares

Leave a Reply

Previous Post
Zone file formats and Resource Records in Linux

Zone File Formats and Resource Records in Linux

Next Post
how share files with NFS in Linux

How to Share Files with NFS in Linux

Related Posts