Every time you type a URL into your browser, send an email, or make an API call, the Domain Name System (DNS) translates the human-readable domain name into an IP address that computers can use to route traffic. This happens billions of times per day across the internet, usually in under 50 milliseconds. When DNS works, nobody notices. When DNS fails, the entire internet appears to be down.
Despite being one of the most critical pieces of internet infrastructure, DNS is poorly understood by most developers. This guide covers how DNS actually works at the protocol level, the different record types and when to use each, how to secure DNS against attacks, and how to optimize DNS for performance and reliability.
Chapter 1: How DNS Resolution Works
The Complete Resolution Process
When you type "www.example.com" into your browser, here's exactly what happens:
Step 1: Browser Cache. The browser checks its own DNS cache. Chrome, Firefox, and Safari all maintain internal DNS caches. If the domain was recently resolved, the cached result is used immediately. Chrome's cache can be viewed at chrome://net-internals/#dns.
Step 2: Operating System Cache. If the browser cache misses, the OS resolver is consulted. On Linux, this is managed by systemd-resolved or nscd. On macOS, it's mDNSResponder. The OS also checks the /etc/hosts file for manual overrides.
Step 3: Recursive Resolver. If the OS cache misses, the query goes to the configured DNS resolver (usually your ISP's DNS, or a public resolver like 1.1.1.1 or 8.8.8.8). This resolver is responsible for finding the answer through an iterative process.
Step 4: Root Name Servers. The recursive resolver asks a root name server: "Who is responsible for .com?" There are 13 root server clusters (a.root-servers.net through m.root-servers.net), operated by various organizations. They respond with the addresses of the .com TLD (Top-Level Domain) name servers.
Step 5: TLD Name Servers. The recursive resolver asks the .com TLD server: "Who is responsible for example.com?" The TLD server responds with the authoritative name servers for example.com (e.g., ns1.registrar.com, ns2.registrar.com).
Step 6: Authoritative Name Servers. The recursive resolver asks the authoritative name server: "What is the A record for www.example.com?" The authoritative server responds with the IP address: 93.184.216.34. This answer is cached by the recursive resolver based on the TTL (Time To Live) value.
# Trace the entire DNS resolution path
dig +trace www.example.com
# Output shows each step:
# . IN NS a.root-servers.net. (root)
# com. IN NS a.gtld-servers.net. (TLD)
# example.com. IN NS ns1.registrar.com. (authoritative)
# www.example.com. IN A 93.184.216.34 (final answer)
# Query a specific DNS server
dig @1.1.1.1 www.example.com A
# Get all records for a domain
dig example.com ANY
# Check specific record types
dig example.com MX # Mail servers
dig example.com TXT # Text records (SPF, DKIM, etc.)
dig example.com AAAA # IPv6 address
dig example.com CNAME # Canonical name (alias)
dig example.com NS # Name servers
dig example.com SOA # Start of Authority
Chapter 2: DNS Record Types β Complete Reference
A and AAAA Records
A records map a domain to an IPv4 address. AAAA records map to IPv6 addresses. These are the most fundamental DNS records.
# A record: domain β IPv4
example.com. 300 IN A 93.184.216.34
www.example.com. 300 IN A 93.184.216.34
# AAAA record: domain β IPv6
example.com. 300 IN AAAA 2606:2800:220:1:248:1893:25c8:1946
# Multiple A records for round-robin load balancing
api.example.com. 60 IN A 10.0.1.10
api.example.com. 60 IN A 10.0.1.11
api.example.com. 60 IN A 10.0.1.12
CNAME Records
CNAME (Canonical Name) records create aliases. They point one domain to another domain, not to an IP address.
# CNAME record: alias β canonical name
blog.example.com. 300 IN CNAME example.com.
shop.example.com. 300 IN CNAME myshop.shopify.com.
status.example.com. 300 IN CNAME status.example.statuspage.io.
# IMPORTANT RULES:
# 1. CNAME cannot coexist with other record types (except DNSSEC)
# 2. CNAME at the zone apex (example.com) is NOT ALLOWED by RFC
# Use ALIAS/ANAME records instead (provider-specific)
# 3. CNAME creates an extra DNS lookup (slower than A records)
MX Records
MX (Mail Exchange) records specify which servers handle email for a domain. The priority value determines the order β lower numbers are tried first.
# MX records for email routing
example.com. 300 IN MX 10 mail1.example.com.
example.com. 300 IN MX 20 mail2.example.com. # Backup
example.com. 300 IN MX 30 mail3.example.com. # Secondary backup
# Google Workspace
example.com. 300 IN MX 1 aspmx.l.google.com.
example.com. 300 IN MX 5 alt1.aspmx.l.google.com.
example.com. 300 IN MX 5 alt2.aspmx.l.google.com.
example.com. 300 IN MX 10 alt3.aspmx.l.google.com.
example.com. 300 IN MX 10 alt4.aspmx.l.google.com.
TXT Records
TXT records store arbitrary text data. They're used extensively for domain verification, email authentication, and security policies.
# SPF (Sender Policy Framework) β declares which servers can send email
example.com. 300 IN TXT "v=spf1 mx a:mail.example.com ip4:93.184.216.0/24 include:_spf.google.com ~all"
# DKIM (DomainKeys Identified Mail) β cryptographic email signing
default._domainkey.example.com. 300 IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUA..."
# DMARC (Domain-based Message Authentication)
_dmarc.example.com. 300 IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; ruf=mailto:dmarc@example.com; pct=100"
# Domain verification (for Google, Cloudflare, etc.)
example.com. 300 IN TXT "google-site-verification=abc123..."
example.com. 300 IN TXT "v=spf1 include:_spf.google.com ~all"
# CAA (Certificate Authority Authorization) β which CAs can issue certs
example.com. 300 IN CAA 0 issue "letsencrypt.org"
example.com. 300 IN CAA 0 issuewild "letsencrypt.org"
example.com. 300 IN CAA 0 iodef "mailto:security@example.com"
SRV Records
SRV (Service) records specify the location of specific services. They include priority, weight, port, and target host.
# Format: _service._protocol.domain. TTL IN SRV priority weight port target
# SIP server
_sip._tcp.example.com. 300 IN SRV 10 60 5060 sip1.example.com.
_sip._tcp.example.com. 300 IN SRV 10 40 5060 sip2.example.com.
# XMPP/Jabber
_xmpp-server._tcp.example.com. 300 IN SRV 5 0 5269 xmpp.example.com.
_xmpp-client._tcp.example.com. 300 IN SRV 5 0 5222 xmpp.example.com.
# CalDAV/CardDAV (calendar and contacts)
_caldavs._tcp.example.com. 300 IN SRV 0 0 443 dav.example.com.
_carddavs._tcp.example.com. 300 IN SRV 0 0 443 dav.example.com.
Chapter 3: DNS Security β DNSSEC
Standard DNS has no authentication. When your recursive resolver asks for the IP of example.com, it trusts whatever answer it receives. An attacker who can intercept or spoof DNS responses can redirect traffic to malicious servers. This is called DNS spoofing or DNS cache poisoning.
DNSSEC (DNS Security Extensions) adds cryptographic signatures to DNS records. The authoritative name server signs each record with a private key, and resolvers verify the signature using the corresponding public key. If the signature doesn't match, the resolver rejects the response.
# Check if a domain has DNSSEC enabled
dig +dnssec example.com A
# Look for the RRSIG (resource record signature) in the response
# If present, DNSSEC is configured
# Validate DNSSEC chain of trust
dig +sigchase +trusted-key=./root.keys example.com A
# Check DNSSEC status using an online tool:
# https://dnssec-analyzer.verisignlabs.com/
# DNSSEC record types:
# DNSKEY β Public key used to verify signatures
# RRSIG β Signature for a set of DNS records
# DS β Delegation Signer (links parent zone to child zone's key)
# NSEC/NSEC3 β Authenticated denial of existence
DNS-over-HTTPS (DoH) and DNS-over-TLS (DoT)
Traditional DNS queries are sent in plaintext over UDP port 53. Anyone on the network path can see which domains you're resolving. DNS-over-HTTPS (DoH) and DNS-over-TLS (DoT) encrypt DNS queries to prevent eavesdropping.
# DNS-over-HTTPS query using curl
curl -s -H 'accept: application/dns-json' 'https://1.1.1.1/dns-query?name=example.com&type=A'
# Response:
# {"Status":0,"TC":false,"RD":true,"RA":true,"AD":true,
# "Answer":[{"name":"example.com","type":1,"TTL":300,
# "data":"93.184.216.34"}]}
# Configure systemd-resolved for DNS-over-TLS (Linux)
# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com
DNSOverTLS=yes
DNSSEC=yes
# Restart resolved
sudo systemctl restart systemd-resolved
# Verify DoT is working
resolvectl status
Chapter 4: DNS-Based Load Balancing and Failover
Round-Robin DNS
The simplest form of DNS-based load balancing: return multiple A records for a domain, and clients connect to a random one.
# Multiple A records β clients get all IPs and choose one
api.example.com. 60 IN A 10.0.1.10
api.example.com. 60 IN A 10.0.1.11
api.example.com. 60 IN A 10.0.1.12
# Limitations:
# - No health checking (dead servers still receive traffic)
# - No geographic awareness
# - Uneven distribution (caching causes some IPs to get more traffic)
# - Cannot weight servers differently
GeoDNS β Geographic Load Balancing
GeoDNS resolves domain names to different IP addresses based on the client's geographic location. Cloudflare, Route 53, and NS1 all offer GeoDNS.
# AWS Route 53 Geolocation Routing
# European users β EU server
# US users β US server
# Everyone else β US server (default)
# This is configured via the Route 53 console or API:
# Record Set 1:
# Name: api.example.com
# Type: A
# Routing Policy: Geolocation
# Location: Europe
# Value: 52.16.xx.xx (eu-west-1)
#
# Record Set 2:
# Name: api.example.com
# Type: A
# Routing Policy: Geolocation
# Location: North America
# Value: 54.xx.xx.xx (us-east-1)
#
# Record Set 3:
# Name: api.example.com
# Type: A
# Routing Policy: Geolocation
# Location: Default
# Value: 54.xx.xx.xx (us-east-1)
Health-Checked DNS Failover
# AWS Route 53 Health-Checked Failover
# Primary β US East server
# Secondary β US West server (only if primary fails health check)
# Health Check Configuration:
# Protocol: HTTPS
# Hostname: api.example.com
# Port: 443
# Path: /health
# Interval: 10 seconds
# Failure threshold: 3 (mark unhealthy after 3 consecutive failures)
# Success threshold: 2 (mark healthy after 2 consecutive successes)
# Failover Record Set:
# Primary:
# Name: api.example.com
# Type: A
# Routing Policy: Failover
# Failover Type: Primary
# Health Check: hc-primary-api
# Value: 54.xx.xx.xx
#
# Secondary:
# Name: api.example.com
# Type: A
# Routing Policy: Failover
# Failover Type: Secondary
# Value: 35.xx.xx.xx
Chapter 5: TTL Strategy and Propagation
TTL (Time To Live) determines how long DNS resolvers cache a record before re-querying the authoritative server. Choosing the right TTL is a balance between performance and agility.
# TTL recommendations by record type and use case:
# Static infrastructure (rarely changes)
# Mail servers, name servers
example.com. 86400 IN NS ns1.example.com. # 24 hours
example.com. 86400 IN MX 10 mail.example.com. # 24 hours
# Semi-static (changes occasionally)
# Main website, established services
www.example.com. 3600 IN A 93.184.216.34 # 1 hour
example.com. 3600 IN A 93.184.216.34 # 1 hour
# Dynamic / failover (changes frequently or needs fast failover)
# API endpoints, CDN origins
api.example.com. 60 IN A 10.0.1.10 # 1 minute
cdn.example.com. 300 IN CNAME d1234.cloudfront.net. # 5 minutes
# PRE-MIGRATION: Lower TTL before making changes
# Step 1: 48 hours before migration, lower TTL to 60 seconds
# Step 2: Wait 48 hours for old TTL to expire everywhere
# Step 3: Make the DNS change
# Step 4: Wait for propagation (now takes ~60 seconds)
# Step 5: After confirming the change works, raise TTL back up
Chapter 6: Split-Horizon DNS
Split-horizon (split-brain) DNS returns different answers depending on who is asking. Internal clients get internal IP addresses; external clients get public IP addresses.
# BIND9 split-horizon configuration
# Define internal network
acl "internal" {
10.0.0.0/8;
172.16.0.0/12;
192.168.0.0/16;
localhost;
};
# Internal view (for internal clients)
view "internal" {
match-clients { "internal"; };
zone "example.com" {
type master;
file "/etc/bind/zones/internal.example.com";
};
};
# External view (for everyone else)
view "external" {
match-clients { any; };
zone "example.com" {
type master;
file "/etc/bind/zones/external.example.com";
};
};
# Internal zone file:
# app.example.com. 300 IN A 10.0.1.50 (internal IP)
# External zone file:
# app.example.com. 300 IN A 93.184.216.34 (public IP)
Chapter 7: Common DNS Misconfigurations and Troubleshooting
# 1. Missing reverse DNS (PTR) record
# Impact: Email delivery failures, SSH warnings
# Fix: Set PTR record via your hosting provider
dig -x 93.184.216.34 # Should return: example.com
# 2. CNAME at zone apex
# WRONG: example.com. CNAME myapp.herokuapp.com.
# This violates RFC 1034 and breaks MX, NS, and other records
# FIX: Use ALIAS/ANAME (provider-specific) or A record with IP
# 3. Lame delegation
# Impact: Intermittent DNS failures
# Cause: NS records point to servers that don't know about the zone
# Check: dig @ns1.example.com example.com SOA
# Fix: Ensure all listed name servers actually serve the zone
# 4. Missing or incorrect SPF/DKIM/DMARC
# Impact: Emails going to spam or being rejected
# Check:
dig example.com TXT | grep spf
dig default._domainkey.example.com TXT
dig _dmarc.example.com TXT
# 5. TTL too high during migration
# Impact: Some users see old IP for hours/days
# Fix: Lower TTL to 60s at least 48 hours before any DNS change
# 6. Wildcard records hiding problems
# *.example.com. A 93.184.216.34
# This catches ALL subdomains, including typos
# Impact: Hides misconfigurations, creates security risks
# DNS debugging tools
dig +short example.com A # Quick lookup
dig +trace example.com A # Full resolution path
nslookup example.com 8.8.8.8 # Query specific resolver
host example.com # Simple lookup
whois example.com # Domain registration info
curl -s https://dns.google/resolve?name=example.com # Google's DNS API
DNS is deceptively simple on the surface but endlessly deep in its implications for performance, security, and reliability. Understanding DNS at the protocol level is essential for anyone building and operating internet-facing applications.
ZeonEdge provides DNS architecture consulting, DNSSEC implementation, and DNS-based failover design. Whether you're setting up DNS for a new domain or optimizing DNS for a high-traffic global application, our infrastructure engineers have the expertise to get it right. Contact our networking team for DNS architecture assistance.
Marcus Rodriguez
Lead DevOps Engineer specializing in CI/CD pipelines, container orchestration, and infrastructure automation.