mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
1585 字
5 分钟
DNS 解析完整流程:从域名到 IP
2023-05-24

前言#

当你输入 www.example.com 按下回车,浏览器在发起 TCP 连接之前,必须先将域名解析为 IP 地址。这个过程看似简单,实际上涉及浏览器缓存、操作系统缓存、本地 DNS 服务器、根域名服务器、顶级域名服务器、权威域名服务器的多级协作。本文完整追踪一个 DNS 查询从诞生到返回的全链路。

DNS 解析全链路概览#

flowchart TB A[用户输入 www.example.com] --> B{浏览器 DNS 缓存?} B -->|命中| Z[返回 IP] B -->|未命中| C{OS DNS 缓存?} C -->|命中| Z C -->|未命中| D{hosts 文件?} D -->|命中| Z D -->|未命中| E[向本地 DNS 服务器查询] E --> F{本地 DNS 缓存?} F -->|命中| Z F -->|未命中| G[递归/迭代查询] G --> H[查询根域名服务器] H --> I[查询顶级域名服务器 .com] I --> J[查询权威域名服务器 example.com] J --> K[返回 IP 地址 93.184.216.34] K --> E E --> D D --> C C --> B B --> Z

一、DNS 报文结构#

1.1 DNS 报文整体格式#

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Header (12 字节) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Question Section |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Answer Section |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Authority Section |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Additional Section |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

1.2 Header 部分详解#

1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

各字段说明

字段长度说明
ID16 bit事务 ID,匹配请求和响应
QR1 bit0=查询,1=响应
Opcode4 bit0=标准查询,1=反向查询,4=通知
AA1 bit权威应答标志
TC1 bit截断标志(UDP 超过 512 字节时置 1)
RD1 bit期望递归查询
RA1 bit支持递归查询
Z3 bit保留
RCODE4 bit响应码(0=无错误,3=域名不存在)
QDCOUNT16 bitQuestion 条目数
ANCOUNT16 bitAnswer 条目数
NSCOUNT16 bitAuthority 条目数
ARCOUNT16 bitAdditional 条目数

1.3 Resource Record 格式#

1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ NAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| CLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
/ RDATA /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

1.4 DNS 名称编码#

// DNS 名称使用长度前缀编码,而非 null 终止
// "www.example.com" 编码如下:
const dnsName = Buffer.from([
0x03, 0x77, 0x77, 0x77, // \x03www
0x07, 0x65, 0x78, 0x61, // \x07exa
0x6d, 0x70, 0x6c, 0x65, // mple
0x03, 0x63, 0x6f, 0x6d, // \x03com
0x00, // 结束标记
]);
// 消息压缩:后续出现相同域名可用指针
// 指针格式: 11 + 14-bit 偏移量
// 例如 0xC00C 指向偏移 12 处的名称

二、记录类型详解#

2.1 常用记录类型#

类型说明示例
A1IPv4 地址93.184.216.34
AAAA28IPv6 地址2606:2800:220:1:...
CNAME5规范名称(别名)www.example.com → example.com
MX15邮件交换10 mail.example.com
NS2域名服务器ns1.example.com
TXT16文本记录SPF, DKIM, DMARC
SRV33服务定位_http._tcp.example.com
SOA6起始授权主 DNS 管理信息
PTR12反向解析(IP→域名)34.216.184.93.in-addr.arpa
CAA257证书颁发机构授权0 issue "letsencrypt.org"

2.2 A 记录与 AAAA 记录#

; A 记录:域名 → IPv4
www.example.com. 300 IN A 93.184.216.34
; AAAA 记录:域名 → IPv6
www.example.com. 300 IN AAAA 2606:2800:220:1:248:1893:25c8:1946
; 一个域名可以有多条 A 记录(DNS 负载均衡)
www.example.com. 300 IN A 93.184.216.34
www.example.com. 300 IN A 93.184.216.35

2.3 CNAME 记录#

flowchart LR A["blog.example.com"] -->|"CNAME"| B["example.github.io"] B -->|"CNAME"| C["github.map.fastly.net"] C -->|"A"| D["151.101.1.147"] Note1["CNAME 链: blog → github → fastly → IP"]
; CNAME 不能与其他记录共存
; 错误示例:
blog.example.com. 300 IN CNAME example.github.io
blog.example.com. 300 IN A 1.2.3.4 ; 冲突!
; 正确:用 CNAME 指向另一个域名
blog.example.com. 300 IN CNAME example.github.io

2.4 MX 记录#

; MX 记录带优先级(数值越小优先级越高)
example.com. 300 IN MX 10 mail1.example.com.
example.com. 300 IN MX 20 mail2.example.com.
example.com. 300 IN MX 30 mail3.example.com.
; 发送邮件时优先尝试 mail1
; mail1 不可用时尝试 mail2,以此类推

2.5 SOA 记录#

; SOA(Start of Authority)记录
example.com. IN SOA ns1.example.com. admin.example.com. (
2026032201 ; Serial(序列号,区域传输时递增)
3600 ; Refresh(从服务器检查主服务器的间隔)
900 ; Retry(检查失败后重试间隔)
604800 ; Expire(从服务器数据过期时间)
86400 ; Minimum TTL(否定缓存的 TTL)
)

三、DNS 解析全链路#

3.1 浏览器缓存#

// Chrome 浏览器 DNS 缓存
// 访问 chrome://net-internals/#dns 查看
// 浏览器 DNS 缓存特点:
// 1. 默认缓存约 1000 条记录
// 2. 缓存时间遵循 DNS 记录的 TTL
// 3. 浏览器重启后缓存清除
// 手动清除 Chrome DNS 缓存
// chrome://net-internals/#dns → Clear host cache

3.2 操作系统缓存#

# Linux systemd-resolved
resolvectl status # 查看缓存统计
resolvectl flush-caches # 清除缓存
resolvectl query example.com # 手动查询
# Linux nscd (Name Service Cache Daemon)
nscd -g # 查看缓存统计
nscd -i hosts # 清除 hosts 缓存
# macOS
dscacheutil -flushcache # 清除 DNS 缓存
sudo killall -HUP mDNSResponder
# Windows
ipconfig /displaydns # 显示 DNS 缓存
ipconfig /flushdns # 清除 DNS 缓存

3.3 hosts 文件#

# /etc/hosts 文件优先级高于 DNS 查询
# 格式: IP 主机名
127.0.0.1 localhost
::1 localhost
192.168.1.100 myserver.local
10.0.0.1 api.internal.example.com
# 解析顺序由 /etc/nsswitch.conf 控制
# hosts: files dns → 先查 hosts 文件,再查 DNS

3.4 完整解析时序图#

sequenceDiagram participant Browser as 浏览器 participant OS as 操作系统 participant Local as 本地 DNS participant Root as 根 DNS participant TLD as .com TLD DNS participant Auth as 权威 DNS Browser->>OS: 查询 www.example.com OS->>OS: 检查本地缓存 OS->>Local: 发送递归查询 Local->>Local: 检查缓存 Local->>Root: 发送查询 www.example.com Root->>Local: 返回 .com TLD NS 地址 Note over Local: 缓存 .com NS 记录 Local->>TLD: 发送查询 www.example.com TLD->>Local: 返回 example.com 权威 NS 地址 Note over Local: 缓存权威 NS 记录 Local->>Auth: 发送查询 www.example.com Auth->>Local: 返回 A 记录 93.184.216.34 Note over Local: 缓存 A 记录(按 TTL) Local->>OS: 返回 93.184.216.34 OS->>OS: 缓存结果 OS->>Browser: 返回 93.184.216.34 Browser->>Browser: 缓存结果

四、递归查询与迭代查询#

4.1 递归查询#

sequenceDiagram participant C as 客户端 participant R as 本地 DNS(递归解析器) C->>R: 查询 www.example.com(递归) Note over R: 客户端只问一次 Note over R: 解析器负责全部工作 R->>R: 查缓存 R->>R: 查根服务器 R->>R: 查 TLD 服务器 R->>R: 查权威服务器 R->>C: 返回 93.184.216.34 Note over C: 得到最终答案

4.2 迭代查询#

sequenceDiagram participant R as 本地 DNS participant Root as 根 DNS participant TLD as .com TLD participant Auth as 权威 DNS R->>Root: 查询 www.example.com Root->>R: 我不知道,去问 .com TLD<br/>(返回 .com NS 列表) R->>TLD: 查询 www.example.com TLD->>R: 我不知道,去问 example.com 权威 DNS<br/>(返回权威 NS 列表) R->>Auth: 查询 www.example.com Auth->>R: 找到了! 93.184.216.34

4.3 查询对比#

特征递归查询迭代查询
谁做工作被查询者查询发起者
返回内容最终答案下一步该问谁
客户端负担重(通常不直接使用)
典型场景客户端 → 本地 DNS本地 DNS → 各级 DNS
服务器压力递归解析器压力大根/TLD 服务器压力小

五、DNS 缓存与 TTL#

5.1 多级缓存架构#

flowchart LR A[浏览器缓存] --> B[OS 缓存] B --> C[路由器缓存] C --> D[本地 DNS 缓存] D --> E[ISP DNS 缓存] E --> F[TLD DNS 缓存] Note1["缓存层级越高,<br/>命中率越低但覆盖面越广"]

5.2 TTL 的作用#

// TTL(Time To Live)决定缓存存活时间
// 单位:秒
// 短 TTL 的利弊
const shortTTL = 60; // 1 分钟
// 优点: DNS 变更后快速生效
// 缺点: 查询量大,增加延迟
// 长 TTL 的利弊
const longTTL = 86400; // 1 天
// 优点: 减少查询量,低延迟
// 缺点: DNS 变更后生效慢
// 实际 TTL 处理
function getCachedRecord(record) {
const elapsed = Date.now() - record.cachedAt;
if (elapsed > record.ttl * 1000) {
return null; // 缓存过期,需要重新查询
}
return record.value;
}

5.3 负面缓存#

; 当查询的域名不存在时,SOA 的 Minimum TTL 字段
; 控制否定缓存的存活时间
; example.com 的 SOA 记录
example.com. IN SOA ns1.example.com. admin.example.com. (
2026032201 ; Serial
3600 ; Refresh
900 ; Retry
604800 ; Expire
86400 ; Minimum TTL(否定缓存 24 小时)
)
; 查询 nonexistent.example.com 返回 NXDOMAIN
; 本地 DNS 会缓存这个否定结果 86400 秒
; 期间不再为该域名向上游查询

六、DNS 负载均衡#

6.1 轮询(Round Robin)#

# 一个域名对应多个 A 记录
$ dig www.example.com
;; ANSWER SECTION:
www.example.com. 300 IN A 93.184.216.34
www.example.com. 300 IN A 93.184.216.35
# 第二次查询时顺序可能变化
$ dig www.example.com
;; ANSWER SECTION:
www.example.com. 300 IN A 93.184.216.35
www.example.com. 300 IN A 93.184.216.34

6.2 地理定位(GeoDNS)#

flowchart TB A[用户请求 example.com] --> B{GeoDNS 判断来源} B -->|亚洲| C[返回亚洲节点 IP<br/>103.1xx.xx.xx] B -->|欧洲| D[返回欧洲节点 IP<br/>185.1xx.xx.xx] B -->|北美| E[返回北美节点 IP<br/>93.1xx.xx.xx] B -->|其他| F[返回默认节点 IP]

6.3 Anycast#

flowchart TB A[用户 A(北京)] --> B[Anycast IP: 1.1.1.1] C[用户 B(上海)] --> B D[用户 C(广州)] --> B B --> E{BGP 路由选择最近节点} E --> F[北京节点] E --> G[上海节点] E --> H[广州节点] A -.-> F C -.-> G D -.-> H

Anycast 原理:多个数据中心广播相同的 IP 地址,BGP 路由协议自动将用户引导到网络拓扑最近的节点。

七、DNSSEC#

7.1 DNSSEC 信任链#

flowchart TB A[根 DNS 的 KSK] -->|签名| B[根 DNS 的 ZSK] B -->|签名| C[.com TLD 的 DS 记录] C -->|验证| D[.com TLD 的 KSK] D -->|签名| E[.com TLD 的 ZSK] E -->|签名| F[example.com 的 DS 记录] F -->|验证| G[example.com 的 KSK] G -->|签名| H[example.com 的 ZSK] H -->|签名| I[example.com 的 A 记录]

7.2 DNSSEC 记录类型#

记录类型说明
DNSKEY公钥(KSK 和 ZSK)
RRSIG资源记录的数字签名
DS委派签发者(子区域 KSK 的哈希)
NSEC下一安全记录(证明域名不存在)
NSEC3NSEC 的哈希版本(防止域名遍历)

7.3 KSK 和 ZSK#

DNSSEC 使用两把密钥:
KSK(Key Signing Key)
├── 只用于签名 ZSK
├── 较长(2048-bit RSA 或更大)
├── 很少轮换(每年 1-2 次)
└── 通过 DS 记录建立父子信任链
ZSK(Zone Signing Key)
├── 用于签名区域内所有记录
├── 较短(1024-2048-bit RSA)
├── 频繁轮换(每月或每季度)
└── 由 KSK 签名,不需要父区域参与

7.4 签名验证过程#

// DNSSEC 验证 www.example.com 的 A 记录
// 1. 获取 A 记录及其 RRSIG
const aRecord = { name: "www.example.com", type: "A", data: "93.184.216.34" };
const rrsig = {
typeCovered: "A",
algorithm: 13, // ECDSA P-256
labels: 3,
originalTTL: 300,
signatureExpiry: 1711159200,
signatureInception: 1711072800,
keyTag: 12345,
signersName: "example.com",
signature: "0xABCDEF...", // 数字签名
};
// 2. 获取 example.com 的 DNSKEY
const dnskey = {
flags: 256, // ZSK
protocol: 3,
algorithm: 13,
publicKey: "0x123456...", // 公钥
};
// 3. 验证签名
const signedData = buildSignedData(aRecord, rrsig);
const isValid = verifyECDSA(dnskey.publicKey, signedData, rrsig.signature);
if (!isValid) {
throw new Error("DNSSEC 验证失败:记录可能被篡改");
}

7.5 NSEC/NSEC3:证明不存在#

; NSEC 记录按字母顺序排列域名
; 证明两个有序域名之间没有其他域名
example.com. IN NSEC beta.example.com. A NS SOA
; 含义: alpha.example.com 之后是 beta.example.com
; 之间没有任何域名
; alpha 只存在 A, NS, SOA 类型的记录
; NSEC3 对域名做哈希,防止遍历
; 2S9EHANOJVULAP7KQBVDMOJ0M1P1RQCH.example.com.
; IN NSEC3 1 0 2 ABCD 2T7B4G4VSA5SMI47K61MV5BV1A22BOJR

八、DNS over HTTPS 与 DNS over TLS#

8.1 传统 DNS 的安全问题#

传统 DNS(端口 53)的安全问题:
1. 明文传输
┌──────┐ UDP/TCP 明文 ┌──────┐
│ 客户端 │ ────────────────→ │ DNS │
└──────┘ └──────┘
攻击者可窃听查询内容和返回结果
2. 无身份验证
- 任何人都可以伪装 DNS 服务器
- ISP 可以返回篡改的响应
3. UDP 无序
- 响应可能被伪造
- ID 碰撞攻击(16-bit ID 空间有限)

8.2 DoH (DNS over HTTPS)#

sequenceDiagram participant C as 客户端 participant D as DoH 服务器 Note over C,D: 建立 TLS 连接 C->>D: TLS 握手 D->>C: TLS 握手完成 Note over C,D: HTTPS 请求 C->>D: GET /dns-query?dns=...<br/>Accept: application/dns-message D->>C: 200 OK<br/>Content-Type: application/dns-message<br/>Body: DNS 响应 Note over C,D: 或使用 POST C->>D: POST /dns-query<br/>Content-Type: application/dns-message<br/>Body: DNS 查询 D->>C: 200 OK + DNS 响应
# 使用 curl 测试 DoH
curl -s -H "Accept: application/dns-message" \
"https://dns.google/dns-query?dns=AAABAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE" \
--output - | hexdump -C
# 使用 doh-proxy
doh-client --domain example.com --type A --server https://dns.google/dns-query

8.3 DoT (DNS over TLS)#

DoT (DNS over TLS):
端口: 853
协议: TLS + DNS
用途: 通常用于路由器到 DNS 服务器的加密
DoH (DNS over HTTPS):
端口: 443
协议: HTTPS + DNS
用途: 通常用于浏览器到 DNS 服务器的加密
优势: 与普通 HTTPS 流量混合,更难被检测和封锁

8.4 加密 DNS 对比#

特性传统 DNSDoTDoH
端口53853443
加密TLSHTTPS (TLS)
隐蔽性
性能最快较快中等
防篡改
防窃听
浏览器支持原生原生

九、常见安全问题#

9.1 DNS 劫持#

sequenceDiagram participant C as 客户端 participant A as 攻击者 participant D as DNS 服务器 C->>A: DNS 查询(被中间人截获) A->>C: 返回伪造的 IP(指向恶意服务器) Note over C: 访问恶意网站 C->>A: 连接到恶意服务器 Note over C,D: 攻击方式 Note over A: 1. 修改本地 DNS 配置 Note over A: 2. 劫持路由器 DNS 设置 Note over A: 3. ISP 级别 DNS 污染

9.2 DNS 缓存污染#

// DNS 缓存污染攻击原理
// 攻击者抢在合法响应之前发送伪造的 DNS 响应
// 攻击条件:
// 1. 知道查询的事务 ID(16-bit,暴力猜解)
// 2. 知道查询的端口号(固定端口更容易猜)
// 3. 在合法响应到达之前发送伪造响应
// Kaminsky 攻击(2008)
// 利用源端口随机化不充分的漏洞
function kaminskyAttack(targetDomain) {
// 1. 向目标 DNS 服务器查询随机子域名
const randomSubdomain = Math.random().toString(36).slice(2);
const query = `${randomSubdomain}.${targetDomain}`;
// 2. 同时泛洪伪造的响应
for (let id = 0; id < 65536; id++) {
for (let port = 1024; port < 2048; port++) {
sendFakeDNSResponse(id, port, query, "evil-ip");
}
}
// 3. 伪造响应包含额外的权威记录
// 将目标域名的 NS 指向攻击者控制的服务器
}

9.3 DNS 放大攻击#

DNS 放大攻击(DDoS 的一种)
攻击原理:
1. 攻击者伪造源 IP(受害者 IP)
2. 向开放 DNS 解析器发送查询(使用 EDNS0 扩大响应)
3. DNS 解析器将大量响应发送到受害者 IP
放大倍数计算:
查询大小: ~60 字节
响应大小: ~4000 字节(使用 ANY 类型查询)
放大倍数: 4000 / 60 ≈ 66 倍
防御措施:
1. DNS 解析器不对外开发(仅服务可信客户端)
2. 源地址验证(BCP 38)
3. 限制响应大小
4. 禁用 ANY 查询

十、实战:使用 dig 命令#

10.1 基本查询#

# 基本查询
$ dig www.example.com
; <<>> DiG 9.18.0 <<>> www.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54321
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;www.example.com. IN A
;; ANSWER SECTION:
www.example.com. 300 IN A 93.184.216.34
;; Query time: 28 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sat Mar 22 08:00:00 UTC 2026
;; MSG SIZE rcvd: 56

10.2 追踪解析路径#

# +trace 参数显示完整解析链路
$ dig +trace www.example.com
; 根服务器
. 518400 IN NS a.root-servers.net.
. 518400 IN NS b.root-servers.net.
;; Received 1097 bytes from 198.41.0.4#53(a.root-servers.net)
; .com TLD 服务器
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
;; Received 899 bytes from 192.5.6.30#53(a.gtld-servers.net)
; 权威服务器
example.com. 172800 IN NS ns1.example.com.
example.com. 172800 IN NS ns2.example.com.
;; Received 200 bytes from 199.43.135.53#53(ns1.example.com)
; 最终答案
www.example.com. 300 IN A 93.184.216.34

10.3 查询特定记录类型#

# 查询 MX 记录
$ dig example.com MX
# 查询 AAAA 记录
$ dig www.example.com AAAA
# 查询 TXT 记录
$ dig example.com TXT
# 查询 NS 记录
$ dig example.com NS
# 查询 SOA 记录
$ dig example.com SOA
# 查询 CNAME 记录
$ dig www.example.com CNAME
# 反向查询(IP → 域名)
$ dig -x 93.184.216.34

10.4 DNSSEC 验证#

# 启用 DNSSEC 验证
$ dig +dnssec www.example.com
;; ANSWER SECTION:
www.example.com. 300 IN A 93.184.216.34
www.example.com. 300 IN RRSIG A 13 3 300 ...
;; flags: qr rd ra ad
;; 注意 ad 标志(Authenticated Data)= DNSSEC 验证通过
# 查询 DNSKEY
$ dig example.com DNSKEY
# 查询 DS 记录(建立信任链)
$ dig example.com DS

10.5 使用 nslookup#

# 简单查询
$ nslookup www.example.com
# 指定 DNS 服务器
$ nslookup www.example.com 8.8.8.8
# 交互模式
$ nslookup
> server 8.8.8.8
> set type=MX
> example.com
> set type=ANY
> example.com
> exit

FAQ#

Q1: 为什么修改了 DNS 记录但还没生效?#

DNS 使用多级缓存,每一级都有 TTL。修改记录后,需要等待所有层级的缓存过期。最坏情况下需要等待整个 TTL 周期(常见的 TTL 为 300 秒到 86400 秒)。如果 TTL 设置为 3600 秒,最多需要 1 小时才能全球生效。

Q2: DNS 使用 UDP 还是 TCP?#

DNS 默认使用 UDP 端口 53。当响应数据超过 512 字节时,会切换到 TCP(设置 TC 标志)。DNS 区域传输(zone transfer)始终使用 TCP。DoH 使用 HTTPS(TCP + TLS),DoT 使用 TLS(TCP)。

Q3: 为什么根域名服务器只有 13 组?#

DNS 报文在 UDP 模式下限制为 512 字节。13 组根服务器(每组包含多个全球分布的实例)的 NS 记录刚好能在 512 字节内放下。虽然现在有了 EDNS0 扩展,这个限制已经不是硬性约束,但 13 组根服务器的约定保留至今。实际通过 Anycast 技术,全球已有超过 1000 个根服务器实例。

Q4: DNS 缓存被污染了怎么办?#

清除各级缓存:浏览器缓存(chrome://net-internals/#dns)、OS 缓存(ipconfig /flushdnsresolvectl flush-caches)、路由器缓存(重启路由器)。如果 ISP 级别被污染,可以切换到可信的公共 DNS(如 8.8.8.8、1.1.1.1)或使用 DoH/DoT。

Q5: CNAME 和 A 记录可以同时存在吗?#

不可以。根据 DNS 规范,如果一个域名有 CNAME 记录,就不能有其他任何记录(SIG 除外)。这是 CNAME 与其他记录类型的互斥规则。如果需要同时指向别名和拥有自己的记录,应该使用其他方案(如 ALIAS/ANAME 记录,由 DNS 服务商在解析时展开为 A 记录)。

Q6: DNSSEC 能防止 DNS 劫持吗?#

DNSSEC 可以检测到 DNS 响应被篡改(因为签名验证会失败),但无法阻止篡改行为本身。如果客户端严格验证 DNSSEC,篡改的响应会被丢弃,客户端得到 SERVFAIL 错误。DNSSEC 解决的是数据完整性和来源验证问题,不是可用性问题。

参考资料#

支持与分享

如果这篇文章对你有帮助,欢迎支持作者或分享给更多人

DNS 解析完整流程:从域名到 IP
https://blog.souloss.com/posts/principles/dns-resolution-complete-process/
作者
Souloss
发布于
2023-05-24
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时