Skip to content

从 GFW 到 WSL2:代理架构完全解析

本文系统性地解释「为什么国内访问不了外网」「Clash 如何解决这个问题」以及「WSL2 为何需要特殊配置」,帮你真正理解整个网络代理的工作原理。


一、国内为什么访问不了外网?

1.1 正常的网络访问流程

在没有任何干预的情况下,你访问 google.com 的过程是这样的:

你的电脑

  │  ① 问:google.com 是哪个 IP?

本地 DNS 服务器

  │  ② 答:142.250.x.x

你的电脑

  │  ③ 向 142.250.x.x 发起连接

Google 服务器  ✓

1.2 GFW 的拦截方式

GFW(防火长城)在这个流程里设置了两道关卡:

你的电脑

  │  ① 问:google.com 是哪个 IP?

┌─────────────────────────────────┐
│           GFW                   │
│  DNS 污染:返回假 IP 或不响应    │  ← 第一道关卡
└─────────────────────────────────┘

  │  ② 答:错误的 IP(或超时)

你的电脑

  │  ③ 向错误 IP 发起连接

┌─────────────────────────────────┐
│           GFW                   │
│  IP 封锁:直接丢弃数据包         │  ← 第二道关卡
└─────────────────────────────────┘

  ✗  连接失败

两种主要拦截手段

  • DNS 污染:篡改 DNS 查询结果,让你拿到错误的 IP
  • IP 封锁:直接封禁目标服务器的 IP 段,数据包到达 GFW 就被丢弃

二、Clash 如何绕过 GFW?

2.1 加密隧道:骗过 GFW 的核心手段

要理解 Clash 怎么工作,先要理解它是怎么「骗过」GFW 的。

GFW 是怎么识别流量的?

GFW 不只是封 IP,它还会做深度包检测(DPI),也就是分析你发出的数据包长什么样:

你发出的数据包


┌─────────────────────────────────────┐
│              GFW · DPI 引擎          │
│                                     │
│  这是 HTTP 流量吗?  → 可以通过      │
│  这是普通 HTTPS?   → 可以通过      │
│  这是 VPN 特征?    → 封锁!        │
│  这是 Shadowsocks? → 封锁!        │
│  这是随机加密数据?  → 可疑,观察…  │
└─────────────────────────────────────┘

早期的 VPN(如 PPTP、L2TP)有非常明显的协议特征,GFW 一眼就能认出来封掉。

现代代理协议如何伪装

Clash 使用的协议(如 VMess、VLESS、Trojan、Shadowsocks)的核心思路是:让流量看起来像普通的 HTTPS 流量

以最常见的 Trojan 协议为例:

你的电脑(Clash)                    境外服务器
  │                                      │
  │  ① 和境外服务器建立真正的 TLS 连接   │
  │     (和访问普通 HTTPS 网站完全一样) │
  │ ─────────────────────────────────→  │
  │                                      │
  │  ② 在 TLS 加密隧道里面,发送真实请求 │
  │     "帮我访问 google.com"            │
  │  (GFW 只看到加密数据,看不出内容)  │
  │ ─────────────────────────────────→  │
  │                                      │
  │  ③ 境外服务器解密,访问 Google       │
  │     把结果加密传回来                 │
  │ ←─────────────────────────────────  │

为什么 GFW 看不出来?

  • 外层:标准 TLS 加密,和你访问银行网站、淘宝是同一种协议
  • 内层:真实请求被包裹在 TLS 里,GFW 无法解密
  • 目标 IP:境外服务器的 IP 没有被封锁(机场会定期更换)

GFW 看到的只是:「这台电脑在和某个境外服务器做 HTTPS 通信」,和正常上网行为无异。

流量伪装的完整对比

传统 VPN现代代理协议(Trojan/VMess)
GFW 能识别吗能,有明显特征难以识别,像普通 HTTPS
加密方式自有协议标准 TLS(和银行网站一样)
被封风险
速度慢(协议开销大)

2.2 系统代理的基本原理

理解了加密隧道,再看 Clash 整体的工作流程就清晰了。

Clash 启动后会做两件事:

  1. 接管系统代理:告诉 Windows「所有网络请求都先交给我」
  2. 在境外建立中继:通过加密隧道连接到 GFW 外的代理服务器
你的电脑(浏览器)

  │  ① 发起请求:我要访问 google.com

Clash(本地代理,127.0.0.1:7897)

  │  ② 判断规则:google.com → 走代理

  │  ③ 将请求包裹进加密隧道

GFW(只看到加密的 HTTPS 流量,放行)


境外代理服务器

  │  ④ 解密,代为访问 Google

Google 服务器  ✓  结果原路返回

2.3 Fake IP 详解

为什么需要 Fake IP?

正常代理还有一个问题:DNS 查询本身也会被 GFW 污染。如果 Clash 等 DNS 查询完成再代理,DNS 这一步就已经失败了。

Fake IP 是 Clash 的解决方案:跳过真实 DNS 查询,直接用假 IP 占位

Fake IP 工作流程

浏览器输入 google.com

  │  ① DNS 查询:google.com 是哪个 IP?

Clash(接管了 DNS)

  │  ② 立刻返回一个假 IP:198.18.0.9
  │     (不做真实 DNS 查询,速度极快)

浏览器

  │  ③ 向 198.18.0.9 发起连接

Clash(拦截到这个连接)

  │  ④ 认出 198.18.0.9 对应 google.com
  │     自己去查真实 IP(走加密隧道)

  │  ⑤ 通过境外服务器连接真实的 Google

Google 服务器  ✓

Fake IP 的核心思想

Fake IP 相当于一个「内部暗号」系统:

  • Clash 给每个域名分配一个假 IP 作为暗号
  • 浏览器拿着暗号来找 Clash
  • Clash 认出暗号,知道你真正要去哪里
  • 整个过程对浏览器完全透明

Fake IP 的优势

对比项传统方式Fake IP
DNS 查询先查询再连接,可能被污染跳过,直接返回假 IP
连接速度多一次 DNS 往返更快
DNS 污染风险

三、WSL2 为什么不能像浏览器一样直接用代理?

3.1 浏览器 vs WSL2 的本质区别

这是理解整个问题的关键

浏览器(Chrome)的行为

Chrome 是一个 Windows 原生应用,它懂得读取 Windows 系统代理设置:

Chrome 输入 google.com

  │  读取 Windows 系统代理设置
  │  发现:代理 = 127.0.0.1:7897

  │  直接把「google.com」这个域名交给 Clash
  │  ← 注意:Chrome 自己完全不做 DNS 解析

Clash  →  境外服务器  →  Google ✓

Chrome 从不自己做 DNS 解析,域名直接交给 Clash,Fake IP 对它没有任何影响。

WSL2 的行为

WSL2 是一个完整的 Linux 虚拟机,它:

  • 不知道 Windows 系统代理是什么
  • 有自己独立的网络栈
  • 像真正的 Linux 系统一样自己做 DNS 解析
WSL2 中执行 curl google.com

  │  ① Linux 网络栈:先做 DNS 解析
  │     "google.com 是哪个 IP?"

Clash 的 DNS(因为 WSL2 网关指向 Clash)

  │  ② 返回 Fake IP:198.18.0.9

curl

  │  ③ 自己向 198.18.0.9 发起 TCP 连接
  │     ← 注意:没有经过 Clash 代理!

  ✗  失败(198.18.0.9 只是个假 IP,没人响应)

根本原因

  • Chrome:把域名交给代理,代理来处理 DNS → 成功
  • WSL2:自己先做 DNS,拿到 Fake IP,再自己连接 → 失败

WSL2 的问题在于「多走了 DNS 这一步」,而这一步拿到的是假 IP。

3.2 架构对比图

┌─────────────────────────────────────────────────────┐
│                    Windows 主机                       │
│                                                       │
│  ┌──────────┐    系统代理     ┌───────────────────┐  │
│  │  Chrome  │ ─────────────→ │                   │  │
│  └──────────┘                │   Clash Verge     │  │
│                              │   127.0.0.1:7897  │  │
│  ┌──────────────────────┐    │                   │  │
│  │       WSL2           │    └────────┬──────────┘  │
│  │  (独立 Linux 虚拟机)  │             │              │
│  │                      │    加密隧道  │              │
│  │  curl google.com     │             ▼              │
│  │    ↓ 自己做 DNS      │    境外代理服务器           │
│  │    ↓ 拿到假 IP       │             │              │
│  │    ↓ 自己连接 → ✗   │             ▼              │
│  └──────────────────────┘    Google 服务器 ✓        │
└─────────────────────────────────────────────────────┘

四、为什么 socks5h 能解决问题?

4.1 三种代理协议的 DNS 处理方式

协议DNS 由谁解析遇到 Fake IP 的结果
http://本地(WSL2 自己)拿到假 IP → 失败 ✗
socks5://本地(WSL2 自己)拿到假 IP → 失败 ✗
socks5h://代理服务器(Clash)Clash 自己查真实 IP → 成功 ✓

h 的含义是 host,即「把主机名(域名)交给代理处理」。

4.2 socks5h 的完整流程

WSL2 中执行 curl --proxy socks5h://127.0.0.1:7897 google.com

  │  ① curl 不做 DNS 解析
  │     直接连接 127.0.0.1:7897(Clash)
  │     告诉 Clash:"我要访问 google.com"

Clash(收到域名,而不是假 IP)

  │  ② Clash 自己查 DNS(走加密隧道,不被污染)
  │     得到真实 IP:142.250.x.x

  │  ③ 通过境外服务器连接 Google

Google 服务器  ✓

socks5h 让 WSL2 的行为变得和 Chrome 一样

  • Chrome:把域名交给 Clash → Clash 处理 DNS
  • WSL2 + socks5h:把域名交给 Clash → Clash 处理 DNS

两者现在行为完全一致,Fake IP 问题彻底绕开。


五、Clash 在整个架构中的角色

Clash 不只是一个简单的「翻墙工具」,它同时扮演了以下几个角色:

┌─────────────────────────────────────────────────────────┐
│                      Clash Verge                         │
│                                                          │
│  ┌──────────────┐  ┌──────────────┐  ┌───────────────┐  │
│  │  DNS 服务器   │  │  代理服务器   │  │  规则引擎      │  │
│  │              │  │              │  │               │  │
│  │ 接管系统 DNS  │  │ 监听 7897 端口│  │ 判断哪些流量  │  │
│  │ 返回 Fake IP  │  │ 接收代理请求  │  │ 走代理/直连   │  │
│  │ 记录域名映射  │  │ 转发到境外    │  │ 国内直连      │  │
│  └──────────────┘  └──────────────┘  │ 国外走代理    │  │
│                                       └───────────────┘  │
│  ┌──────────────────────────────────────────────────┐    │
│  │                  TUN 虚拟网卡                      │    │
│  │  在系统层面拦截所有流量(包括不支持代理的程序)      │    │
│  └──────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────┘

五个核心角色

① DNS 服务器 接管本地 DNS 查询,实现 Fake IP 机制,防止 DNS 污染。

② 代理服务器 监听本地端口(7897),接收来自各程序的代理请求,通过加密隧道转发到境外。

③ 规则引擎 根据规则判断每个请求的处理方式:国内网站直连(不走代理,更快),国外网站走代理。

④ TUN 虚拟网卡(虚拟网卡模式)

TUN 是整个架构里最底层、最强力的机制,值得单独详细说明。

系统代理的局限性

系统代理(① ② ③)依赖程序「主动配合」——程序必须知道系统代理是什么,并且自愿把请求交给 Clash。Chrome 懂这套规则,但很多程序不懂:

不支持系统代理的程序(如某些命令行工具、游戏客户端)

  │  直接发起网络连接,完全不看系统代理设置

操作系统网络层


GFW  →  ✗ 被拦截

TUN 的解决思路:在更底层拦截

TUN(Network Tunnel)是操作系统提供的一种虚拟网卡机制。Clash 创建一个虚拟网卡,把自己插入到操作系统的网络栈里,在数据包离开电脑之前就拦截它:

任何程序(不管它懂不懂代理)

  │  发起网络请求

操作系统网络栈

  │  ← Clash TUN 虚拟网卡在这里拦截

┌─────────────────────────────────┐
│         Clash TUN 虚拟网卡       │
│                                 │
│  拦截所有流出的数据包             │
│  交给 Clash 规则引擎判断         │
│  国内 → 放行直连                 │
│  国外 → 加密转发到境外服务器      │
└─────────────────────────────────┘

用一个比喻理解:

TUN 的比喻

系统代理像小区门卫:只拦截主动配合报到的访客(懂代理的程序),翻墙进来的不管。

TUN 虚拟网卡像在小区唯一的出口修了一道闸机:不管你是谁、走哪条路,出小区就必须过闸机,没有例外。

TUN 和系统代理的对比

系统代理TUN 虚拟网卡
拦截方式程序主动配合操作系统层强制拦截
覆盖范围只有懂代理的程序所有程序,无一例外
配置复杂度简单需要管理员权限
典型场景浏览器上网游戏、命令行工具、不支持代理的 App

为什么 TUN 对 WSL2 依然无效?

理论上 TUN 能拦截所有流量,但 WSL2 是一个独立的 Hyper-V 虚拟机,它的网络流量从 Windows 视角来看像是「来自另一台机器的流量」,经由虚拟交换机转发,绕过了 TUN 虚拟网卡的拦截层。这就是即使开了虚拟网卡模式,WSL2 里不设代理仍然访问不了外网的根本原因。

⑤ 系统代理注册 把自己注册为 Windows 系统代理,让 Chrome 等支持系统代理的程序自动走代理。


六、完整架构总览

┌─────────────────────────────────────────────────────────────┐
│                         你的电脑                              │
│                                                               │
│  Windows 应用层                                               │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────────────┐   │
│  │  Chrome  │  │  其他APP  │  │          WSL2            │   │
│  │系统代理  │  │ 系统代理  │  │   独立 Linux 虚拟机       │   │
│  └────┬─────┘  └────┬─────┘  │   curl/git/pip...        │   │
│       │              │        │   设置 socks5h 环境变量   │   │
│       │              │        └───────────┬──────────────┘   │
│       │              │                    │ socks5h           │
│       └──────────────┴────────────────────┘                  │
│                              │                               │
│                              ▼                               │
│               ┌──────────────────────────┐                  │
│               │       Clash Verge        │                  │
│               │     127.0.0.1:7897       │                  │
│               │                          │                  │
│               │  DNS服务器 + 规则引擎     │                  │
│               │  + 代理转发 + TUN网卡    │                  │
│               └─────────────┬────────────┘                  │
│                             │                               │
└─────────────────────────────┼───────────────────────────────┘
                              │ 加密隧道(GFW 看不出来)
                    ┌─────────▼──────────┐
                    │    GFW(防火长城)   │
                    │  看到加密数据,放行  │
                    └─────────┬──────────┘

                    ┌─────────▼──────────┐
                    │   境外代理服务器     │
                    └─────────┬──────────┘

                    ┌─────────▼──────────┐
                    │   Google / GitHub  │
                    │   等境外服务器      │
                    └────────────────────┘

七、WSL2 最终配置方案

基于以上理解,WSL2 使用 socks5h 是最合适的方案:

bash
# ~/.bashrc

# Clash Verge 代理配置
export http_proxy="socks5h://127.0.0.1:7897"
export https_proxy="socks5h://127.0.0.1:7897"
export all_proxy="socks5h://127.0.0.1:7897"
bash
# git 单独配置(git 不读取环境变量,需要独立设置)
git config --global http.proxy socks5h://127.0.0.1:7897
git config --global https.proxy socks5h://127.0.0.1:7897

为什么用 socks5h 而不是 http?

  • http://127.0.0.1:7897:WSL2 自己做 DNS → 拿到 Fake IP → 失败
  • socks5h://127.0.0.1:7897:域名交给 Clash 处理 DNS → 拿到真实 IP → 成功

WSL2 镜像网络模式

C:\Users\你的用户名\.wslconfig 中配置:

ini
[wsl2]
networkingMode=mirrored

此模式下 WSL2 和 Windows 共享网络,可直接使用 127.0.0.1 访问 Clash,无需查询宿主机 IP。


八、常见问题速查

现象原因解决方案
curl 超时无响应代理端口错误确认 Clash 实际端口(如 7897)
Connection refusedClash 未启动或 Allow LAN 未开检查 Clash 设置
SSL 握手失败Fake IP 导致 DNS 异常改用 socks5h 协议
git 卡住不动git 未单独配置代理git config --global http.proxy socks5h://...
Chrome 正常但 WSL2 不行WSL2 不读系统代理手动设置 socks5h 环境变量

理解了这套架构,遇到任何代理问题都能自行排查。