DNS与FakeIP排障:污染、副作用、TUN调优
1. GFW 旁路注入:你被怎么污染的
明文 DNS 经过国际出口时,GFW 站在光纤旁边偷看。每个查询包它瞥一眼里面的域名,命中黑名单(google.com、youtube.com 这类),立刻伪造一个回包,源地址写成你查的 DNS 服务器 IP,发回给你。
%%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#3B82F6', 'actorTextColor': '#000'}}}%%
sequenceDiagram
autonumber
participant App as "你的应用"
participant DNS as "上游 DNS<br/>(8.8.8.8 / 阿里)"
participant GFW as "GFW (旁路)"
App->>DNS: "查 youtube.com (明文 UDP)"
Note over GFW: "偷看到域名命中黑名单"
par 正常应答
DNS-->>App: "真实 IP (慢)"
and GFW 抢答
GFW-->>App: "伪造 IP 93.46.8.x (更快到)"
end
Note over App: "UDP 没法验证哪个真<br/>用先到的那个"
App->>App: "连了 93.46.8.x (打不开)"伪造包从 GFW 设备直接发出来,路径比 “ 真 DNS 服务器答复 “ 短得多,几乎总是先到。UDP 协议没法验证哪个是真,系统采信先到的那个。真答复后到时被当成 “ 重复包 “ 直接扔了。
“ 我换用 8.8.8.8 怎么也被污染 “? 因为 GFW 不管你查的是哪个 DNS,它只看请求里的域名。换 DNS 服务器没用,必须加密查询内容(让 GFW 看不到域名) 或绕开 UDP(用 TCP)。这就是为什么 DoH(DNS over HTTPS) 是默认推荐——HTTPS 加密之后 GFW 看不到里面查的是啥。
GFW 抢答的假 IP 不是随机的,集中在固定几段:
| 投毒 IP 段 | 特征 |
|---|---|
93.46.8.x | 意大利 |
203.98.7.x | 新西兰 |
8.7.198.x | Level3 网段 |
240.0.0.0/4 | IANA 保留段(正常网络绝不会出现) |
这个特征催生了第 3 章的 fallback-filter——“ 看到回来的是这几个段,当作被污染,用 fallback 的结果 “。
2. Fake-ip 副作用:局域网瘫痪 + 直连还原
fake-ip 撒了个 “ 谎 “——它给应用的不是真 IP。多数场景这无所谓,但有两类场景会翻车。
2.1 局域网打印机被瞬间废掉
家里的网络打印机叫 printer.local,NAS 叫 nas.lan,公司的代码服务器叫 gitlab.internal.company.com。它们都是域名。
fake-ip 模式下 Clash 不管三七二十一:你查 printer.local,我发个 198.18.0.7。电脑收到 198.18.0.7,真的把打印任务发到这个地址。Clash 截胡这个连接,查表知道 “ 这个 IP 对应 printer.local”,然后……然后它去哪?打印机在你局域网,Clash 既不知道它真实 IP,也没法用代理节点访问。结果是打印机连不上、Bonjour 设备发现失败、AirPlay 投屏没设备。
救法是告诉 fake-ip:” 这几个域名别给假 IP,放过 “。这就是 fake-ip-filter:
1 | dns: |
匹配到这里的域名走 redir-host 路线——正常解析、拿到真 IP、走直连或代理规则。
精心型机场订阅会写一份很全的 filter。敷衍型订阅没写,这就是为什么开了 TUN 之后 printer.local 突然找不到——不是 Clash 的锅,是订阅没写 filter。
2.2 翻车现场:Navicat 连 AWS RDS 被错代理到 Netflix
上一节讲了直连分支怎么 “ 反查域名拿真 IP” 的机制,听起来 fake-ip + 域名规则配合得很好。但当分流规则用的是 IP 段而不是域名时,会出一类特别隐蔽的翻车。
实例:你用 Navicat 连 AWS 中国区的 RDS,域名长这样:
1 | xxx.cn-northwest-1.rds.amazonaws.com.cn |
明明是国内服务(IP 在国内宁夏机房),却莫名其妙连不上。打开 Clash 日志一看:
1 | [TCP] 198.18.0.1:51627(Navicat) --> 34.208.231.7:22 |
34.208.0.0/12 这条 IP 段规则把它当成了海外服务,丢给了 Netflix 节点。Netflix 节点在洛杉矶,绕地球半圈回宁夏,能连上才奇怪。
为什么会这样:
- Navicat 拿到的是 fake-ip
198.18.0.x,真正去连接时 Clash 反查到amazonaws.com.cn - 但分流规则没有
DOMAIN-SUFFIX,amazonaws.com.cn,DIRECT,只有按 IP 段写的IP-CIDR,34.208.0.0/12,Netflix - Clash 为了匹配 IP 段规则,调用本地 DNS 解析
amazonaws.com.cn,拿到34.208.231.7(AWS 在全球用一张 IP 表) - 这个 IP 命中了
34.208.0.0/12,被分给 Netflix
根因:AWS 在全球用一张 IP 表,34.208.x.x 在多数规则集里被划进 “ 海外 AWS”。但 AWS 中国是合资公司单独运营、用了另一套 IP 段——规则维护者不可能穷举,必然漏。
救场方法 1(推荐):给目标 IP 加一条精确直连:
1 | IP-CIDR,34.208.231.7/32,DIRECT,no-resolve |
no-resolve 这个尾巴的意思是:” 这条规则按 IP 匹配,不要为了它去做 DNS 查询“。两个好处:
- 对方本来就是 IP 连接(Navicat 配的就是 IP)——免去无意义解析
- 对方是域名连接时,也不会因为这条 IP 规则触发反向解析,导致 fake-ip 的
198.18.x.x被错误地交给 DNS 模块去查
救场方法 2(更通用):给域名加一条直连,优先级放在 IP 规则之前:
1 | DOMAIN-SUFFIX,amazonaws.com.cn,DIRECT |
域名规则优先级高、不依赖 GeoIP 数据库,是最稳的方法。
反面教材:很多人遇到这种情况会去切 Global 模式想 “ 全代理总行了吧 “,但 Global 反而把这台 RDS 强制扔到 Netflix,更连不上。Global ≠ 解决一切,见 第一篇 ch.8 的澄清。
2.3 Navicat 连 AWS RDS 凭什么直连
Navicat 用域名连国内 AWS RDS,需要直连。fake-ip 模式下,Navicat 拿到的是 198.18.0.x 这种假 IP,怎么直连?
关键在分流引擎做了一次 “ 反查 “:
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#3B82F6', 'primaryTextColor': '#fff', 'lineColor': '#60A5FA'}}}%%
flowchart TD
A["Navicat 查 xxx.rds.amazonaws.com.cn"] --> B["Clash 发 198.18.0.9"]
B --> C["Navicat 连 198.18.0.9:3306"]
C --> D["Clash 截胡 → 查表知道是 amazonaws.com.cn"]
D --> E{"匹配规则"}
E -->|"DOMAIN-SUFFIX,amazonaws.com.cn,DIRECT"| F["调本地 nameserver<br/>查真实 IP"]
F --> G["拿到 161.189.x.x"]
G --> H["直连 161.189.x.x:3306"]
classDef key fill:#F59E0B,stroke:#D97706,color:#000
classDef ok fill:#10B981,stroke:#059669,color:#fff
class F key
class H ok注意第 6 步——直连分支会临时绕开 fake-ip,真去解析一次。这就是为什么直连场景下,本地 nameserver 也得配对(多数机场订阅会指向国内 DNS 比如阿里)。
如果日志报 “ 直连域名解析失败 “,通常是机场的 nameserver 全配的是境外 DNS(比如 8.8.8.8),国内域名走不通。解法是用脚本(见第 5 章)把 nameserver-policy 里 geosite:cn 单独指给国内 DNS。
3. Fallback / Fallback-filter / Nameserver-policy 三件套
精心型机场的 dns: 块通常长成这样,理解了这三件套就能看懂大部分配置:
1 | dns: |
工作流程:
nameserver和fallback并发发查询(不是串行)- 等
nameserver先回,用fallback-filter判断:可信吗? - 可信 → 用
nameserver的结果(快) - 不可信 → 等
fallback的结果用(保险) nameserver-policy优先级最高,命中就跳过上面整套流程
这套设计的核心思想:国内域名走国内 DNS(快),境外域名走境外 DNS(防污染)。判断 “ 这个域名是国内还是境外 “ 不靠你列名单,靠 GeoIP——看主用 DNS 给你的 IP 是不是中国。
4. TUN 三档力度:gVisor / Mixed / System
Clash Verge 里 TUN 不止一个开关。点进 “ 虚拟网卡模式 “ 的齿轮,能选 “ 堆栈 “(stack)。这就是 TUN 的接管力度:
| 堆栈 | 接管什么 | 什么时候要 | 代价 |
|---|---|---|---|
| gVisor(增强,默认) | TCP 全管,UDP 基础管 | 日常浏览 + 终端 + IDE | 几乎无 |
| Mixed(混合) | TCP + UDP 都更彻底 | 需要 UDP 的应用:部分游戏 NAT、WebRTC、视频会议 | 偶发兼容问题 |
| System(系统栈 / 游戏档) | 直接用操作系统的网络栈,接管最狠 | 上面两档都搞不定的极端情况 | macOS 上偶尔崩、对系统侵入大 |
底层原理差异:
- gVisor:Google 出的用户态 TCP/IP 协议栈,Clash 自己解析 IP 包、TCP 握手、流量控制。优点是隔离性好、不依赖系统、跨平台。缺点是 UDP 性能一般、某些 UDP 协议(如 QUIC、游戏的自定义 UDP)兼容性差
- Mixed:TCP 用 gVisor、UDP 用更激进的接管。多数 UDP 场景能跑,代价是出问题难定位
- System:直接调用操作系统的 socket(macOS 上是
utun设备 + PF 路由),等于让 Clash 用宿主机的协议栈。性能最好,但崩了可能影响系统网络栈,且不同 macOS 版本行为不一致
兜底建议:默认用 gVisor,别折腾。除非:
- 打游戏 NAT 卡了(典型:交换机 / Switch 上联机 NAT 受限)→ 升级 Mixed
- WebRTC 视频会议有问题 → 升级 Mixed
- Mixed 也搞不定 → 试 System(自己评估系统稳定性风险)
5. 实战配置模板:用脚本注入完整 Dns 块
如果你的订阅是上一篇 ch.6.3 里的 “ 中等型 “ 或 “ 敷衍型 “,直接开 DNS 覆写会把订阅里仅有的几行也盖掉。更好的做法是用 Verge 的全局扩展脚本注入——既补全缺失字段,又保留订阅原有的(比如机场专属 nameserver-policy)。
操作位置:Clash Verge 订阅页底部 → “ 全局扩展脚本 “ → 点编辑图标 → 粘贴下面这段:
1 | function main(config) { |
要点:
default-nameserver必须是纯 IP(不能是https://域名),因为它专门用来解析其他 DNS 服务器的域名,鸡和蛋问题prefer-h3: true优先用 DoH3(最快的加密 DNS,见附录)nameserver-policy用 GeoSite 把国内外域名分给不同 DNS,避免国内域名走境外 DNS 慢fake-ip-filter用 spread 语法保留订阅原有条目,再追加你自己关心的- DNS 覆写开关要保持关——脚本注入和覆写是两条互斥路径,开覆写会让脚本白注
保存后右键订阅 → “ 重新激活订阅 “ 才会生效。
6. 常见问题速查
| 现象 | 原因 | 解决 |
|---|---|---|
ping 域名返回 198.18.x.x,以为代理坏了 | ping 用 ICMP 不走代理,看到的是 fake-ip。用 curl -I https://xxx 验代理 | 不用解决,这是正常的 |
| 内网打印机 / NAS 找不到 | mDNS / .local 被分配了假 IP | 加进 fake-ip-filter |
| 双重 DNS 拦截,解析异常 | 路由器 OpenClash + 设备 Verge 都接管了 | 二选一,别套娃 |
| WebRTC 泄漏真实 IP | 浏览器 P2P 绕过代理 | 浏览器装 WebRTC 防泄漏插件 |
| Verge 重启后短暂断网 | 映射表清空,应用缓存的假 IP 失效 | 开 store-fake-ip: true |
| 银行 / 金融 App 无法登录 | 应用校验 IP 归属地,假 IP 不通过 | 把该 App 域名加 fake-ip-filter |
nslookup xxx 114.114.114.114 返回 198.18.x.x | TUN 已经截胡所有 DNS,你指定的 DNS 服务器没用 | 想看真 IP 把域名加 fake-ip-filter |
| 国内域名访问慢、走了境外节点 | 机场 nameserver 全是境外 DNS,国内域名也走 fallback | 用第 5 章脚本,给 geosite:cn 单独指国内 DNS |
| 直连域名报 “ 解析失败 “ | 同上,机场 nameserver 配置不当 | 同上 |