Operations 12 min read

Why Your Company Network Stalls: Master Linux DNS with BIND9, Dnsmasq, and CoreDNS

This article explains DNS fundamentals, the full query flow, record types, Linux client configuration files, compares BIND9, Dnsmasq, CoreDNS and Unbound, and provides step‑by‑step hands‑on setups for each server with concrete commands and configuration examples.

AI Agent Super App
AI Agent Super App
AI Agent Super App
Why Your Company Network Stalls: Master Linux DNS with BIND9, Dnsmasq, and CoreDNS

DNS operation

DNS translates human‑readable domain names (e.g., www.example.com) into IP addresses (e.g., 192.168.1.100). The query flow is:

Client checks its local cache.

If missing, the client contacts the configured local DNS server.

The local server, when lacking a cached answer, queries a root server, which returns the authoritative TLD server (e.g., .com).

The TLD server points to the domain’s authoritative server (e.g., for example.com).

The authoritative server returns the final IP address.

Record types

A – maps a name to an IPv4 address.

AAAA – maps a name to an IPv6 address.

CNAME – alias for another name.

MX – mail exchange server.

TXT – arbitrary text, often used for verification.

NS – name‑server delegation.

PTR – reverse DNS lookup.

Linux client configuration

/etc/resolv.conf

# /etc/resolv.conf example
nameserver 10.0.0.1
nameserver 8.8.8.8
search internal.local
options timeout:2 attempts:3

/etc/hosts

# /etc/hosts example
127.0.0.1   localhost
10.0.0.10   dns.internal.local dns
10.0.0.20   web01.internal.local web01
10.0.0.30   db01.internal.local db01

Lookup order

Linux resolves names in the order hosts file → DNS cache → DNS server . The order is configurable via /etc/nsswitch.conf:

# /etc/nsswitch.conf
hosts:      files dns myhostname

Comparison of internal DNS server software

Small office / home – Dnsmasq

Cloud‑native / Kubernetes – CoreDNS

Medium‑large enterprises – BIND9

Recursive DNS service – Unbound

DNS software comparison
DNS software comparison

BIND9 hands‑on configuration

Installation

# CentOS/RHEL
yum install -y bind bind-utils
systemctl enable named
systemctl start named

# Ubuntu/Debian
apt-get update
apt-get install -y bind9 bind9-utils dnsutils
systemctl enable named
systemctl start named
BIND9 installation
BIND9 installation

Main configuration file /etc/named.conf

// /etc/named.conf full example
options {
    listen-on port 53 { 10.0.0.10; };
    listen-on-v6 port 53 { ::1; };
    directory "/var/named";
    dump-file "/var/named/data/cache_dump.db";
    statistics-file "/var/named/data/named_stats.txt";
    recursion yes;
    allow-query { 10.0.0.0/24; };
    allow-query-cache { 10.0.0.0/24; };
    dnssec-validation auto;
    auth-nxdomain no;
};

zone "internal.local" IN {
    type master;
    file "internal.local.zone";
    allow-update { none; };
};

zone "0.0.10.in-addr.arpa" IN {
    type master;
    file "10.0.0.zone";
    allow-update { none; };
};

Forward (authoritative) zone file

$TTL 86400
@       IN SOA  ns.internal.local. admin.internal.local. (
                        2024051901  ; Serial
                        3600        ; Refresh
                        1800        ; Retry
                        604800      ; Expire
                        86400 )     ; Minimum

@       IN NS      ns.internal.local.
ns      IN A       10.0.0.10

www     IN A       10.0.0.20
web01   IN A       10.0.0.20
web02   IN A       10.0.0.21
db01    IN A       10.0.0.30
db02    IN A       10.0.0.31
mail    IN A       10.0.0.40

blog    IN CNAME   www
forum   IN CNAME   www

@       IN MX 10   mail.internal.local.

Reverse zone file

$TTL 86400
@       IN SOA  ns.internal.local. admin.internal.local. (
                        2024051901  ; Serial
                        3600        ; Refresh
                        1800        ; Retry
                        604800      ; Expire
                        86400 )     ; Minimum

@       IN NS      ns.internal.local.
10      IN PTR      ns.internal.local.
20      IN PTR      web01.internal.local.
21      IN PTR      web02.internal.local.
30      IN PTR      db01.internal.local.
31      IN PTR      db02.internal.local.
40      IN PTR      mail.internal.local.

Syntax check and service reload

# Check main config syntax
named-checkconf /etc/named.conf

# Check zone files
named-checkzone internal.local /var/named/internal.local.zone
named-checkzone 0.0.10.in-addr.arpa /var/named/10.0.0.zone

# Reload configuration
systemctl reload named

# Test resolution
dig @10.0.0.10 www.internal.local
nslookup web01.internal.local 10.0.0.10

Dnsmasq quick deployment

Installation

# CentOS/RHEL
yum install -y dnsmasq
systemctl enable dnsmasq

# Ubuntu/Debian
apt-get install -y dnsmasq
systemctl enable dnsmasq

/etc/dnsmasq.conf

# /etc/dnsmasq.conf
interface=eth0
bind-interfaces
domain-needed
bogus-priv

server=8.8.8.8
server=114.114.114.114

address=/internal.local/10.0.0.10

host-record=web01,10.0.0.20
host-record=web02,10.0.0.21
host-record=db01,10.0.0.30

cache-size=1000
neg-ttl=3600
max-ttl=86400

log-queries
log-facility=/var/log/dnsmasq.log

Using the hosts file

# /etc/hosts (one record per line)
10.0.0.10   ns.internal.local ns
10.0.0.20   web01.internal.local web01 www
10.0.0.21   web02.internal.local web02
10.0.0.30   db01.internal.local db01 mysql
10.0.0.31   db02.internal.local db02

# Apply changes
systemctl restart dnsmasq

CoreDNS cloud‑native deployment

Binary installation

# Download CoreDNS
wget https://github.com/coredns/coredns/releases/download/v1.11.1/coredns_1.11.1_linux_amd64.tgz
tar -zxf coredns_1.11.1_linux_amd64.tgz
mv coredns /usr/local/bin/

# Create configuration directory
mkdir -p /etc/coredns

Corefile configuration

cat > /etc/coredns/Corefile <<'EOF'
.:53 {
    forward . 8.8.8.8 114.114.114.114
    log
    errors
    cache 30
}

internal.local:53 {
    file db.internal.local
    log
    errors
}
EOF

Zone file for internal.local

cat > /etc/coredns/db.internal.local <<'EOF'
$ORIGIN internal.local.
$TTL 86400
@  IN  SOA ns.internal.local. admin.internal.local. (
     2024051901  ; Serial
     3600        ; Refresh
     1800        ; Retry
     604800      ; Expire
     86400 )     ; Minimum

@       IN  NS      ns.internal.local.
ns      IN  A       10.0.0.10
www     IN  A       10.0.0.20
web01   IN  A       10.0.0.20
db01    IN  A       10.0.0.30
EOF

Docker deployment (recommended)

# Run CoreDNS in Docker
docker run -d \
    --name coredns \
    -p 53:53/udp \
    -p 53:53/tcp \
    -v /etc/coredns/Corefile:/Corefile \
    coredns/coredns:1.11.1

# Test
 dig @127.0.0.1 www.internal.local
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

ConfigurationNetworkLinuxDNSBIND9CoreDNSDnsmasq
AI Agent Super App
Written by

AI Agent Super App

AI agent applications, installation, large-model testing, computer fundamentals, IT operations and maintenance exchange, network technology exchange, Linux learning

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.