浏览器 → 本地缓存 → /etc/hosts → DNS解析器 → 递归查询
│
│ 递归查询路径:
│ 本地DNS → 根DNS服务器 → .com DNS → example.com DNS
│
└──→ 返回IP地址: 93.184.216.34
| 类型 | 说明 | 示例 |
|---|---|---|
| A | IPv4地址 | example.com. IN A 93.184.216.34 |
| AAAA | IPv6地址 | example.com. IN AAAA 2606:2800:220:1:... |
| CNAME | 别名 | www IN CNAME example.com. |
| MX | 邮件交换 | example.com. IN MX 10 mail.example.com. |
| NS | 名称服务器 | example.com. IN NS ns1.example.com. |
| TXT | 文本记录 | example.com. IN TXT "v=spf1 include:..." |
| SRV | 服务记录 | _sip._tcp IN SRV 10 60 5060 sip.example.com. |
| PTR | 反向解析 | 34.216.184.93.in-addr.arpa. IN PTR example.com. |
$ cat /etc/resolv.conf
# This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8). # Do not edit. # # This file might be symlinked as /etc/resolv.conf. If you're looking at # /etc/resolv.conf and seeing this text, you have followed the symlink. # # This is a dynamic resolv.conf file for connecting local clients to the # internal DNS stub resolver of systemd-resolved. This file lists all # configured search domains. # # Run "resolvectl status" to see details about the uplink DNS servers # currently in use. # # Third party programs should typically not access this file directly, but only # through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a # different way, replace this symlink by a static file or a different symlink. # # See man:systemd-resolved.service(8) for details about the supported modes of # operation for /etc/resolv.conf. nameserver 127.0.0.53 options edns0 trust-ad search .
# 常用配置
nameserver 8.8.8.8 # DNS服务器
nameserver 8.8.4.4 # 备用DNS
search example.com # 搜索域
options timeout:2 # 超时2秒
options attempts:3 # 最多重试3次
options rotate # 轮询DNS服务器
$ cat /etc/hosts
127.0.1.1 localhost.localdomain VM-4-3-ubuntu 127.0.0.1 localhost ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters ff02::3 ip6-allhosts
# 静态DNS解析,优先级高于DNS查询
# 格式:IP 主机名 [别名]
127.0.0.1 localhost
192.168.1.10 web1.example.com web1
192.168.1.11 web2.example.com web2
192.168.1.100 db1.example.com db1
$ cat /etc/nsswitch.conf | grep -v '^#' | grep -v '^$'
passwd: files systemd group: files systemd shadow: files systemd gshadow: files systemd hosts: files dns networks: files protocols: db files services: db files ethers: db files rpc: db files netgroup: nis
hosts行决定解析顺序:files dns表示先查/etc/hosts再查DNS。
$ systemctl status systemd-resolved | head -10
● systemd-resolved.service - Network Name Resolution
Loaded: loaded (/usr/lib/systemd/system/systemd-resolved.service; enabled; preset: enabled)
Active: active (running) since Tue 2026-05-19 02:15:52 CST; 19h ago
Docs: man:systemd-resolved.service(8)
man:org.freedesktop.resolve1(5)
https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
Main PID: 803 (systemd-resolve)
Status: "Processing requests..."
Tasks: 1 (limit: 9127)# 配置 /etc/systemd/resolved.conf
[Resolve]
DNS=8.8.8.8 8.8.4.4
FallbackDNS=1.1.1.1 9.9.9.9
Domains=example.com
LLMNR=no
DNSOverTLS=opportunistic
# 重启服务
sudo systemctl restart systemd-resolved
# 查看DNS统计
resolvectl statistics
# 查询特定域
resolvectl query google.com
# dig - 最强大的DNS查询工具
dig google.com # 基本查询
dig google.com +short # 仅返回IP
dig google.com MX # 查MX记录
dig google.com ANY # 查所有记录
dig -x 8.8.8.8 # 反向解析
dig @8.8.8.8 google.com # 指定DNS服务器
dig google.com +trace # 跟踪完整解析路径
# nslookup - 简单查询
nslookup google.com
nslookup google.com 8.8.8.8
# host - 简洁输出
host google.com
host -t MX google.com
# 检查DNS传播
# https://dnschecker.org/ 或 dnspython
# 安装
sudo apt install bind9 bind9utils
# /etc/bind/named.conf.options
options {
directory "/var/cache/bind";
forwarders {
8.8.8.8;
8.8.4.4;
};
dnssec-validation auto;
};
# 正向区域 /etc/bind/db.example.com
$TTL 604800
@ IN SOA ns1.example.com. admin.example.com. (
2024010101 ; Serial
3600 ; Refresh
900 ; Retry
604800 ; Expire
86400 ) ; Negative Cache TTL
IN NS ns1.example.com.
ns1 IN A 192.168.1.1
web IN A 192.168.1.10
# 检查配置
sudo named-checkconf
sudo named-checkzone example.com /etc/bind/db.example.com
# 1. 测试DNS
dig google.com
nslookup google.com
# 2. 检查resolv.conf
cat /etc/resolv.conf
# 3. 检查/etc/hosts
cat /etc/hosts
# 4. 检查resolved状态
systemctl status systemd-resolved
# 5. 刷新DNS缓存
sudo resolvectl flush-caches
sudo systemd-resolve --flush-caches # 旧版# 1. 查询域名解析
dig google.com +short
dig google.com MX
# 2. 反向解析
dig -x 8.8.8.8 +short
# 3. 跟踪解析路径
dig google.com +trace | head -30
# 4. 检查本地DNS配置
cat /etc/resolv.conf✅ 理解DNS解析流程
✅ 掌握Linux DNS配置
✅ 学会dig/nslookup诊断
✅ 了解Bind9自建DNS
# 查看DNS缓存
sudo resolvectl statistics
# 刷新DNS缓存
sudo resolvectl flush-caches
# 启用DNS缓存(dnsmasq)
sudo apt install dnsmasq
# /etc/dnsmasq.conf
server=8.8.8.8
server=8.8.4.4
cache-size=1000
listen-address=127.0.0.1
# 测试DNS性能
dig @127.0.0.1 google.com # 第一次查询
dig @127.0.0.1 google.com # 第二次(应更快)
# systemd-resolved启用DoH
# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com 9.9.9.9#dns.quad9.net
DNSOverTLS=opportunistic
sudo systemctl restart systemd-resolved
# 检查DNS响应是否被篡改
dig @8.8.8.8 twitter.com
# 对比不同DNS服务器的结果
dig @1.1.1.1 twitter.com
dig @8.8.8.8 twitter.com
# 使用DNSSEC验证
dig +dnssec example.com
# 使用DoH防止中间人
curl -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=example.com&type=A'# 内外网使用不同DNS解析
# /etc/systemd/resolved.conf
[Resolve]
DNS=10.0.0.1
Domains=internal.example.com
# 外部查询走公共DNS
# /etc/systemd/resolved.conf.d/public.conf
[Resolve]
DNS=8.8.8.8 1.1.1.1
# dnsmasq实现Split DNS
server=/internal.example.com/10.0.0.1
server=/example.com/8.8.8.8
address=/dev.example.com/127.0.0.1
#!/bin/bash
# dns-monitor.sh
DOMAINS="google.com github.com cloudflare.com"
DNS_SERVERS="8.8.8.8 1.1.1.1 9.9.9.9"
ALERT_THRESHOLD=500 # ms
for domain in $DOMAINS; do
for dns in $DNS_SERVERS; do
time_ms=$(dig +stats @{$dns} $domain | grep "Query time" | awk '{print $4}')
if [ "$time_ms" -gt "$ALERT_THRESHOLD" ] 2>/dev/null; then
echo "⚠️ $domain via $dns: ${time_ms}ms (slow!)"
else
echo "✅ $domain via $dns: ${time_ms}ms"
fi
done
done
# DNS轮询(Round Robin) - 最简单的负载均衡
# 同一个域名多个A记录
www.example.com. IN A 192.168.1.10
www.example.com. IN A 192.168.1.11
www.example.com. IN A 192.168.1.12
# dig查询会轮流返回不同IP
dig www.example.com +short
# 192.168.1.10
# 192.168.1.11
# 192.168.1.12
# 缺点:无法感知服务器健康状态
# 改进方案:使用GeoDNS或全局负载均衡(GSLB)
DNS解析失败
│
├── 检查 /etc/resolv.conf
│ ├── nameserver配置正确?
│ └── 是否被systemd-resolved管理?
│
├── 检查 /etc/hosts
│ └── 是否有冲突的静态映射?
│
├── 本地DNS测试
│ ├── dig @127.0.0.1 domain
│ └── 指定DNS: dig @8.8.8.8 domain
│
├── 网络连通性
│ ├── ping DNS服务器IP
│ └── 检查53端口: nc -zv DNS_IP 53
│
└── 缓存问题
├── resolvectl flush-caches
└── 重启systemd-resolved
# 1. 启用DNS缓存减少查询延迟
# systemd-resolved默认缓存
resolvectl statistics | grep "Cache"
# 2. 使用预取(prefetch)减少过期查询延迟
# Bind9配置
options {
prefetch 2 9; # TTL<2秒时预取,9秒后执行
};
# 3. 负面缓存优化
# 减少NXDOMAIN响应的缓存时间
# /etc/systemd/resolved.conf
CacheFromLocalhost=yes
# 4. 并行查询
# 同时查询多个DNS服务器,取最快响应
# /etc/systemd/resolved.conf
[Resolve]
DNS=8.8.8.8 1.1.1.1 9.9.9.9
# 5. 本地hosts优化
# 高频域名直接写入/etc/hosts
echo "151.101.1.140 github.global.ssl.fastly.net" | sudo tee -a /etc/hosts
echo "192.30.253.112 github.com" | sudo tee -a /etc/hosts
CDN通过DNS CNAME将用户请求路由到最近的边缘节点。
# DNS配置CDN
www.example.com. IN CNAME www.example.com.cdn.cloudflare.net.
# 查询CDN解析过程
dig www.example.com +trace
# 可以看到CNAME链和最终IP
# GeoDNS:根据用户地理位置返回不同IP
# 服务商:CloudFlare, AWS Route53, 阿里云DNS, DNSPod
# 检查域名是否启用DNSSEC
dig +dnssec example.com
# 如果有RRSIG记录,说明启用了DNSSEC
# 验证DNSSEC
delv example.com
# 输出 "fully validated" 表示验证通过
# 启用DNSSEC验证(resolved)
# /etc/systemd/resolved.conf
DNSSEC=allow-downgrade