跳到主要内容

DNS 域名解析

DNS 解析流程

DNS 缓存层级

DNS 查询会依次经过多级缓存:

  1. 浏览器缓存(Chrome: chrome://net-internals/#dns
  2. 操作系统缓存nscd / systemd-resolved
  3. 路由器缓存
  4. 递归解析器缓存(ISP DNS / 公共 DNS)

DNS 记录类型

记录类型说明示例使用场景
AIPv4 地址example.com → 93.184.216.34基础域名解析
AAAAIPv6 地址example.com → 2606:2800:...IPv6 支持
CNAME别名www → example.comCDN、别名
MX邮件服务器example.com → mail.example.com邮件路由
TXT文本记录v=spf1 include:...SPF/DKIM/域名验证
NS域名服务器example.com → ns1.dns.comDNS 授权
SRV服务记录_sip._tcp.example.com服务发现
PTR反向解析34.216.184.93 → example.com反垃圾邮件
SOA起始授权序列号、刷新间隔区域传输
CAACA 授权0 issue "letsencrypt.org"证书申请限制
CNAME 限制
  • 根域名(example.com)不能设 CNAME,必须用 A 记录
  • CNAME 不能与其他记录共存(如 MX)
  • 解决方案:使用 ALIAS/ANAME(部分 DNS 提供商支持)

DNS 排查工具

dig 命令

# 基本查询
dig example.com

# 查询特定记录类型
dig example.com A # IPv4 地址
dig example.com AAAA # IPv6 地址
dig example.com MX # 邮件服务器
dig example.com NS # 域名服务器
dig example.com TXT # TXT 记录
dig example.com ANY # 所有记录

# 指定 DNS 服务器查询
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com

# 简洁输出(只看结果)
dig +short example.com

# 完整解析链路追踪(排查必备)
dig +trace example.com

# 反向解析
dig -x 93.184.216.34

# 查看 DNSSEC 信息
dig +dnssec example.com

dig +trace 输出解读

$ dig +trace www.example.com

# 1. 根域名服务器
. IN NS a.root-servers.net.
# 2. TLD 服务器
com. IN NS a.gtld-servers.net.
# 3. 权威 DNS
example.com. IN NS ns1.example.com.
# 4. 最终结果
www.example.com. IN A 93.184.216.34

nslookup

# 交互式查询
nslookup
> set type=MX
> example.com

# 非交互式
nslookup example.com
nslookup -type=MX example.com
nslookup example.com 8.8.8.8 # 指定 DNS 服务器

host 命令

host example.com
host -t MX example.com
host -t TXT example.com

DNS 服务器配置

/etc/resolv.conf

/etc/resolv.conf
# DNS 搜索域(短名补全)
search example.com internal.example.com

# DNS 服务器(最多 3 个,按顺序查询)
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 1.1.1.1

# 选项
options timeout:2 attempts:3 rotate
# timeout: 超时时间(秒)
# attempts: 重试次数
# rotate: 轮询使用多个 nameserver
resolv.conf 被覆盖

很多系统由 NetworkManager 或 systemd-resolved 自动管理 /etc/resolv.conf

# systemd-resolved(Ubuntu 18+)
# 查看实际 DNS 配置
resolvectl status

# 修改 DNS
# 编辑 /etc/systemd/resolved.conf
[Resolve]
DNS=8.8.8.8 1.1.1.1
FallbackDNS=8.8.4.4

systemctl restart systemd-resolved

# NetworkManager
nmcli con mod "连接名" ipv4.dns "8.8.8.8 1.1.1.1"
nmcli con up "连接名"

常用公共 DNS

DNS 服务IPv4IPv6特点
Google8.8.8.8 / 8.8.4.42001:4860:4860::8888全球覆盖
Cloudflare1.1.1.1 / 1.0.0.12606:4700:4700::1111速度快、隐私保护
阿里 DNS223.5.5.5 / 223.6.6.6国内优选
腾讯 DNS119.29.29.29国内备选

DNS 高级配置

本地 DNS 缓存(systemd-resolved)

# 查看缓存统计
resolvectl statistics

# 清除 DNS 缓存
resolvectl flush-caches
# 或
systemd-resolve --flush-caches

# Mac 清除 DNS 缓存
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

/etc/hosts 本地解析

/etc/hosts
# 格式:IP 域名 别名
127.0.0.1 localhost
192.168.1.100 db.internal.example.com db

# 用途:
# 1. 测试环境域名解析
# 2. 屏蔽恶意域名
# 3. 开发环境本地域名
解析优先级

/etc/hosts > DNS 缓存 > DNS 服务器

/etc/nsswitch.conf 中的 hosts: 行控制:

hosts: files dns myhostname
# files = /etc/hosts 先查
# dns = DNS 服务器后查

DNS 常见故障排查

常见问题与解决

问题可能原因排查命令
解析超时DNS 服务器不可达dig @8.8.8.8 domain
解析为错误 IPDNS 缓存污染 / 劫持dig +trace domain
部分用户无法解析TTL 缓存未过期dig +short domain @各地DNS
CNAME 循环配置错误dig +trace domain
NXDOMAIN域名不存在或过期whois domain

常见面试问题

Q1: DNS 解析的完整流程?

答案

  1. 浏览器先查本地缓存(浏览器 → OS → hosts 文件)
  2. 未命中则向配置的递归解析器(如 8.8.8.8)发起查询
  3. 递归解析器如果没缓存,依次向根域名服务器、TLD 服务器、权威 DNS 发起迭代查询
  4. 权威 DNS 返回最终结果
  5. 递归解析器缓存结果(按 TTL),返回给客户端

Q2: DNS 记录的 TTL 是什么?如何利用 TTL 做平滑切换?

答案

TTL(Time To Live)是 DNS 记录的缓存时间,单位是秒。

平滑切换策略

  1. 切换前 1-2 天,将 TTL 从默认值(如 3600s)降低到 60s
  2. 等待旧 TTL 时间过去,确保全网缓存刷新
  3. 修改 DNS 记录指向新 IP
  4. 确认切换成功后,将 TTL 恢复到正常值

Q3: DNS 劫持和 DNS 污染的区别?

答案

  • DNS 劫持:中间设备(路由器/ISP)拦截 DNS 请求,返回篡改的结果。通常将域名解析到广告页面或钓鱼网站。解决:使用 HTTPS DNS (DoH) 或 DNS over TLS (DoT)。
  • DNS 污染:向 DNS 查询注入虚假响应。攻击者监听 DNS 查询并抢先返回伪造结果。解决:使用 DNSSEC 验证。

Q4: A 记录和 CNAME 记录的区别?什么时候用哪个?

答案

  • A 记录:直接映射域名到 IP 地址。变更 IP 时需要修改 A 记录。
  • CNAME 记录:映射域名到另一个域名(别名)。目标域名的 IP 变化时无需修改 CNAME。

使用建议:

  • 根域名(example.com)只能用 A 记录
  • CDN 接入通常用 CNAME(指向 CDN 提供的域名)
  • 需要固定 IP 时用 A 记录
  • 多个子域名指向同一服务时用 CNAME

相关链接