DNS 排查手册
线上出问题,一半时候第一步该查 DNS。这份是速查表。
排查顺序
1. 域名能不能解析 dig / nslookup
2. 解析到的 IP 对不对 对比多台 DNS
3. 那个 IP 通不通 ping / telnet 端口
4. TLS 握手成不成 openssl s_client
5. HTTP 层对不对 curl -v
别跳步。 跳过第 2 步就抓不到 DNS 污染。
1. 基础解析
dig example.com A
dig example.com AAAA
dig example.com MX
dig example.com TXT
dig example.com NS
只要答案,不要一堆输出:
dig +short example.com A
2. 指定 DNS 服务器(关键步骤)
dig @223.5.5.5 example.com A # 阿里
dig @119.29.29.29 example.com A # 腾讯
dig @1.1.1.1 example.com A # Cloudflare
dig @8.8.8.8 example.com A # Google
结果不一致 = 有问题。
判断 DNS 污染的特征
| 特征 | 含义 |
|---|---|
| 不同 DNS 返回完全不同网段的 IP | 污染 |
| 返回的 IP 属于知名大厂(Facebook/Twitter) | 典型污染(GFW 会用这些 IP 回包) |
| 每次查询 IP 都变 | 污染或轮询 |
dig 返回 SERVFAIL 但网页能开 | 本地 hosts 或代理 |
真实案例(我亲测):
dig @223.5.5.5 xxx.workers.dev → 103.252.115.53
dig @119.29.29.29 xxx.workers.dev → 108.160.169.37 (Facebook)
dig @1.1.1.1 xxx.workers.dev → 69.171.229.73 (Facebook)
dig @8.8.8.8 xxx.workers.dev → 128.242.240.244
四个 DNS 四个不同答案,全是假的 → 这个域名被污染了。
3. 查 DNSSEC
dig example.com DS
dig example.com DNSKEY
- 有
DS+DNSKEY→ 已启用 - 两个都空 → 未启用
未启用的风险:中间人可以伪造应答,用户访问到假站点。 自建域可以一键开,托管在别人二级域下的开不了。
4. 追踪完整解析链
dig +trace example.com
从根域一路追到权威服务器。适合排查"为什么某个 NS 不生效"。
5. 查 MX(邮件能不能收)
dig +short example.com MX
排序后输出(优先级低的先试):
10 mail1.example.com.
20 mail2.example.com.
MX 为空 = 收不到邮件。 这是注册第三方服务时最常见的死因。
6. 查 SPF / DMARC
dig +short example.com TXT | grep spf
dig +short _dmarc.example.com TXT
SPF 结果解读
| 结尾 | 含义 | 风险 |
|---|---|---|
-all | 只有列表内主机能发信 | ✅ 严格,正常 |
~all | 软失败,建议拒收 | ✅ 常见,可接受 |
?all | 不表态 | ⚠️ 弱 |
+all | 任何主机都能发信 | ❌ 等于没配 SPF |
特例:v=spf1 -all 单独出现
这是一个信号:这个域声明"只能收,不能发"。 典型于一次性邮箱、转发域。做风控的系统看到会直接扣分。
7. 端口连通性
# TCP
nc -zv example.com 443
telnet example.com 80
# Windows
Test-NetConnection example.com -Port 443
别用 ping 判断服务是否可用 —— 很多服务器禁 ICMP,但服务正常。
8. TLS 握手
openssl s_client -connect example.com:443 -servername example.com
看这几行:
subject=CN = example.com
issuer=C = US, O = Let's Encrypt
Verify return code: 0 (ok)
Verify return code 非 0 就是证书有问题。
查证书有效期:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -dates
9. HTTP 层
curl -v https://example.com
curl -I https://example.com # 只看 headers
curl -o /dev/null -s -w "%{http_code} %{time_total}\n" https://example.com
看 curl -v 里的:
* Connected to example.com (1.2.3.4) port 443 ← 连的是哪个 IP
* TLSv1.3 (IN), TLS handshake, Server hello ← TLS 版本
< HTTP/2 200 ← 状态码
< server: cloudflare ← 后端是谁
10. 排查清单
出问题时按这个顺序查,一条条打勾:
- [ ]
dig +short 域名有结果吗 - [ ] 多个 DNS 服务器结果一致吗
- [ ] 解析出的 IP 属于该服务的正常网段吗
- [ ]
dig 域名 MX有值吗(要收信的话) - [ ]
dig 域名 TXT有 SPF 吗 - [ ]
dig 域名 DS有值吗(要防劫持的话) - [ ] 端口通吗(用
nc不用ping) - [ ]
openssl s_client的 return code 是 0 吗 - [ ] 证书过期了吗
- [ ]
curl -v连的 IP 和 dig 出来的一致吗
第 2 条和第 10 条最容易漏,也最容易定位问题。
常用一行命令
# 快速体检
for d in 223.5.5.5 1.1.1.1 8.8.8.8; do echo -n "$d: "; dig +short @$d example.com A | head -1; done
# 证书还剩几天
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -enddate
# 批量查 MX
for d in a.com b.com c.com; do echo -n "$d: "; dig +short $d MX | head -1; done