DNS 改了没生效?其实是 Clash fake-ip 在骗你
部署新子域名,改完 A 记录,习惯性跑一句 dig 验证,结果回来的是:
$ dig +short sub.example.com A
198.18.0.202
198.18.0.202——既不是我的服务器 IP,也不是 Cloudflare,完全陌生。第一反应:DNS 没有传播完?注册商出问题了?记录填错了?追了半小时,全是红鲱鱼。真相只有一句话:这个地址是假的,是本地代理伪造的。
现象
dig +short <域名>/nslookup/ping解析出198.18.x.x或198.19.x.x(RFC 2544 基准测试保留段),有时也是240.x.x.xdig @1.1.1.1 <域名>直接超时,没有响应- 但浏览器里访问该域名完全正常,页面加载无误
- 实际业务流量没有任何异常
根因
这是 Clash / ClashX / Mihomo / Surge / Stash 等代理客户端 fake-ip 模式的正常工作机制,不是 Bug。
在 fake-ip 模式下,代理接管了 OS 的 DNS 解析器(通常是 127.0.0.1:53)。每当应用发起 DNS 查询,代理不等真实响应,立刻返回一个 198.18.0.0/15 段里的占位地址,同时在内部维护一张映射表:198.18.0.202 → sub.example.com。当 TCP 连接发往这个假 IP 时,代理拦截、查表、替换为真实目标,再通过隧道转发出去。
这套机制的好处是减少 DNS 查询延迟(不等 RTT 就能建连);代价是本机的解析结果完全是假的。dig @1.1.1.1 超时,是因为代理同时劫持了出站 :53 UDP,Cloudflare 的 53 端口根本收不到包。
只要本地跑着 Clash/Surge 等代理且启用了 fake-ip(绝大多数用户的默认配置),dig / nslookup / ping 的解析结果对"域名指向哪个真实 IP"这件事毫无参考价值。198.18.0.0/15 是代理分配的会话级占位符,每次重启代理都会变。
正解
绕过本地解析器,直接查公共 DNS,或者在没有代理的机器上查:
方法一:指定公共解析器(推荐)
# 国内首选 AliDNS,在代理环境下通常不被拦截
dig @223.5.5.5 +short sub.example.com A
# Google DNS(代理可能劫持 :53,若超时换 AliDNS)
dig @8.8.8.8 +short sub.example.com A方法二:在目标服务器上解析(最权威)
服务器没有本地代理,解析结果就是全球真实传播状态:
ssh root@your-server 'getent hosts sub.example.com'
# 输出示例:203.0.113.10 sub.example.com方法三:在线工具
dnschecker.org 会从全球多个节点同时查询,一眼看清传播进度。
dig @223.5.5.5 +short <域名> 和 ssh server 'getent hosts <域名>' 返回相同的真实 IP,而裸 dig <域名> 还在返回 198.18.x,这个差异本身就证明 fake-ip 是根因,DNS 配置没有问题。
诊断速查
| 命令 | 返回 198.18.x | 返回真实 IP |
|------|:---:|:---:|
| dig +short <域名> | fake-ip 中 | 未开启 fake-ip |
| dig @1.1.1.1 +short <域名> | 代理拦截 :53 | 代理放行 :53 |
| dig @223.5.5.5 +short <域名> | — | 这个才是真相 |
| 服务器 getent hosts <域名> | — | 这个才是真相 |
只要公共解析器和服务器端结果一致且指向目标 IP,你的 DNS 就是正确的,不需要任何修改。
一句话外卖
开着 Clash fake-ip 时,本机的 DNS 解析结果是代理伪造的占位地址,验证域名解析只能用
dig @223.5.5.5或在无代理的服务器上执行。