为什么开了 VPN 还是 "doesn't serve your region"?
从系统代理的局限到 TUN 模式,彻底搞懂虚拟网卡与 Fake-IP 原理
你打开了 VPN,绿灯亮着,节点也连上了——但 Cursor 还是弹出「This model provider doesn't serve your region」。这不是 VPN 没连上,而是这个请求根本没经过 VPN。
🎯 问题现象:开了代理,还是访问不了
你大概遇到过这类情况:
| 场景 | 现象 |
|---|---|
| IDE 插件(Cursor、Copilot) | 报 region 限制错误 |
| CLI 工具(curl、npm、pip) | 速度慢或超时 |
| 游戏客户端 | 高延迟,不走代理 |
| gRPC / QUIC 协议的应用 | 完全不走代理 |
| 系统层 SDK(如 Apple 框架) | 忽略代理设置 |
原因只有一个:普通的系统代理,覆盖不了这些程序。
🧠 根源:系统代理的工作边界
系统代理是什么?
Clash 默认启用的「系统代理」,本质上是在操作系统层面设置一个 HTTP/SOCKS 代理地址(比如 127.0.0.1:7890),然后等应用程序主动来用它。
应用程序 → 读取系统代理设置 → 把请求发到 127.0.0.1:7890 → Clash 转发
关键词是「主动来用它」。
哪些程序会被漏掉?
大量程序不遵守系统代理设置:
- CLI 工具:
curl、git、npm、pip默认不读系统代理,需要手动设置环境变量HTTPS_PROXY - Electron 应用:部分版本有自己的网络栈,不走系统代理
- 游戏客户端:通常直连,系统代理对 UDP 也无效
- gRPC / QUIC:HTTP/2 over UDP,传统 HTTP 代理不支持
- 系统级进程:macOS 的很多系统服务走自己的通道
- JVM / .NET 应用:需要额外的 JVM 参数才能走代理
网络栈视角
系统代理工作在 OSI 第七层(应用层),它的机制是:应用发请求前,先问一下"有没有代理?",有的话转发给代理,没有或者不问的话直接出去。
┌─────────────────────────────────────────────┐
│ 第7层 应用层 HTTP / HTTPS / gRPC │ ← 系统代理工作在这里
│ 第4层 传输层 TCP / UDP │
│ 第3层 网络层 IP │
│ 第2层 数据链路层 Ethernet / Wi-Fi │
│ 第1层 物理层 │
└─────────────────────────────────────────────┘
不主动配合的程序,流量直接从第三层出去了,Clash 完全感知不到。
🏛️ TUN 模式:用虚拟网卡接管整个网络层
TUN/TAP 设备是什么?
TUN(Network TUNnel)是操作系统提供的一种虚拟网络设备。它和真实网卡的区别是:
- 真实网卡:数据包 → 物理硬件 → 网线/无线 → 外部网络
- TUN 设备:数据包 → 虚拟网卡驱动 → 用户空间程序(也就是 Clash)
Clash 创建一个 TUN 设备(通常叫 utun 或 Meta),然后修改系统路由表,把所有流量的下一跳指向这个虚拟网卡:
ip route add default via 198.18.0.1 dev utun0
流量路径对比
系统代理模式:
应用程序(主动配合)
↓
127.0.0.1:7890(Clash 入口)
↓
规则匹配 → 代理节点 → 目标服务器
应用程序(不配合)→ 直接出网 ← Clash 看不到
TUN 模式:
所有应用程序的所有流量
↓
网络层(IP 包)
↓
路由表 → 虚拟网卡 utun0
↓
Clash 进程(用户空间)
↓
规则匹配 → 代理节点 / 直连
TUN 模式在网络层拦截,不管应用程序有没有"主动配合",只要是发出去的 IP 包,Clash 都能看到并处理。
为什么所有流量都逃不掉?
因为路由表是操作系统的最底层转发决策。一个 IP 包要发出去,必须查路由表找下一跳。TUN 模式把默认路由改成了虚拟网卡,就像把所有出城的路都汇聚到一个收费站——不管你开什么车,都得从这里过。
🔍 DNS 的坑:Fake-IP vs Real-IP
开了 TUN 模式后,随之而来的是一个新问题:DNS。
为什么 DNS 是关键?
Clash 做规则匹配时,需要知道目标域名(比如 api.openai.com)应该走代理还是直连。但 TCP 连接是基于 IP 的——如果应用先把域名解析成 IP,再发连接,Clash 只能看到一个 IP 地址,不知道原始域名是什么,规则匹配就失效了。
更麻烦的是:DNS 污染。国内的 DNS 服务器会对某些域名返回错误的 IP,应用拿到脏 IP 后发出连接,Clash 就算能拦截,也已经是错误的目标了。
Real-IP 模式(传统方式)
Clash 使用系统 DNS 或配置的上游 DNS 解析域名,得到真实 IP。
应用 → DNS 查询 api.openai.com
→ Clash DNS → 上游 DNS(可能被污染)
→ 返回真实 IP(可能是脏 IP)
→ 应用发起 TCP 连接到该 IP
→ Clash 拦截,尝试从 IP 反查域名
问题:
- DNS 查询本身可能泄漏(走直连的 DNS 请求暴露了你要访问什么)
- 被污染的域名返回脏 IP,规则匹配失效
- IP 到域名的反查不总是准确的
Fake-IP 模式(Clash 增强模式推荐)
Clash 内置一个 DNS 服务器,当应用查询域名时:
- 立刻返回一个假 IP(从
198.18.0.0/15段里取),不等真实 DNS 响应 - 在本地维护一张映射表:
198.18.0.1 → api.openai.com - 当应用用这个假 IP 发起连接时,Clash 从映射表里查回真实域名
- 用域名做规则匹配,再去真正解析并转发
时间轴 →
应用: [DNS 查询 api.openai.com] → [立刻得到 198.18.0.1] → [发起 TCP 连接]
Clash: [记录映射表] ──────────────────────────────────── [查到域名,做规则匹配,真正解析并转发]
对比
| 维度 | Real-IP 模式 | Fake-IP 模式 |
|---|---|---|
| DNS 解析时机 | 应用发起,可能被污染 | Clash 全权控制 |
| 规则匹配依据 | IP(不稳定) | 域名(准确) |
| DNS 泄漏风险 | 有 | 基本消除 |
| 连接速度 | 正常(需等 DNS) | 更快(假 IP 立刻返回) |
| 兼容性 | 好 | 少数应用有问题(需加 fake-ip-filter) |
Fake-IP 模式下,DNS 污染的问题被彻底绕开——因为域名从来没有被「真正解析」过,直到 Clash 内部用可信的上游(比如 8.8.8.8 over DoH)去解析。
⚙️ Clash Verge 实际配置
开启 TUN 模式
在 Clash Verge(Clash Verge Rev)中:
- 进入 设置 → TUN 模式,打开开关
- macOS / Windows 首次开启需要管理员权限(安装虚拟网卡驱动)
- 确认网卡列表里出现
utun设备(macOS 上通常命名为utun1024)
TUN 模式堆栈:System / GVisor / Mixed
开启 TUN 后最重要的选项是堆栈(Stack),它决定在哪里实现 TCP/IP 协议栈:
| 堆栈 | 原理 | 性能 | 兼容性 | 适合场景 |
|---|---|---|---|---|
| System | 使用操作系统内核的 TCP/IP 栈 | 最好,接近原生 | 一般 | 性能敏感、追求低开销 |
| GVisor | Google 开源的用户空间 TCP/IP 栈,完全绕开内核 | 最差,有额外拷贝开销 | 最好 | 兼容性问题多的场景 |
| Mixed | TCP 用 GVisor,UDP 用 System | 中等 | 好 | 日常推荐 |
GVisor 的开销来源是:每个数据包在内核态 ↔ 用户态之间来回拷贝,再走一遍用户空间实现的完整协议栈。高并发时 CPU 会明显上升。日常使用推荐 Mixed——TCP 走 GVisor 保兼容性,UDP(游戏、视频)走 System 保性能。
其他配置项说明
| 选项 | 说明 |
|---|---|
| 自动设置全局路由 | 自动把系统默认路由指向虚拟网卡,这是 TUN 模式的核心开关,必须开启 |
| 严格路由 | 添加更激进的路由规则,防止任何流量绕过 TUN;副作用是局域网访问可能失效(如路由器管理页、NAS),默认关闭即可 |
| 自动选择流量出口接口 | 自动检测当前活跃的物理网卡(Wi-Fi / 以太网),经常切换网络时开着省心 |
DNS 劫持 any:53 | 强制拦截所有目标端口 53 的 DNS 请求,包括硬编码了 8.8.8.8 的应用,Fake-IP 能生效的前提 |
| 最大传输单元(MTU)1500 | 标准以太网 MTU,Clash 内部处理分片,通常不用改;若遇到大文件传输异常可调低至 1400 |
TUN 模式的额外开销
开启 TUN 模式确实有代价:
- CPU:GVisor 栈开销最大,Mixed / System 较小;正常使用感知不明显,高并发(几百个并发连接)时差异明显
- 内存:Clash 需要维护所有连接的状态表,比系统代理模式多约 50–100 MB
- 稳定性:整个系统网络都依赖 Clash 进程;系统代理模式下 Clash 崩溃只是代理失效,直连还在;TUN 模式下 Clash 崩溃会直接断网
DNS 配置建议
在你的 Clash 配置文件中:
dns:
enable: true
enhanced-mode: fake-ip # 开启 Fake-IP
fake-ip-range: 198.18.0.1/16
nameserver:
- https://8.8.8.8/dns-query # DoH,防污染
- https://1.1.1.1/dns-query
fake-ip-filter: # 这些域名不用 Fake-IP(常见兼容性白名单)
- "*.lan"
- localhost.ptlogin2.qq.com
- +.stun.*.*
TUN 配置
tun:
enable: true
stack: mixed # 推荐:TCP 用 GVisor,UDP 用 System
auto-route: true # 自动修改路由表
auto-detect-interface: true # 自动选择出口网卡
dns-hijack:
- any:53 # 劫持所有 DNS 请求
⚠️ 常见踩坑
和其他 VPN 冲突
TUN 模式和其他 VPN(Wireguard、OpenVPN、公司 VPN)都会修改路由表,同时开启必然冲突。同一时间只能有一个接管路由。
macOS SIP 问题
部分 macOS 版本在开启系统完整性保护(SIP)时,安装虚拟网卡驱动会失败。Clash Verge Rev 通常已处理这个问题,但遇到报错时检查驱动是否正确安装。
Fake-IP 导致某些应用异常
少数应用会校验 IP 地址的合法性或缓存 IP,收到 198.18.x.x 的假 IP 后行为异常。把这些域名加入 fake-ip-filter 白名单即可,它们会走 Real-IP 模式解析。
DNS 没有走 Clash 接管
如果系统 DNS 没有被指向 Clash(通常是 198.18.0.1 或 127.0.0.1),Fake-IP 机制不会生效。开启 dns-hijack: any:53 可以强制劫持所有 DNS 请求,不管应用把 DNS 发到哪里。
📝 总结:什么时候必须用 TUN 模式?
| 场景 | 系统代理够用? | 需要 TUN? |
|---|---|---|
| 浏览器访问网页 | ✅ | 不必要 |
| IDE 插件(Cursor、Copilot) | ❌ 经常漏 | ✅ |
| CLI 工具(curl、git、pip) | ❌ 需手动配环境变量 | ✅ |
| 游戏(TCP) | ❌ | ✅ |
| 游戏(UDP) | ❌ | ✅ |
| gRPC / QUIC 应用 | ❌ | ✅ |
| 系统级进程 | ❌ | ✅ |
一句话总结:系统代理是「君子协定」,TUN 模式是「物理拦截」。如果你在意「所有流量都走代理」,TUN 模式是唯一可靠的选择。