For our Blog Visitor only Get Additional 3 Month Free + 10% OFF on TriAnnual Plan YSBLOG10
Grab the Deal

How to Create DNS on Linux Server with BIND and Zone Files

To create DNS on a Linux server, install BIND (named), add zones in named.conf, build forward and reverse zone files with SOA, NS, A/MX/CNAME and PTR records, open port 53 TCP/UDP, start and enable named, test with dig, then register nameserver glue at your registrar to go live.

In this guide, I’ll show you how to create DNS on Linux server using BIND step by step. We’ll cover authoritative and caching roles, Ubuntu/Debian and RHEL/Alma/Rocky commands, zone files, firewall rules, testing with dig, and hardening. Follow along and you’ll have a production-ready DNS service with confidence.

What You’ll Build and When to Use it?

DNS translates domain names to IP addresses. On Linux, BIND (named) is the most widely used DNS software. You can deploy it as:

  • Authoritative DNS: Serves your domain’s official records (A, AAAA, MX, etc.).
  • Caching/Resolver: Answers client queries and caches results to speed up lookups.
  • Split-DNS (Views): Different answers for internal vs. external clients.

If your goal is “How to create DNS on Linux server” for your own domains, you’ll configure an authoritative server. If you just want faster, local lookups for a network, deploy a caching resolver only. You can also run both roles with proper access controls.

Prerequisites

  • A Linux server (Ubuntu/Debian or RHEL/Alma/Rocky/CentOS) with static public IP
  • Root or sudo privileges
  • A domain you control at a registrar (for delegating nameservers)
  • Firewall access to open ports 53 TCP and UDP
  • Basic CLI familiarity and a text editor (nano/vi)

Step 1: Install BIND (named)

Choose the commands matching your distribution.

# Ubuntu/Debian
sudo apt update
sudo apt install bind9 bind9-utils bind9-dnsutils

# RHEL/CentOS/Alma/Rocky
sudo dnf install bind bind-utils
# On older CentOS: sudo yum install bind bind-utils

Service names differ slightly:

  • Ubuntu/Debian: service is bind9
  • RHEL-family: service is named

Step 2: Define Global Options and Access Controls

On Ubuntu/Debian, options live in /etc/bind/named.conf.options and zones in /etc/bind/named.conf.local. On RHEL, everything is typically in /etc/named.conf with zone files in /var/named.

// Ubuntu/Debian: /etc/bind/named.conf.options
options {
    directory "/var/cache/bind";
    dnssec-validation auto;

    // Allow recursion only to trusted clients (for caching role).
    recursion yes;
    allow-recursion { 127.0.0.1; 10.0.0.0/8; 192.168.0.0/16; };

    // Who can query this server.
    allow-query { any; };

    // Listen addresses
    listen-on { any; };
    listen-on-v6 { any; };
};
// RHEL/Alma/Rocky: /etc/named.conf (partial)
options {
    directory "/var/named";
    dnssec-validation auto;

    recursion yes;
    allow-recursion { 127.0.0.1; 10.0.0.0/8; 192.168.0.0/16; };
    allow-query     { any; };

    listen-on port 53 { any; };
    listen-on-v6 { any; };
};

Security tip: If this server is public and authoritative only, disable recursion and restrict queries if needed.

recursion no;
allow-recursion { none; };

Step 3: Add Your Zones (Authoritative)

Assume your domain is example.com and your DNS server’s public IP is 203.0.113.10. We’ll create a forward zone for example.com and a reverse zone for 203.0.113.0/24.

Ubuntu/Debian zone declarations

# /etc/bind/named.conf.local
zone "example.com" {
    type master;
    file "/etc/bind/zones/db.example.com";
};

zone "113.0.203.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/db.203.0.113";
};

Create the zones directory and files:

sudo mkdir -p /etc/bind/zones
sudo nano /etc/bind/zones/db.example.com
sudo nano /etc/bind/zones/db.203.0.113

RHEL/Alma/Rocky zone declarations

# /etc/named.conf (add inside the main config)
zone "example.com" IN {
    type master;
    file "db.example.com";
};

zone "113.0.203.in-addr.arpa" IN {
    type master;
    file "db.203.0.113";
};

Create zone files under /var/named and set permissions:

sudo nano /var/named/db.example.com
sudo nano /var/named/db.203.0.113
sudo chown root:named /var/named/db.*
sudo chmod 640 /var/named/db.*

Step 4: Build Forward and Reverse Zone Files

Here’s a minimal, production-ready example with SOA, NS, A, AAAA, MX, CNAME, and TXT records.

;$ORIGIN example.com.
;$TTL 3600
@   IN SOA ns1.example.com. hostmaster.example.com. (
        2025010101 ; serial (YYYYMMDDNN)
        3600       ; refresh
        900        ; retry
        1209600    ; expire
        300 )      ; negative cache

    IN NS   ns1.example.com.
    IN NS   ns2.example.com.

ns1 IN A    203.0.113.10
ns2 IN A    203.0.113.11

@   IN A    203.0.113.20
@   IN AAAA 2001:db8::20

www IN CNAME @
mail IN A    203.0.113.30
@   IN MX 10 mail.example.com.

_txt IN TXT "v=spf1 a mx ~all"
_dmarc IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"

Reverse zone (PTR) example for 203.0.113.0/24:

;$ORIGIN 113.0.203.in-addr.arpa.
;$TTL 3600
@   IN SOA ns1.example.com. hostmaster.example.com. (
        2025010101
        3600
        900
        1209600
        300 )
    IN NS ns1.example.com.
    IN NS ns2.example.com.

10  IN PTR ns1.example.com.
11  IN PTR ns2.example.com.
20  IN PTR example.com.
30  IN PTR mail.example.com.

Always increment the SOA serial on every change. The common pattern is YYYYMMDDNN.

Step 5: Open Firewall and Enable the Service

DNS uses UDP 53 for most queries and TCP 53 for zone transfers and large responses.

# UFW (Ubuntu)
sudo ufw allow 53/udp
sudo ufw allow 53/tcp

# firewalld (RHEL/Alma/Rocky)
sudo firewall-cmd --add-service=dns --permanent
sudo firewall-cmd --reload

Start and enable BIND:

# Ubuntu/Debian
sudo systemctl enable --now bind9
sudo systemctl status bind9

# RHEL-family
sudo systemctl enable --now named
sudo systemctl status named

Step 6: Test with dig

Use dig to verify your records locally before delegating at your registrar.

dig @127.0.0.1 example.com A +short
dig @127.0.0.1 www.example.com CNAME +short
dig @127.0.0.1 mail.example.com A +short
dig @127.0.0.1 -x 203.0.113.20 +short

# Check SOA and NS
dig @127.0.0.1 example.com SOA +noall +answer
dig @127.0.0.1 example.com NS +noall +answer

If dig fails, inspect logs:

# Ubuntu/Debian
sudo journalctl -u bind9 -e
sudo named-checkconf
sudo named-checkzone example.com /etc/bind/zones/db.example.com

# RHEL-family
sudo journalctl -u named -e
sudo named-checkconf
sudo named-checkzone example.com /var/named/db.example.com

Step 7: Delegate Your Domain (Registrar Glue)

At your domain registrar:

  • Create host/glue records for ns1.example.com = 203.0.113.10 and ns2.example.com = 203.0.113.11.
  • Set your domain’s nameservers to ns1.example.com and ns2.example.com.
  • Wait for propagation (often minutes to a few hours).

Once delegated, public queries to example.com should resolve from your Linux DNS server.

Authoritative vs. Caching: Quick Configuration Notes

  • Authoritative-only: recursion no;, serve only your zones, limit allow-transfer to secondaries.
  • Caching-only: No master zones; enable recursion yes;, restrict allow-recursion to your LAN.
  • Mixed role: Use BIND views to separate internal clients from public.

Security and Reliability Best Practices

  • Limit zone transfers: allow-transfer { 203.0.113.11; };
  • Use TSIG keys for secure transfers between primary/secondary.
  • Harden recursion: only for internal IP ranges if needed.
  • Enable DNSSEC validation for resolvers; consider signing zones if you manage a public authoritative setup.
  • Run as non-root (default), keep BIND updated, and monitor logs.
  • Rate-limit responses (Response Policy/Rate Limiting) to reduce abuse.
  • Monitor with rndc status and external uptime checks.

Common DNS Records You’ll Use

  • A/AAAA: Map names to IPv4/IPv6 addresses.
  • CNAME: Alias one name to another (don’t use at zone apex).
  • MX: Mail exchanger for your domain.
  • TXT: SPF, DKIM, DMARC, and verification tokens.
  • NS: Authoritative nameservers for the zone.
  • PTR: Reverse DNS mapping IP to hostname (critical for email IPs).

Troubleshooting Checklist

  • Port 53 in use? On Ubuntu, systemd-resolved may conflict. Disable the stub listener:
    sudo sed -i 's/#DNSStubListener=yes/DNSStubListener=no/' /etc/systemd/resolved.conf
    sudo systemctl restart systemd-resolved

    Ensure BIND listens on your server IP, not 127.0.0.53.
  • Syntax errors: Run named-checkconf and named-checkzone.
  • Firewall/NAT: Open UDP/TCP 53 and forward correctly if behind a router.
  • Serial not incremented: Secondary won’t update; increase SOA serial.
  • Glue missing: Public cannot find ns1/ns2; add host records at registrar.
  • Reverse DNS: Your ISP often controls PTR for public IP blocks—request delegation or add PTR via their portal.

When to Use Managed DNS (and How YouStable Helps)

Running DNS yourself offers control, but you must handle availability, DDoS resilience, and global latency. If your domain is mission-critical, consider managed DNS or pair your authoritative BIND with secondary DNS on a cloud network. YouStable’s managed VPS and cloud instances provide high availability, anycast-friendly networking, and 24/7 support—so your DNS stays fast and reliable while you focus on apps.

FAQs

What is the easiest way to create a DNS server on Linux?

Install BIND and add a master zone. On Ubuntu: apt install bind9, declare zones in /etc/bind/named.conf.local, create zone files, open port 53, then test with dig. For many small teams, a caching-only resolver is even simpler—no zones, just safe recursion for your LAN.

Should I use BIND, dnsmasq, or Unbound?

BIND is the most feature-complete for authoritative + recursive + views + DNSSEC signing. Unbound excels as a modern, secure caching resolver. dnsmasq is lightweight for small networks (DHCP + DNS). If you need authoritative for public domains, BIND is the standard choice.

How do I set up reverse DNS (PTR) for my server?

Create a reverse zone (in-addr.arpa for IPv4 or ip6.arpa for IPv6) and add PTR records. However, for public IPs, your ISP usually controls rDNS. Open a ticket or use their portal to point your IP to the desired hostname. Keep A/AAAA and PTR consistent, especially for mail servers.

What ports do I open for DNS?

Open UDP 53 for standard queries and TCP 53 for zone transfers and large responses (DNS over TCP). On RHEL-based systems use firewall-cmd --add-service=dns --permanent. On Ubuntu, allow both 53/udp and 53/tcp in UFW.

How do I make my DNS highly available?

Run at least two authoritative servers (ns1/ns2) in different networks, restrict zone transfers with TSIG, and monitor with external health checks. Consider secondary DNS on another provider or anycast. If you prefer simplicity, YouStable can provision redundant VPS instances with global monitoring for resilient DNS.

Sanjeet Chauhan

Sanjeet Chauhan is a blogger & SEO expert, dedicated to helping websites grow organically. He shares practical strategies, actionable tips, and insights to boost traffic, improve rankings, & maximize online presence.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top