- Published on
DNS Complete Guide: Name Servers, DDNS, nslookup — From Domain Registration to Troubleshooting
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 1. Understanding How DNS Works
- 2. Name Servers Deep Dive
- 3. DNS Record Types Complete Reference
- 4. Domain Registration and Transfer Practical Guide
- 5. DDNS (Dynamic DNS) Complete Guide
- 6. nslookup Complete Usage Guide
- 7. Mastering the dig Command
- 8. DNS Security
- 9. 10 Real-World Troubleshooting Scenarios
- Scenario 1: Domain Registered But Cannot Access (Propagation Delay)
- Scenario 2: SSL Certificate Issuance Failure (CAA Record)
- Scenario 3: Emails Going to Spam (SPF/DKIM/DMARC)
- Scenario 4: Subdomain Not Working
- Scenario 5: Some Users Cannot Access After DNS Change (TTL Cache)
- Scenario 6: nslookup Works But Browser Cannot Connect
- Scenario 7: DNS Outage After Domain Transfer
- Scenario 8: K8s Internal DNS Resolution Failure (CoreDNS, ndots)
- Scenario 9: Origin Server IP Exposed After CDN Integration (DNS Leak)
- Scenario 10: DDNS Updates Not Reflecting
- 10. DNS Service Comparison
- Quiz
- References
1. Understanding How DNS Works
What is DNS? The Internet's Phone Book
DNS (Domain Name System) is the system that translates human-readable domain names (e.g., www.example.com) into computer-understandable IP addresses (e.g., 93.184.216.34). It was first proposed by Paul Mockapetris in 1983 through RFC 882 and 883, with RFC 1034 and 1035 serving as the current base specifications.
Without DNS, we would need to type IP addresses directly to visit any website. DNS is the most fundamental yet critical component of internet infrastructure.
User input: www.example.com
|
DNS Resolution
|
IP address: 93.184.216.34
|
HTTP request to server
DNS Hierarchy: From Root to Subdomain
DNS is a hierarchical distributed database with a tree structure. From top to bottom:
. (Root)
/ \
com org net kr jp ... (TLD - Top Level Domain)
|
example (SLD - Second Level Domain)
/ \
www mail api (Subdomain)
Role of each level:
| Level | Example | Managed By |
|---|---|---|
| Root (.) | . | ICANN / IANA |
| TLD | .com, .kr, .org | Registry (Verisign, KISA, etc.) |
| SLD | example.com | Domain owner |
| Subdomain | www.example.com | Domain owner |
An FQDN (Fully Qualified Domain Name) includes a trailing dot: www.example.com.
DNS Query Flow: Recursive vs Iterative
DNS resolution uses a combination of two query types.
Recursive Query: The client asks a recursive resolver to "give me the final answer." The resolver handles everything on the client's behalf.
Iterative Query: The recursive resolver asks each name server "who knows about this domain?" and each server responds with "I don't know, but ask over there," pointing to the next server.
[User PC] -- Recursive Query --> [Recursive Resolver (ISP/8.8.8.8)]
|
Iterative Queries Begin
|
+---------------+---------------+
v v v
[Root Server] [TLD Server] [Authoritative NS]
".com is here" "example.com "IP is 93.x.x.x"
is here"
Detailed flow:
- User types
www.example.comin the browser - Check browser cache, OS cache, hosts file
- OS sends recursive query to configured resolver (e.g., 8.8.8.8)
- Recursive resolver checks cache; if miss, queries Root servers iteratively
- Root server: "
.comTLD server isa.gtld-servers.net" - Recursive resolver queries the TLD server
- TLD server: "Name server for
example.comisns1.example.com" - Recursive resolver queries the authoritative name server
- Authoritative NS: "IP for
www.example.comis93.184.216.34" - Recursive resolver caches the result and responds to the client
13 Root Servers and Anycast
The 13 root servers (A through M) are the starting point of all DNS. Despite being only 13 in name, Anycast technology distributes them across over 1,700 instances worldwide.
| Root Server | Operator | Instances (approx.) |
|---|---|---|
| A | Verisign | 10+ |
| B | USC-ISI | 6+ |
| C | Cogent | 10+ |
| D | University of Maryland | 200+ |
| E | NASA | 300+ |
| F | ISC | 300+ |
| J | Verisign | 200+ |
| K | RIPE NCC | 100+ |
| L | ICANN | 200+ |
| M | WIDE Project | 10+ |
What is Anycast? A technique that assigns the same IP address to multiple physical servers. User queries are automatically routed to the nearest instance via BGP routing. This is why only 13 root server IPs can serve the entire world with fast responses.
DNS Caching: The Key to Performance
DNS caching occurs at multiple levels:
[Browser Cache] -> [OS Cache] -> [Recursive Resolver Cache] -> [TTL from each NS response]
Chrome: chrome://net-internals/#dns to inspect
Windows: ipconfig /displaydns
Linux: systemd-resolve --statistics
macOS: sudo dscacheutil -flushcache
Understanding TTL (Time To Live):
example.com. 3600 IN A 93.184.216.34
^
TTL = 3600 seconds (1 hour)
TTL strategy based on values:
| TTL Value | Use Case | Pros | Cons |
|---|---|---|---|
| 60s | Before DNS changes | Fast propagation | More queries, slower responses |
| 300s (5 min) | General services | Balanced choice | - |
| 3600s (1 hour) | Stable services | Fast responses, fewer queries | Slow change propagation |
| 86400s (1 day) | Rarely changing records | Best performance | Difficult emergency changes |
Pro tip: Lower TTL to 60 seconds before making DNS changes, then raise it back once propagation is complete.
2. Name Servers Deep Dive
Authoritative vs Recursive Name Servers
| Aspect | Authoritative NS | Recursive Resolver |
|---|---|---|
| Role | Holds definitive info for a domain | Traverses DNS tree on behalf of clients |
| Data | Original data from zone files | Cached data |
| Example | ns1.cloudflare.com | 8.8.8.8 (Google DNS) |
| Operator | Domain owner/hosting provider | ISP, Google, Cloudflare |
| Response flag | AA (Authoritative Answer) bit set | No AA bit |
Primary (Master) vs Secondary (Slave) Name Servers
Authoritative name servers are further divided into Primary and Secondary.
[Primary NS] --Zone Transfer--> [Secondary NS]
(read/write) (read only)
Manages original zone file Backup when Primary fails
Add/modify/delete records Load distribution role
Why are Secondary servers needed?
- High availability: Secondary responds when Primary fails
- Load distribution: Queries are spread across servers
- Geographic distribution: Placed near users
- RFC 2182 recommends: At least 2 name servers
Zone Transfer: AXFR vs IXFR
Methods for replicating zone data from Primary to Secondary.
| Method | Description | Use Case |
|---|---|---|
| AXFR | Full zone file transfer | Initial sync, data inconsistency |
| IXFR | Incremental transfer (changes only) | Regular incremental updates |
# Test AXFR (should be blocked from external sources for security)
dig @ns1.example.com example.com AXFR
# Check synchronization via SOA record Serial
dig @ns1.example.com example.com SOA +short
# 2024032301 ns1.example.com. admin.example.com. ...
SOA Record Serial Number:
Conventionally uses YYYYMMDDNN format (e.g., 2026032301). When the Serial increases, Secondary servers initiate zone transfers.
Why Glue Records Are Necessary
When domain example.com's name server is ns1.example.com, a circular reference problem occurs:
Q: What is example.com's IP?
-> example.com's name server is ns1.example.com
-> What is ns1.example.com's IP?
-> Need to ask example.com's name server, but...
-> Circular reference!
Solution: Glue Records
Register the name server's IP directly in the parent TLD server:
;; Delegation records in .com TLD server
example.com. IN NS ns1.example.com.
example.com. IN NS ns2.example.com.
;; Glue records (Additional Section)
ns1.example.com. IN A 203.0.113.1
ns2.example.com. IN A 203.0.113.2
Major DNS Software
| Software | Type | Features |
|---|---|---|
| BIND9 | Auth/Recursive | Oldest DNS server. Full feature set |
| PowerDNS | Auth only | DB backend support (MySQL, PostgreSQL) |
| CoreDNS | Auth/Recursive | Go-based, plugin architecture, K8s default DNS |
| Unbound | Recursive only | Lightweight, security-focused, DNSSEC validation by default |
| Knot DNS | Auth only | High performance, modern design |
| dnsmasq | Lightweight caching | For small networks/home routers |
CoreDNS in Kubernetes
Since Kubernetes 1.13, CoreDNS is the default DNS server. It enables Pods to communicate using service names.
# CoreDNS Corefile example
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
K8s DNS Resolution Rules:
# Accessing services from a Pod
my-service -> my-service.default.svc.cluster.local
my-service.other-ns -> my-service.other-ns.svc.cluster.local
my-service.other-ns.svc.cluster.local -> Full FQDN
# Pod's /etc/resolv.conf
nameserver 10.96.0.10 # CoreDNS ClusterIP
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5 # If fewer than 5 dots, append search domains
What ndots:5 means:
api.example.com has only 2 dots (less than 5), so K8s first tries api.example.com.default.svc.cluster.local etc. This can slow down external DNS resolution. For external domains, use FQDN (add trailing .).
3. DNS Record Types Complete Reference
Core Record Types
| Type | Purpose | Example |
|---|---|---|
| A | IPv4 address mapping | example.com. IN A 93.184.216.34 |
| AAAA | IPv6 address mapping | example.com. IN AAAA 2606:2800:220:1:: |
| CNAME | Alias (points to another domain) | www.example.com. IN CNAME example.com. |
| MX | Mail server designation | example.com. IN MX 10 mail.example.com. |
| TXT | Text info (SPF, DKIM, etc.) | example.com. IN TXT "v=spf1 ..." |
| NS | Name server designation | example.com. IN NS ns1.example.com. |
| SOA | Zone authority info | Serial, refresh, expiry, etc. |
| SRV | Service location | _sip._tcp.example.com. IN SRV 10 60 5060 sip.example.com. |
| CAA | Certificate authority authorization | example.com. IN CAA 0 issue "letsencrypt.org" |
| PTR | Reverse lookup (IP to domain) | 34.216.184.93.in-addr.arpa. IN PTR example.com. |
| NAPTR | URI transformation rules | Used in SIP, ENUM |
CNAME Restrictions
# OK - CNAME on subdomain
www.example.com. IN CNAME example.com.
# BAD - Cannot use CNAME on root domain (Apex)!
# example.com. IN CNAME other.com. (RFC violation)
# Solutions: ALIAS/ANAME (non-standard) or Cloudflare's CNAME Flattening
Why can't you use CNAME on the apex? CNAME cannot coexist with any other records for the same name. But apex domains must have SOA and NS records, which conflict with CNAME.
Email Authentication Trio: SPF, DKIM, DMARC
Three DNS-based authentication systems to prevent email spam and phishing.
SPF (Sender Policy Framework):
example.com. IN TXT "v=spf1 include:_spf.google.com include:sendgrid.net ip4:203.0.113.0/24 -all"
| Mechanism | Meaning |
|---|---|
include:domain | Also allow that domain's SPF |
ip4:CIDR | Allow that IP range |
a | Allow domain's A record IP |
mx | Allow MX record IPs |
-all | Reject all others |
~all | Soft fail all others |
DKIM (DomainKeys Identified Mail):
selector1._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEB..."
The mail server adds a digital signature to emails, and the receiving server verifies it using the public key from DNS.
DMARC (Domain-based Message Authentication, Reporting, and Conformance):
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com; pct=100"
| Policy | Meaning |
|---|---|
p=none | Monitor only (collect reports) |
p=quarantine | Send suspicious mail to spam |
p=reject | Reject failed authentication |
Practical Zone File Example (BIND Format)
$TTL 3600
$ORIGIN example.com.
@ IN SOA ns1.example.com. admin.example.com. (
2026032301 ; Serial (YYYYMMDDNN)
3600 ; Refresh (1 hour)
900 ; Retry (15 min)
1209600 ; Expire (2 weeks)
86400 ; Minimum TTL (1 day)
)
; Name servers
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
; A records
@ IN A 203.0.113.10
www IN A 203.0.113.10
api IN A 203.0.113.20
; AAAA record
@ IN AAAA 2001:db8::10
; CNAME
blog IN CNAME example.github.io.
docs IN CNAME readthedocs.io.
; MX records (lower number = higher priority)
@ IN MX 10 mail.example.com.
@ IN MX 20 mail2.example.com.
mail IN A 203.0.113.30
; TXT records
@ IN TXT "v=spf1 include:_spf.google.com -all"
_dmarc IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
; SRV record
_sip._tcp IN SRV 10 60 5060 sip.example.com.
; CAA records
@ IN CAA 0 issue "letsencrypt.org"
@ IN CAA 0 issuewild "letsencrypt.org"
4. Domain Registration and Transfer Practical Guide
Domain Registration Structure
[ICANN] --manages--> [Registry] --delegates--> [Registrar] --sells--> [Reseller]
(Verisign, etc.) (Namecheap, etc.) (Hosting, etc.)
Registry: Manages an entire TLD (e.g., .com is Verisign)
Registrar: ICANN-accredited to handle domain registration
Reseller: Resale partner of a registrar
Popular Registrar Comparison
| Registrar | .com Annual Cost | Features |
|---|---|---|
| Cloudflare Registrar | ~10.11 USD | At-cost pricing, zero markup |
| Namecheap | ~8.88 USD (first year) | Watch renewal price increases |
| Porkbun | ~9.73 USD | Good value |
| Google Domains | Service ended, migrated to Squarespace | Ended in 2023 |
| GoDaddy | ~12.99 USD | Large marketplace, upselling concerns |
| Gandi | ~15.00 USD | Privacy by default |
Why Cloudflare Registrar is recommended:
- Wholesale (at-cost) pricing with zero markup
- Renewal price stays the same
- Free DNSSEC and Whois Privacy
- Easy integration with Cloudflare CDN/security
Domain Transfer Procedure
1. Disable Transfer Lock at current registrar
2. Obtain Auth Code (EPP code) from current registrar
3. Initiate Transfer at new registrar + enter Auth Code
4. Confirm approval email from old registrar (5-7 day wait)
5. Verify DNS settings after transfer completes
Important notes:
- 60-day transfer lock after registration/transfer (ICANN 60-Day Lock)
- Cannot transfer domains expiring within 15 days
- Country-code TLDs (.kr, .jp, etc.) may have separate procedures
Whois and RDAP
# Whois lookup
whois example.com
# RDAP (Whois successor, JSON-based)
curl -s "https://rdap.verisign.com/com/v1/domain/example.com" | jq .
RDAP (Registration Data Access Protocol) advantages:
- Standardized JSON responses
- Secure transmission via HTTPS
- Internationalization (IDN) support
- Differentiated access control
5. DDNS (Dynamic DNS) Complete Guide
Why You Need DDNS
Residential internet connections typically assign dynamic IP addresses. ISPs periodically change your IP (or when the router restarts), making it difficult to run servers from home without a static IP.
Problem:
Home server IP: 211.xxx.xxx.100 (yesterday)
Home server IP: 211.xxx.xxx.200 (today) - IP changed!
DNS: myserver.example.com -> 211.xxx.xxx.100 (registered yesterday)
-> Cannot connect!
Solution (DDNS):
Detect IP change -> Automatically update DNS record
myserver.example.com -> 211.xxx.xxx.200 (auto-updated)
DDNS Service Comparison
| Service | Free | Custom Domain | Update Interval | Features |
|---|---|---|---|---|
| DuckDNS | Free | No (*.duckdns.org only) | Real-time | Fully free, open source |
| No-IP | Free (30-day renewal) | Paid | 5 min | 3 free hostnames |
| Cloudflare DDNS | Free | Yes (own domain) | Real-time | Need to implement via API |
| Synology DDNS | Free | No (*.synology.me) | Real-time | Synology NAS only |
| Dynu | Free | Yes (up to 4) | Real-time | IPv6 support |
Setup 1: ddclient (Linux)
# Install
sudo apt install ddclient
# /etc/ddclient.conf configuration (Cloudflare example)
protocol=cloudflare
use=web, web=https://api.ipify.org
zone=example.com
login=your-email@example.com
password=your-cloudflare-api-token
myserver.example.com
# Start service
sudo systemctl enable ddclient
sudo systemctl start ddclient
# Check status
sudo systemctl status ddclient
sudo ddclient -query
Setup 2: DIY DDNS with Cloudflare API
#!/bin/bash
# cloudflare-ddns.sh
# Configuration
CF_API_TOKEN="your-api-token-here"
CF_ZONE_ID="your-zone-id-here"
CF_RECORD_NAME="myserver.example.com"
CF_RECORD_ID="your-record-id-here"
# Get current public IP
CURRENT_IP=$(curl -s https://api.ipify.org)
# Get IP registered in DNS
DNS_IP=$(dig +short "$CF_RECORD_NAME" @1.1.1.1)
# Update if IP has changed
if [ "$CURRENT_IP" != "$DNS_IP" ]; then
echo "IP changed: $DNS_IP -> $CURRENT_IP"
curl -s -X PUT \
"https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$CF_RECORD_ID" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$CF_RECORD_NAME\",\"content\":\"$CURRENT_IP\",\"ttl\":60,\"proxied\":false}"
echo "DNS updated successfully"
else
echo "IP unchanged: $CURRENT_IP"
fi
# Add to crontab (run every 5 minutes)
crontab -e
# */5 * * * * /home/user/cloudflare-ddns.sh >> /var/log/ddns.log 2>&1
Setup 3: Docker + DDNS Auto-Update
# docker-compose.yml
version: '3'
services:
cloudflare-ddns:
image: oznu/cloudflare-ddns:latest
restart: always
environment:
- API_KEY=your-cloudflare-api-token
- ZONE=example.com
- SUBDOMAIN=myserver
- PROXIED=false
- RRTYPE=A
- DELETE_ON_STOP=false
- DNS_SERVER=1.1.1.1
docker-compose up -d
Home Server Stack: DDNS + Let's Encrypt + Nginx Proxy Manager
[Internet] -> [Router Port Forwarding] -> [Nginx Proxy Manager] -> [Services]
|
Let's Encrypt
Auto SSL Issuance
# docker-compose.yml - Home server stack
version: '3'
services:
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
restart: unless-stopped
ports:
- '80:80'
- '443:443'
- '81:81' # Admin panel
volumes:
- ./npm-data:/data
- ./npm-letsencrypt:/etc/letsencrypt
cloudflare-ddns:
image: oznu/cloudflare-ddns:latest
restart: always
environment:
- API_KEY=your-cf-token
- ZONE=example.com
- SUBDOMAIN=home
Port Forwarding + Firewall Configuration
Router settings:
External 80 -> Internal 192.168.1.100:80
External 443 -> Internal 192.168.1.100:443
Linux firewall (UFW):
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Security considerations:
- Never expose port 22 (SSH) externally (use VPN or Tailscale instead)
- Block admin panel (port 81) from external access
- Use fail2ban for brute force protection
- Enable Cloudflare Proxy to hide origin IP
6. nslookup Complete Usage Guide
Basic Usage
# Basic lookup
nslookup example.com
# Server: 8.8.8.8
# Address: 8.8.8.8#53
#
# Non-authoritative answer:
# Name: example.com
# Address: 93.184.216.34
# Query using a specific DNS server
nslookup example.com 1.1.1.1
Querying by Record Type
# MX records (mail servers)
nslookup -type=mx gmail.com
# gmail.com mail exchanger = 5 gmail-smtp-in.l.google.com.
# gmail.com mail exchanger = 10 alt1.gmail-smtp-in.l.google.com.
# AAAA records (IPv6)
nslookup -type=aaaa google.com
# TXT records (SPF, DKIM, etc.)
nslookup -type=txt example.com
# NS records (name servers)
nslookup -type=ns example.com
# SOA records (zone information)
nslookup -type=soa example.com
# CAA records (certificate authority authorization)
nslookup -type=caa example.com
# SRV records (service location)
nslookup -type=srv _sip._tcp.example.com
# ANY (all records - some servers block this)
nslookup -type=any example.com
Interactive Mode
nslookup
> server 8.8.8.8 # Change DNS server
> set type=mx # Set record type
> gmail.com # Query
> set type=txt
> example.com
> set debug # Debug mode ON
> example.com # Detailed output
> set d2 # More detailed debug
> exit
Reverse Lookup (PTR)
# IP -> Domain lookup
nslookup 8.8.8.8
# 8.8.8.8.in-addr.arpa name = dns.google.
nslookup 1.1.1.1
# 1.1.1.1.in-addr.arpa name = one.one.one.one.
10 Practical Examples
# 1. Check name servers for a domain
nslookup -type=ns example.com
# 2. Check mail servers (email debugging)
nslookup -type=mx company.com
# 3. Check SPF records (email spam issues)
nslookup -type=txt example.com
# 4. Compare Google DNS vs Cloudflare DNS
nslookup example.com 8.8.8.8
nslookup example.com 1.1.1.1
# 5. Check IPv6 addresses
nslookup -type=aaaa facebook.com
# 6. Test wildcard subdomains
nslookup nonexistent-sub.example.com
# 7. Check CAA records (before SSL certificate issuance)
nslookup -type=caa example.com
# 8. Reverse DNS lookup (identify IP owner)
nslookup 203.0.113.1
# 9. Trace CNAME chains
nslookup -type=cname www.example.com
# 10. Check SOA record for DNS administrator info
nslookup -type=soa example.com
7. Mastering the dig Command
dig vs nslookup Differences
| Aspect | dig | nslookup |
|---|---|---|
| Output | Detailed (section-based) | Brief |
| DNSSEC | Supported (+dnssec) | Not supported |
| Trace | Supported (+trace) | Not supported |
| Batch mode | Supported (-f) | Not supported |
| Installation | bind-utils/dnsutils | Usually pre-installed |
| Recommended for | DevOps/SRE | Quick checks |
Basic Usage
# Basic query
dig example.com
# Output structure:
# ;; QUESTION SECTION: <- Question
# ;example.com. IN A
#
# ;; ANSWER SECTION: <- Answer
# example.com. 3600 IN A 93.184.216.34
#
# ;; AUTHORITY SECTION: <- Authoritative name servers
# example.com. 3600 IN NS a.iana-servers.net.
#
# ;; ADDITIONAL SECTION: <- Additional info
# a.iana-servers.net. 3600 IN A 199.43.135.53
#
# ;; Query time: 23 msec
# ;; SERVER: 8.8.8.8#53(8.8.8.8)
Frequently Used Options
# Short output (IP only)
dig +short example.com
# 93.184.216.34
# Specific record types
dig example.com MX
dig example.com AAAA
dig example.com TXT
dig example.com NS
dig example.com SOA
dig example.com CAA
# Specify DNS server
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com
# Check response time only
dig example.com | grep "Query time"
# ;; Query time: 23 msec
Tracing from Root: +trace
# Trace entire DNS resolution from Root
dig +trace example.com
# Output (summary):
# . 518400 IN NS a.root-servers.net. <- Root
# com. 172800 IN NS a.gtld-servers.net. <- TLD
# example.com. 86400 IN NS a.iana-servers.net. <- Authoritative
# example.com. 3600 IN A 93.184.216.34 <- Final answer
This is one of the most useful commands for DNS troubleshooting. You can see exactly at which step a problem occurs.
DNSSEC Verification
# Check DNSSEC signature info
dig +dnssec example.com
# Verify DNSSEC validity
dig +sigchase +trusted-key=/etc/trusted-key.key example.com
# Query DNSSEC-related records directly
dig example.com DNSKEY
dig example.com DS
dig example.com RRSIG
dig example.com NSEC
Batch Queries
# Query all domains from a file at once
cat domains.txt
# example.com
# google.com
# github.com
dig -f domains.txt +short
# Batch query for specific record type
dig -f domains.txt MX +short
Advanced Options
# TCP mode (instead of UDP)
dig +tcp example.com
# Output specific sections only
dig +noall +answer example.com # Answer only
dig +noall +authority example.com # Authority section only
dig +noall +stats example.com # Statistics only
# Abbreviated output with TTL
dig +nocmd +noall +answer +ttlid example.com
# Reverse lookup
dig -x 8.8.8.8
# 8.8.8.8.in-addr.arpa. IN PTR dns.google.
# Check DNS server version via CHAOS class
dig @ns1.example.com version.bind CHAOS TXT
# EDNS Client Subnet test
dig +subnet=203.0.113.0/24 example.com @8.8.8.8
15 Practical Examples
# 1. Check authoritative response from specific name server
dig @ns1.example.com example.com +norecurse
# 2. Check DNS propagation (compare multiple DNS servers)
for dns in 8.8.8.8 1.1.1.1 9.9.9.9 208.67.222.222; do
echo "=== $dns ==="
dig @$dns example.com +short
done
# 3. Trace full CNAME chain
dig +trace +nodnssec www.example.com CNAME
# 4. Check MX record priorities
dig example.com MX +short | sort -n
# 5. Check SPF record
dig example.com TXT +short | grep spf
# 6. Check DKIM record
dig selector1._domainkey.example.com TXT +short
# 7. Check DMARC policy
dig _dmarc.example.com TXT +short
# 8. Check CAA records (before SSL issuance)
dig example.com CAA +short
# 9. Check SOA serial number (zone transfer sync)
dig example.com SOA +short
# 10. Compare response times (DNS performance test)
for i in $(seq 1 10); do
dig example.com @8.8.8.8 | grep "Query time"
done
# 11. Check IPv6 records
dig example.com AAAA +short
# 12. Verify wildcard DNS
dig random-subdomain.example.com +short
# 13. Check NSEC/NSEC3 for DNSSEC authenticated denial
dig nonexistent.example.com NSEC
# 14. Check DNS response size (DDoS amplification test)
dig example.com ANY +bufsize=4096
# 15. Attempt full zone export (security audit)
dig @ns1.example.com example.com AXFR
8. DNS Security
DNS Attack Types
1. DNS Cache Poisoning
Normal: Resolver -> Authoritative NS -> Correct IP
Attack: Attacker injects fake response into resolver cache
Result: Users are redirected to phishing sites
Defense: DNSSEC, random source ports, 0x20 encoding
2. DNS Amplification DDoS
Attack method:
1. Attacker spoofs source IP to victim's IP
2. Sends queries that generate large responses to open resolvers (ANY type)
3. Small query -> Large response = amplification effect (50-70x)
4. All responses flood the victim
Defense: BCP38 (source address validation), RRL (Response Rate Limiting)
3. DNS Hijacking
Method 1: DNS response tampering at router/ISP level
Method 2: Registrar account compromise -> name server change
Method 3: Malware changes system DNS settings
Defense: DNSSEC, registrar 2FA, DNS monitoring
4. DNS Tunneling
Purpose: Abuse DNS protocol for data exfiltration/remote control
Method: Hide encoded data in DNS queries/responses
Example: Query TXT for malicious-data.encoded.evil.com
-> Firewall sees it as normal DNS traffic
Defense: Monitor DNS query length/frequency, DNS firewall
How DNSSEC Works
DNSSEC cryptographically verifies the integrity and origin of DNS responses.
Chain of Trust:
Root (.) -> .com -> example.com
At each level:
1. DNSKEY: Zone's public key
2. RRSIG: Digital signature for each record
3. DS: Hash of child zone's public key (stored in parent zone)
4. NSEC/NSEC3: Proof that "this name does not exist"
# Check DNSSEC verification
dig +dnssec example.com
# 'ad' flag in response means DNSSEC validation succeeded
# flags: qr rd ra ad; QUERY: 1, ANSWER: 2
# Query DNSKEY
dig example.com DNSKEY +short
# Query DS record (from parent zone)
dig example.com DS +short
DNS over HTTPS (DoH) / DNS over TLS (DoT)
Traditional DNS is sent over plaintext UDP/TCP, allowing ISPs and network administrators to view and manipulate DNS queries.
| Protocol | Port | Encryption | Features |
|---|---|---|---|
| Plain DNS | 53 (UDP/TCP) | None | Eavesdropping/tampering possible |
| DoT | 853 (TCP) | TLS | Dedicated port, blockable |
| DoH | 443 (HTTPS) | HTTPS | Hidden in HTTPS traffic, hard to block |
| DoQ | 853 (QUIC) | QUIC | Newest, low latency |
# DoH DNS query (curl)
curl -s -H "accept: application/dns-json" \
"https://1.1.1.1/dns-query?name=example.com&type=A" | jq .
# DoH services
# Cloudflare: https://1.1.1.1/dns-query
# Google: https://dns.google/dns-query
# Quad9: https://dns.quad9.net/dns-query
# DoT test (using kdig)
kdig -d @1.1.1.1 +tls-ca +tls-host=cloudflare-dns.com example.com
DNS Filtering: Pi-hole, NextDNS, AdGuard Home
[Devices] -> [DNS Filter] -> [Only allowed queries pass] -> [Internet]
|
Block ads/malicious domains
Block trackers
Filter adult content
| Solution | Type | Features |
|---|---|---|
| Pi-hole | Self-hosted | Run on Raspberry Pi, network-wide blocking |
| NextDNS | Cloud | 300K queries/month free, easy setup |
| AdGuard Home | Self-hosted | DoH/DoT support, web UI |
Enterprise: DNS Firewall and RPZ
RPZ (Response Policy Zone):
Technology to override responses for specific domains in a DNS firewall
Example (BIND RPZ):
; rpz.db
evil-domain.com CNAME . ; NXDOMAIN response
malware-c2.com CNAME . ; Block
phishing-site.com A 10.0.0.1 ; Redirect to warning page
9. 10 Real-World Troubleshooting Scenarios
Scenario 1: Domain Registered But Cannot Access (Propagation Delay)
Symptom: You registered a domain and set up an A record, but the browser cannot connect.
Cause: DNS propagation across all DNS servers worldwide can take up to 48 hours.
# Diagnosis
# 1. Check directly from authoritative name server (if this works, config is correct)
dig @ns1.your-dns-provider.com yourdomain.com A +short
# 2. Check propagation via multiple public DNS
dig @8.8.8.8 yourdomain.com +short
dig @1.1.1.1 yourdomain.com +short
dig @9.9.9.9 yourdomain.com +short
# 3. Check global propagation online
# https://www.whatsmydns.net/
Resolution:
- Wait (up to 48 hours, usually 1-4 hours)
- Force flush local DNS cache:
ipconfig /flushdns(Windows) orsudo dscacheutil -flushcache(macOS) - Setting a low TTL beforehand speeds up propagation
Scenario 2: SSL Certificate Issuance Failure (CAA Record)
Symptom: Attempting to issue an SSL certificate with Let's Encrypt but it fails.
# Diagnosis: Check CAA records
dig yourdomain.com CAA +short
# 0 issue "digicert.com" <- Let's Encrypt is not in the allow list!
# Fix: Add or modify CAA record
# yourdomain.com. IN CAA 0 issue "letsencrypt.org"
# yourdomain.com. IN CAA 0 issuewild "letsencrypt.org"
# If no CAA records exist, all CAs can issue (default behavior)
dig yourdomain.com CAA +short
# (empty response = no restrictions)
Scenario 3: Emails Going to Spam (SPF/DKIM/DMARC)
Symptom: Sent emails end up in recipients' spam folders.
# Diagnosis 1: Check SPF record
dig yourdomain.com TXT +short | grep spf
# "v=spf1 include:_spf.google.com -all"
# Diagnosis 2: Check DKIM record (selector from email headers)
dig google._domainkey.yourdomain.com TXT +short
# Diagnosis 3: Check DMARC policy
dig _dmarc.yourdomain.com TXT +short
# "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com"
# Resolution checklist:
# 1. Verify SPF includes all mail-sending server IPs/domains
# 2. Verify DKIM signing key is registered
# 3. Set up DMARC policy (start with p=none for monitoring)
# 4. Analyze DMARC reports, then strengthen: p=quarantine -> p=reject
Scenario 4: Subdomain Not Working
Symptom: api.example.com works but staging.example.com does not.
# Diagnosis: Check if subdomain record exists
dig staging.example.com A +short
# (empty response = no record)
dig api.example.com A +short
# 203.0.113.20 (working)
# Check wildcard records
dig *.example.com A +short
Resolution:
- Explicitly add A/CNAME record for the subdomain
- Or set up a wildcard (
*.example.com) record - Remember that explicit records take priority over wildcards
Scenario 5: Some Users Cannot Access After DNS Change (TTL Cache)
Symptom: After changing DNS records, some users reach the new server while others still reach the old one.
# Diagnosis: Check cache state at different DNS servers
dig @8.8.8.8 example.com +short # Google DNS
dig @1.1.1.1 example.com +short # Cloudflare DNS
dig @9.9.9.9 example.com +short # Quad9
# Check TTL
dig example.com | grep -A1 "ANSWER SECTION"
# example.com. 1800 IN A 203.0.113.10
# ^ remaining TTL is still high
Resolution:
- Wait for the TTL duration to expire
- Next time, lower TTL to 60 seconds 24 hours before making DNS changes
- Restore TTL to original value after changes are complete
Scenario 6: nslookup Works But Browser Cannot Connect
Symptom: nslookup example.com returns correct results but Chrome cannot access the site.
# Diagnosis 1: Check hosts file
cat /etc/hosts # Linux/macOS
type C:\Windows\System32\drivers\etc\hosts # Windows
# Diagnosis 2: Check browser DNS cache
# Chrome: chrome://net-internals/#dns -> Clear host cache
# Diagnosis 3: Check HSTS issues
# Chrome: chrome://net-internals/#hsts
# Delete domain and retry
# Diagnosis 4: Check proxy/VPN settings
# Browser proxy settings can bypass DNS
# Diagnosis 5: Check DNS over HTTPS settings
# Chrome Settings -> Privacy and Security -> Use secure DNS
Scenario 7: DNS Outage After Domain Transfer
Symptom: Site goes down after transferring the domain to another registrar.
# Diagnosis: Check current name servers
dig example.com NS +short
# If old registrar's NS appear, update hasn't propagated yet
# Resolution steps:
# 1. Set up DNS records at new registrar FIRST
# 2. Replicate ALL records to the new location before transfer
# 3. Change name servers
# 4. Keep old name servers active for at least 48 hours
Prevention: Always set up all DNS records at the new registrar before initiating the transfer.
Scenario 8: K8s Internal DNS Resolution Failure (CoreDNS, ndots)
Symptom: Pod cannot access external domains (api.external.com) or it is very slow.
# Diagnosis 1: Test DNS resolution from within the Pod
kubectl exec -it debug-pod -- nslookup api.external.com
# Diagnosis 2: Check resolv.conf
kubectl exec -it debug-pod -- cat /etc/resolv.conf
# nameserver 10.96.0.10
# search default.svc.cluster.local svc.cluster.local cluster.local
# options ndots:5
# Diagnosis 3: Check CoreDNS logs
kubectl logs -n kube-system -l k8s-app=kube-dns
# Problem: Due to ndots:5, api.external.com (2 dots) causes
# api.external.com.default.svc.cluster.local etc. to be tried first
Resolution:
# Method 1: Use FQDN (add trailing dot)
# In code, call api.external.com. instead
# Method 2: Set Pod dnsConfig
apiVersion: v1
kind: Pod
spec:
dnsConfig:
options:
- name: ndots
value: '2'
Scenario 9: Origin Server IP Exposed After CDN Integration (DNS Leak)
Symptom: Using Cloudflare but origin server IP is exposed, receiving direct DDoS attacks.
# Diagnosis: Check for non-proxied records
# In Cloudflare dashboard, look for grey cloud (DNS Only)
# instead of orange cloud (Proxied) records
# Scan subdomains for exposure
dig direct.example.com +short # Origin IP exposed?
dig mail.example.com +short # Origin IP in MX A record?
dig ftp.example.com +short # Origin IP in FTP subdomain?
Resolution:
- Enable Cloudflare proxy on all A/AAAA records
- Use a separate IP for A records needed by MX
- If origin IP is already exposed, change the server IP
- Check historical DNS records: SecurityTrails, DNS History may retain the origin IP
Scenario 10: DDNS Updates Not Reflecting
Symptom: DDNS service is configured but DNS doesn't update when IP changes.
# Diagnosis 1: Check current public IP
curl -s https://api.ipify.org
# Diagnosis 2: Check IP registered in DNS
dig myserver.example.com +short
# Diagnosis 3: Check DDNS client logs
sudo journalctl -u ddclient -n 50
# Diagnosis 4: Verify API token validity
curl -s -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
-H "Authorization: Bearer YOUR_TOKEN" | jq .
# Common causes:
# 1. API token expired or insufficient permissions
# 2. Wrong Zone ID or Record ID
# 3. Firewall blocking DDNS client outbound communication
# 4. Cron job disabled
# 5. IP check service (ipify, etc.) unreachable
10. DNS Service Comparison
Managed DNS Services
| Service | Free Plan | Managed DNS | DDNS | DNSSEC | DDoS Protection | Pricing (Paid) |
|---|---|---|---|---|---|---|
| Cloudflare | Yes (unlimited) | Yes | Via API | Yes (free) | Yes | Free to Enterprise |
| AWS Route 53 | No | Yes | No | Yes | Yes (Shield) | 0.50 USD/zone/month |
| Google Cloud DNS | No | Yes | No | Yes | Yes | 0.20 USD/zone/month |
| Azure DNS | No | Yes | No | Yes (preview) | Yes | 0.50 USD/zone/month |
| NS1 | Free tier | Yes | Yes | Yes | Yes | Custom |
| Dyn (Oracle) | No | Yes | Yes | Yes | Yes | Custom |
Public DNS Resolvers
| Service | Primary | Secondary | DoH | DoT | DNSSEC Validation | Features |
|---|---|---|---|---|---|---|
| Google DNS | 8.8.8.8 | 8.8.4.4 | Yes | Yes | Yes | Most widely used |
| Cloudflare | 1.1.1.1 | 1.0.0.1 | Yes | Yes | Yes | Fastest |
| Quad9 | 9.9.9.9 | 149.112.112.112 | Yes | Yes | Yes | Malicious domain blocking |
| OpenDNS | 208.67.222.222 | 208.67.220.220 | Yes | No | Yes | Filtering options |
| AdGuard DNS | 94.140.14.14 | 94.140.15.15 | Yes | Yes | Yes | Ad blocking |
Recommended by Scenario
| Scenario | Recommended Service | Reason |
|---|---|---|
| Personal blog/site | Cloudflare (free) | Free DNS + CDN + SSL |
| Startup | Cloudflare Pro or Route 53 | Scalability + reliability |
| Enterprise | Route 53 + Cloudflare | Multi-DNS + latency-based routing |
| Home server | Cloudflare + DDNS | Free + dynamic IP support |
| K8s cluster | CoreDNS + External-DNS | Automated DNS management |
Quiz
Q1: What is the difference between recursive and iterative DNS queries?
Recursive Query: The client asks a recursive resolver for the final answer. The resolver handles all intermediate steps and returns the final IP address.
Iterative Query: The recursive resolver queries each level of name server (Root, TLD, Authoritative) in order. Each server returns a referral to the next server rather than the final answer.
Typically, client-to-resolver uses recursive queries, while resolver-to-name-servers uses iterative queries.
Q2: Why can't you set a CNAME record on the root domain (apex)?
Per the RFC, a CNAME must be the only record for that name. That is, if a CNAME exists, no other records (A, MX, NS, SOA, etc.) can exist for the same name.
However, the root domain must have SOA and NS records, which cannot coexist with a CNAME.
Alternatives include Cloudflare's CNAME Flattening or ALIAS/ANAME records offered by some DNS providers.
Q3: I set TTL to 60 seconds but DNS changes haven't propagated after 48 hours. Why?
Possible causes:
- Cache from before the TTL change may still exist. The TTL change itself needs time equal to the old TTL to propagate.
- Some ISP DNS servers enforce a minimum TTL (e.g., minimum 300 seconds).
- Client OS and browser caches also cache DNS independently.
- If name servers themselves were changed, propagation at the TLD level can take up to 48 hours.
Fix: Lower TTL 24 hours before the planned DNS change, and flush local caches with ipconfig /flushdns etc. after the change.
Q4: Does DNSSEC encrypt DNS queries?
No. DNSSEC verifies the integrity and authenticity of DNS responses, not encryption.
DNS responses protected by DNSSEC are still transmitted in plaintext. The content of DNS queries remains visible on the network.
For DNS query encryption (privacy), use DNS over HTTPS (DoH) or DNS over TLS (DoT).
Summary:
- DNSSEC = prevents response tampering (integrity)
- DoH/DoT = encrypts queries (privacy)
- Using both provides optimal security
Q5: Why is accessing the external domain api.external.com slow from a K8s Pod, and how do you fix it?
Cause: Kubernetes' default DNS setting of ndots:5 means domains with fewer than 5 dots get search domains appended first.
api.external.com has only 2 dots, so the actual query order is:
api.external.com.default.svc.cluster.local(NXDOMAIN)api.external.com.svc.cluster.local(NXDOMAIN)api.external.com.cluster.local(NXDOMAIN)api.external.com.(success)
Three unnecessary queries occur before the actual resolution.
Solutions:
- Use FQDN:
api.external.com.(add trailing dot) - Set ndots to a lower value (e.g., 2) in Pod's dnsConfig
- Add caching rules in CoreDNS for frequently accessed external domains
References
RFC Documents
- RFC 1034 - Domain Names - Concepts and Facilities
- RFC 1035 - Domain Names - Implementation and Specification
- RFC 2136 - Dynamic Updates in the DNS (DDNS)
- RFC 2181 - Clarifications to the DNS Specification
- RFC 2308 - Negative Caching of DNS Queries
- RFC 4033, 4034, 4035 - DNS Security Extensions (DNSSEC)
- RFC 6698 - DNS-Based Authentication (DANE/TLSA)
- RFC 7208 - SPF (Sender Policy Framework)
- RFC 7489 - DMARC
- RFC 8484 - DNS over HTTPS (DoH)
- RFC 7858 - DNS over TLS (DoT)
- RFC 8659 - DNS Certification Authority Authorization (CAA)
Tools and Services
- dig / nslookup - DNS query command-line tools
- whatsmydns.net - Global DNS propagation checker
- dnschecker.org - DNS record checker
- mxtoolbox.com - Email DNS diagnostics (SPF, DKIM, DMARC)
- securitytrails.com - DNS history lookup
- dnsviz.net - DNSSEC visualization and verification
DNS Software
- BIND9 - https://www.isc.org/bind/
- CoreDNS - https://coredns.io/
- PowerDNS - https://www.powerdns.com/
- Unbound - https://nlnetlabs.nl/projects/unbound/
- Knot DNS - https://www.knot-dns.cz/
Learning Resources
- Cloudflare Learning Center - DNS concepts (learning.cloudflare.com)
- howdns.works - Visual DNS explanation
- messwithdns.net - DNS hands-on playground
- Julia Evans - DNS-related blog and zines