DNS Explained: From Basics to Configuration
DNS is one of the most critical services on the internet. Without it, you'd have to memorize IP addresses like 142.250.185.78 instead of typing google.com. In this article, we'll go from the basics to hands-on configuration.
DNS is the phone book of the internet. You look up a name (domain), and it gives you the number (IP address) to call.
Part 1: Understanding DNS
What is DNS?
DNS (Domain Name System) translates human-readable domain names into IP addresses that computers use to communicate.
google.com → DNS → 142.250.185.78
amazon.com → DNS → 52.94.236.248
DNS operates on UDP port 53 (and TCP 53 for large responses or zone transfers).
The DNS Hierarchy
DNS is organized in a hierarchical tree structure:
. (Root)
|
+-----------+-----------+
| | |
.com .org .net ← TLD (Top-Level Domain)
|
+---+---+
| |
google amazon ← Second-Level Domain
|
www ← Subdomain (optional)
DNS Components:
- Root Servers: 13 root server clusters worldwide (a.root-servers.net to m.root-servers.net)
- TLD Servers: Manage .com, .org, .net, country codes (.de, .fr, .uk)
- Authoritative Servers: Hold the actual DNS records for a domain
- Recursive Resolvers: Your ISP's DNS or public DNS (8.8.8.8, 1.1.1.1)
DNS Resolution Process
When you type www.example.com in your browser:
- Local Cache Check: Browser and OS check their cache first
- Recursive Resolver: If not cached, query goes to your configured DNS server
- Root Server: Resolver asks root server "Where is .com?"
- TLD Server: Root says "Ask the .com TLD server"
- Authoritative Server: TLD says "Ask example.com's nameserver"
- Answer: Authoritative server returns the IP address
- Caching: Result is cached based on TTL (Time To Live)
This entire process typically takes 20-120 milliseconds. Cached responses are instant.
DNS Record Types
DNS doesn't just store IP addresses. There are many record types:
| Record | Purpose | Example |
|---|---|---|
| A | Maps domain to IPv4 address | example.com → 93.184.216.34 |
| AAAA | Maps domain to IPv6 address | example.com → 2606:2800:220:1:: |
| CNAME | Alias to another domain | www.example.com → example.com |
| MX | Mail server for the domain | example.com → mail.example.com (priority 10) |
| TXT | Text data (SPF, DKIM, verification) | "v=spf1 include:_spf.google.com ~all" |
| NS | Nameserver for the domain | example.com → ns1.example.com |
| SOA | Start of Authority (zone info) | Primary NS, admin email, serial, timers |
| PTR | Reverse DNS (IP to domain) | 34.216.184.93 → example.com |
| SRV | Service location | _sip._tcp.example.com → sipserver.example.com:5060 |
| CAA | Certificate Authority Authorization | example.com → letsencrypt.org |
Part 2: DNS Tools and Queries
dig - DNS Lookup Utility
dig is the most powerful DNS tool. Install it with:
# Debian/Ubuntu
sudo apt install dnsutils
# CentOS/RHEL
sudo dnf install bind-utils
Basic Queries
# Query A record
dig example.com
# Query specific record type
dig example.com MX
dig example.com TXT
dig example.com NS
dig example.com AAAA
# Query all records
dig example.com ANY
Understanding dig Output
$ dig google.com
; <<>> DiG 9.18.1 <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12345
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 300 IN A 142.250.185.78
;; Query time: 23 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Wed Feb 12 10:30:00 CET 2026
;; MSG SIZE rcvd: 55
Key fields:
- status: NOERROR - Query successful
- 300 - TTL in seconds (5 minutes)
- IN - Internet class
- A - Record type
- Query time - How long the lookup took
- SERVER - DNS server that answered
Advanced dig Options
# Short answer only
dig +short google.com
# Trace the full resolution path
dig +trace google.com
# Query specific DNS server
dig @8.8.8.8 google.com
dig @1.1.1.1 google.com
# Reverse DNS lookup
dig -x 142.250.185.78
# Check if DNSSEC is enabled
dig +dnssec example.com
# Get only answer section
dig +noall +answer google.com
Trace DNS Resolution
$ dig +trace google.com
. 518400 IN NS a.root-servers.net.
com. 172800 IN NS a.gtld-servers.net.
google.com. 172800 IN NS ns1.google.com.
google.com. 300 IN A 142.250.185.78
nslookup - Simple DNS Queries
# Basic lookup
nslookup google.com
# Query specific server
nslookup google.com 8.8.8.8
# Query MX records
nslookup -type=MX google.com
# Reverse lookup
nslookup 142.250.185.78
host - Quick DNS Lookups
# Simple lookup
host google.com
# Verbose output
host -v google.com
# Query specific type
host -t MX google.com
host -t TXT google.com
# Reverse lookup
host 142.250.185.78
Part 3: Linux DNS Configuration
/etc/resolv.conf - DNS Client Configuration
This file tells your system which DNS servers to use:
# /etc/resolv.conf
# Primary DNS server
nameserver 8.8.8.8
# Secondary DNS server
nameserver 8.8.4.4
# Third DNS server (optional)
nameserver 1.1.1.1
# Search domain (optional)
search example.com internal.example.com
# Domain (optional)
domain example.com
Options explained:
- nameserver: DNS server IP (max 3)
- search: Domains to append for short hostnames
- domain: Default domain for the host
On modern systems with NetworkManager or systemd-resolved, /etc/resolv.conf is often auto-generated. Don't edit it directly!
systemd-resolved (Modern Systems)
# Check current DNS configuration
resolvectl status
# See which DNS servers are being used
resolvectl dns
# Flush DNS cache
sudo resolvectl flush-caches
# Check cache statistics
resolvectl statistics
Configure DNS with systemd-resolved
# Edit the configuration
sudo nano /etc/systemd/resolved.conf
# /etc/systemd/resolved.conf
[Resolve]
DNS=8.8.8.8 8.8.4.4
FallbackDNS=1.1.1.1 9.9.9.9
DNSSEC=allow-downgrade
DNSOverTLS=opportunistic
Cache=yes
# Restart the service
sudo systemctl restart systemd-resolved
NetworkManager DNS Configuration
# View connections
nmcli connection show
# Set DNS for a connection
nmcli connection modify "Wired connection 1" ipv4.dns "8.8.8.8 8.8.4.4"
nmcli connection modify "Wired connection 1" ipv4.ignore-auto-dns yes
# Apply changes
nmcli connection up "Wired connection 1"
/etc/hosts - Local DNS Override
The /etc/hosts file is checked BEFORE DNS. Use it for local overrides:
# /etc/hosts
# Loopback
127.0.0.1 localhost
::1 localhost
# Local network hosts
192.168.1.10 server1.local server1
192.168.1.11 server2.local server2
192.168.1.20 printer.local printer
# Block domains (point to nowhere)
0.0.0.0 ads.example.com
0.0.0.0 tracking.example.com
# Development overrides
192.168.1.100 myapp.local
127.0.0.1 api.myapp.local
Changes to /etc/hosts take effect immediately. No restart needed.
/etc/nsswitch.conf - Name Resolution Order
This file controls the order in which name lookups happen:
# /etc/nsswitch.conf
# hosts: files = check /etc/hosts first, then dns
hosts: files dns
# You might also see:
hosts: files mdns4_minimal [NOTFOUND=return] dns
Part 4: Setting Up a Local DNS Server
Option 1: dnsmasq (Lightweight)
dnsmasq is perfect for small networks, home labs, or development environments.
Installation
# Debian/Ubuntu
sudo apt install dnsmasq
# CentOS/RHEL
sudo dnf install dnsmasq
Basic Configuration
# /etc/dnsmasq.conf
# Listen on this interface
interface=eth0
# Don't read /etc/resolv.conf
no-resolv
# Upstream DNS servers
server=8.8.8.8
server=8.8.4.4
# Local domain
domain=home.local
local=/home.local/
# DHCP range (optional)
dhcp-range=192.168.1.100,192.168.1.200,24h
# Static DNS entries
address=/server1.home.local/192.168.1.10
address=/server2.home.local/192.168.1.11
# Block ads (return NXDOMAIN)
address=/ads.example.com/
# Cache size
cache-size=1000
# Log queries (for debugging)
log-queries
log-facility=/var/log/dnsmasq.log
Start dnsmasq
sudo systemctl enable dnsmasq
sudo systemctl start dnsmasq
sudo systemctl status dnsmasq
# Test it
dig @127.0.0.1 google.com
Option 2: BIND9 (Full-Featured)
BIND is the most widely used DNS server software. Use it for production environments.
Installation
# Debian/Ubuntu
sudo apt install bind9 bind9utils bind9-doc
# CentOS/RHEL
sudo dnf install bind bind-utils
Main Configuration
# /etc/bind/named.conf.options (Debian/Ubuntu)
# /etc/named.conf (CentOS/RHEL)
options {
directory "/var/cache/bind";
// Forwarding
forwarders {
8.8.8.8;
8.8.4.4;
};
// Allow queries from local network
allow-query { localhost; 192.168.1.0/24; };
// Allow recursion for local network
allow-recursion { localhost; 192.168.1.0/24; };
// DNSSEC validation
dnssec-validation auto;
// Listen on
listen-on { 127.0.0.1; 192.168.1.1; };
listen-on-v6 { none; };
};
Create a Zone File
# /etc/bind/named.conf.local
zone "example.local" {
type master;
file "/etc/bind/zones/db.example.local";
};
zone "1.168.192.in-addr.arpa" {
type master;
file "/etc/bind/zones/db.192.168.1";
};
Forward Zone File
# /etc/bind/zones/db.example.local
$TTL 604800
@ IN SOA ns1.example.local. admin.example.local. (
2026021201 ; Serial (YYYYMMDDNN)
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
; Name servers
@ IN NS ns1.example.local.
; A records
ns1 IN A 192.168.1.1
server1 IN A 192.168.1.10
server2 IN A 192.168.1.11
web IN A 192.168.1.20
db IN A 192.168.1.21
; CNAME records
www IN CNAME web.example.local.
mysql IN CNAME db.example.local.
; MX records
@ IN MX 10 mail.example.local.
mail IN A 192.168.1.30
Reverse Zone File
# /etc/bind/zones/db.192.168.1
$TTL 604800
@ IN SOA ns1.example.local. admin.example.local. (
2026021201 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
; Name servers
@ IN NS ns1.example.local.
; PTR records
1 IN PTR ns1.example.local.
10 IN PTR server1.example.local.
11 IN PTR server2.example.local.
20 IN PTR web.example.local.
21 IN PTR db.example.local.
30 IN PTR mail.example.local.
Validate and Start BIND
# Check configuration syntax
sudo named-checkconf
sudo named-checkzone example.local /etc/bind/zones/db.example.local
sudo named-checkzone 1.168.192.in-addr.arpa /etc/bind/zones/db.192.168.1
# Start BIND
sudo systemctl enable named # or bind9 on Debian
sudo systemctl start named
sudo systemctl status named
# Test
dig @localhost server1.example.local
dig @localhost -x 192.168.1.10
Part 5: DNS Security
DNSSEC
DNSSEC adds cryptographic signatures to DNS records, preventing spoofing attacks.
# Check if a domain uses DNSSEC
dig +dnssec example.com
# Look for RRSIG records in the output
# AD flag in header = Authentic Data (validated)
DNS over HTTPS (DoH) / DNS over TLS (DoT)
Encrypt DNS queries to prevent eavesdropping:
# systemd-resolved with DoT
# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com
DNSOverTLS=yes
Common DNS Attacks
| Attack | Description | Protection |
|---|---|---|
| DNS Spoofing | Fake DNS responses | DNSSEC |
| DNS Amplification | DDoS using open resolvers | Rate limiting, disable open recursion |
| DNS Tunneling | Exfiltrate data via DNS | Monitor unusual DNS traffic |
| Cache Poisoning | Insert bad records in cache | DNSSEC, randomize query IDs |
Part 6: Troubleshooting DNS
Common Issues and Fixes
# Issue: DNS not resolving
# Check 1: Can you reach the DNS server?
ping 8.8.8.8
# Check 2: Is DNS port open?
nc -zv 8.8.8.8 53
# Check 3: What DNS servers are configured?
cat /etc/resolv.conf
resolvectl status
# Check 4: Is it a specific domain or all DNS?
dig google.com
dig @8.8.8.8 google.com
# Check 5: Flush local cache
sudo resolvectl flush-caches # systemd
sudo systemctl restart nscd # if using nscd
DNS Propagation
When you change DNS records, it takes time to propagate:
# Check TTL of current record
dig +nocmd +noall +answer example.com
# Query different DNS servers to see propagation
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com
dig @9.9.9.9 example.com
DNS Propagation Tips:
- Lower TTL before making changes (e.g., 300 seconds)
- Wait for old TTL to expire before changing
- Propagation typically takes 24-48 hours globally
Quick Reference
Public DNS Servers
| Provider | Primary | Secondary | Features |
|---|---|---|---|
| 8.8.8.8 | 8.8.4.4 | Fast, reliable | |
| Cloudflare | 1.1.1.1 | 1.0.0.1 | Privacy-focused, fastest |
| Quad9 | 9.9.9.9 | 149.112.112.112 | Security-focused, blocks malware |
| OpenDNS | 208.67.222.222 | 208.67.220.220 | Parental controls available |
Essential Commands Cheatsheet
# Query DNS
dig example.com
dig +short example.com
dig @8.8.8.8 example.com MX
# Trace resolution
dig +trace example.com
# Reverse lookup
dig -x 93.184.216.34
# Check configuration
cat /etc/resolv.conf
resolvectl status
# Flush cache
sudo resolvectl flush-caches
# Test local DNS server
dig @127.0.0.1 example.com
Summary
Key Takeaways:
- DNS translates domain names to IP addresses using a hierarchical system
- Common record types: A (IPv4), AAAA (IPv6), CNAME (alias), MX (mail), TXT (text)
- Use
digfor detailed DNS queries,hostfor quick lookups - Configure DNS clients via
/etc/resolv.confor systemd-resolved - Use dnsmasq for simple local DNS, BIND9 for full-featured DNS servers
- Secure DNS with DNSSEC and DNS over TLS/HTTPS
DNS is fundamental to how the internet works. Understanding it deeply will help you troubleshoot network issues faster and build more robust infrastructure.