CH1
流量正常出门
Step 1 / 30
💻
你的电脑
🏠
路由器 / 网关
📡
运营商 ISP
🌐
互联网
📋 你电脑里的路由表
Destination
Gateway
Iface
default
192.168.1.1
en0
192.168.1.0/24
link
en0
127.0.0.0/8
-
lo0
← 兜底规则
192.168.1.42
(内网 IP)
src=192.168.1.42
203.0.113.27
(公网 IP)
src=203.0.113.27
SNAT · 改源 IP
📒 路由器的 conntrack 翻译表
内网
↔ 公网(路由器替你出去)
192.168.1.42:50012
↔
203.0.113.27:54321
192.168.1.99:33100
↔
203.0.113.27:62880
…回包按这张表翻回去,包就送到正确的内网机器
⚠ WiFi 和手机热点本质一样
连家里 WiFi:
你 → 🏠 路由器 → ISP → 互联网
路由器知道你查的所有 DNS、连过的所有 IP
用别人的热点:「运营商」 ≈ 换成了「这台手机」
先看一个最朴素的情况:没有任何代理时,包是怎么离开你的电脑的
OS 拿到包后查「路由表」,决定从哪张网卡出去
99% 的流量走 default 兜底规则 — 后面 VPN 工具劫持的就是它
你的内网 IP 出不了公网,路由器替你出门、用它自己的公网 IP(SNAT)
路由器记着翻译表 conntrack,回包按表翻回内网
手机热点 = 手机当路由器,能看到你所有流量元数据
🌐
浏览器
SOCKS5 协议
代理服务器
127.0.0.1:7890
应用主动告诉它"我要访问 X"
→ google.com
🎯
google.com
⚙ 系统偏好设置 · 网络 · 代理
HTTP / HTTPS / SOCKS Proxy:
127.0.0.1 : 7890
macOS / Windows 写好这些 key,应用主动调 API 读 —
读不读、读了听不听,应用说了算
仅是"建议"
💀 谁会无视系统代理?
🧭
Safari / Chrome
✓ 读,走代理
$_
curl 命令行
✗ 不读,直连
🎮
游戏 / 原生 UDP
✗ 不读,直连
📱
Electron 后台
✗ 看作者写的
最朴素的代理:应用主动告诉代理服务器"我要访问 X",代理替你跑一趟
系统代理只是"全局提示"——OS 没法强制应用走代理
所以你以为开了"全局代理",实际还是有大块流量从物理网卡裸奔
❓ 怎么强制让所有流量都走代理?
应用层代理是"请求应用配合",但很多应用不配合。
要让所有 App 都没法绕过,得在
更底层
下手——
⬇ 比应用层低,比驱动层高,刚好是「网卡」层 ⬇
操作系统 (macOS / Linux)
Browser
curl / Game
System
内核协议栈
TCP / UDP / IP
查路由表,决定走哪张网卡
default → utun5
(下一步改这里)
TUN 设备 utun5
("假网卡" · 内核虚构)
内核侧:当作普通网卡
用户侧:一个 fd
Surge / Clash
用户态进程
read(fd) → IP 包
fd read
⚡ 路由表前后对比
关 Surge:
default → 192.168.1.1 → en0
开 Surge:
default → utun5 ← 劫持点
⚙ 解析五元组
src/sport · dst/dport · proto
在用户态做决定
🎯 不论 App 是否"读代理设置",包都要经过 OS 路由表
路由表把 default 指向了 utun5,所以 — 没!有!人!能!跳!过!Surge
游戏 UDP / curl / 闷头跑的后台 App……全都进 TUN
应用层代理太"软",得在比应用更底层的地方接管
引入 TUN 虚拟网卡:内核眼里是网卡,对端却是用户态进程
改一行 default 路由 → 所有流量被引向 TUN
Surge 进程在用户态读包、解析五元组,做下一步决策
这就是为什么开了 Surge "所有流量都被接管" — 路由表本身改了
TUN utun5
所有 IP 包来这里
fd read
Surge 规则引擎
每个连接独立决策
从上往下匹配,命中即停
5 种规则类型,下一步详细看
📋 规则类型 (按"看哪个字段"分类)
DOMAIN-SUFFIX
看域名后缀
google.com
→
PROXY
IP-CIDR
看目的 IP 段
192.168.0.0/16
→
DIRECT
GEOIP
看 IP 属于哪国
GEOIP, CN
→
DIRECT
PROCESS-NAME
看哪个进程发的
WeChat
→
DIRECT
DST-PORT
看目的端口
DST-PORT, 53
→
PROXY
远端代理服务器
机场 / 自建 VPS
SS · Trojan · VLESS · Hysteria2
PROXY
en0 物理网卡 (直连)
不再进 TUN,避免回环
源接口标记不同 → 跳过 TUN
DIRECT
🎚 拖动下方滑杆 → 观察 Surge 对每种目的地的决策
实战演示:YouTube 走代理、B 站直连、内网 IP 直连
接管 ≠ 必须代理。Surge 在用户态对每个连接做规则匹配决定走向
规则类型:看域名 / 看 IP / 看国别 / 看进程 / 看端口
命中 PROXY → 把 IP 包封装成 SS/Trojan/VLESS 协议发到远端代理服务器
命中 DIRECT → Surge 用物理网卡重新发,但带特殊标记跳过 TUN 避免回环
🌐
浏览器
DNS 查询走哪条?
google.com → ?
A. 本地 DNS
📡 运营商 DNS (114.114.114.114)
快、稳,但 DNS 服务器看见你查的所有域名
→ 流量代理了,元数据没代理
B. 走代理的 DNS
远端 DNS over 代理
不泄漏,但每次 DNS 都要走代理 → 慢
且本地解析直连域名(B 站等)也走远端 → 浪费
⚠
DNS 泄漏
运营商记下你想访问 google
📛 即使流量本身走了代理被加密,DNS 查询本身已经泄了密
"我们看不见你在 google 看了什么,但我们知道你访问过 google"
🌐
浏览器
① DNS: google.com?
Surge 拦截 DNS 请求
不真去解析,直接返回
假 IP: 198.18.0.1
维护映射表
198.18.0.1 ↔ google.com
198.18.0.2 ↔ youtube.com
198.18.0.3 ↔ ……
② → 198.18.0.1
③ TCP → 198.18.0.1:443
TUN utun5
收到目的 IP=198.18.0.1 的包
Surge 查映射表
"198.18.0.1 其实是 google.com"
④ 用真域名做规则匹配
命中 DOMAIN-SUFFIX,google.com,PROXY
⑤ 通过代理服务器
在远端代理那边做真实 DNS 解析
✓ 本地 DNS 全程没看到 google.com
运营商日志里只有 "查了一下 198.18.0.1"
域名要先变 IP 才能发包 — DNS 查询本身走哪条路?
DNS 泄漏:用本地 DNS 等于告诉运营商"我想访问 google"
fake-ip:返回假 IP,本地 DNS 全程没看到真域名
🐛 坑 #1:IPv6 双栈泄漏
💻
你电脑 (双栈)
IPv4 → utun5 ✓
TUN utun5
v4 被接管
IPv6 → en0 ✗ 泄
en0 (物理) → ISP
v6 偷偷裸奔
后果
• 访问 google.com 优先用 v6
• 整条 v6 流量从运营商裸奔
• 你以为开了全局代理
• 实际查 ip.sb 显示运营商 IPv6
→ 修:代理工具开 ipv6 true
检测命令:
route -n get -inet6 default | grep interface
interface 显示 utun5 = v6 也接管 ✓;显示 en0 = v6 泄漏 ✗
🔬 坑 #2:进程级规则 (PROCESS-NAME) 是怎么实现的?
📱
WeChat 进程
PID 4321
发出 IP 包
Surge 收到包
只看到五元组
src=192.168.1.42:50012
不知道是哪个进程发的
反查
查 OS 的 socket 表
"哪个 PID 拥有这个五元组对应的 socket?"
macOS: PF + audit_token
Linux: cgroup / socket cookie
这就是为什么 Surge 启动时一定要授权 root
查 socket-to-PID 映射、绑 PF 规则、改路由表 — 全都需要 root 权限
如果你不给授权,PROCESS-NAME 规则就会失效(只能匹配 IP / 域名)
→ 实战:让 微信/网易云 命中 PROCESS-NAME 走 DIRECT,避免被代理误伤
💥 坑 #3:为什么重启前要先关 Surge?
① Surge 启动时
创建 TUN utun5 → 改路由表 default → utun5 → 备份原路由
② 正常退出 (菜单栏 → Quit)
恢复 default 路由 → 销毁 utun5 → 还原 DNS → 干净 ✓
③ 强制关机 / 崩溃 / kill -9 (没机会清理)
路由表还指着 utun5 → 但 utun5 已经不存在 → 包发出去都被丢
④ 下次开机表现
😵 全网断 · WiFi 显示已连接 · 浏览器一直转圈 · 看似没问题但啥都连不上
修法 1:再启动一次 Surge,它会"接管"残留路由并正常清理
修法 2:终端跑
sudo route delete default; sudo route add default 192.168.1.1
📱 坑 #4:手机为什么必须开"VPN 配置文件"?
桌面 (macOS / Linux / Windows)
Surge 启动 = root 权限
↓
直接调系统 API 建 TUN 设备
↓
直接改路由表
↓
完事
"自由发挥"
代价:要给 root 授权
iOS (沙盒严格)
App 不能直接建 TUN
↓
必须走
NetworkExtension
framework
↓
注册 Personal VPN profile
↓
系统在 App 进程之外建 TUN
"穿过系统 API"
状态栏 VPN 字样 = NetworkExtension 在跑
现代电脑双栈:代理只接管了 v4,v6 偷偷直连
PROCESS-NAME 规则要做"socket → PID → 进程名"的反查 — 需要 root
路由表是 Surge 动态建的,正常退出会清理;强制关机会留下"残尸"
iOS 沙盒不让 App 直接建 TUN,要借 NetworkExtension framework
🛠 主流工具横向对照 · 都是 TUN + 规则引擎 + 协议化代理
工具
平台
规则语法
协议支持亮点
说明
Surge
macOS · iOS
[Rule] / .conf
全协议 + MitM
商业版 · 最完备
Clash (Meta/Verge)
全平台 (开源)
rules: / YAML
SS · Vless · WG
开源主流
sing-box
全平台 (开源)
route.rules / JSON
Hysteria2 · TUIC
后起新军
Quantumult X
iOS
[filter_local]
脚本能力强
iOS 商业老牌
V2Ray (v2fly)
全平台
routing / JSON
VMess · VLESS
老牌全功能
Shadowrocket
iOS
类 Surge 简化
SS 系
iOS 入门
📐 共同骨架
① TUN 设备接管路由 → ② 用户态规则引擎做分流决策 → ③ 协议化代理客户端发到远端
差别仅在 UI、规则语法的"语糖"、支持的代理协议组合 —
原理 100% 一致
所以学会一个,其他都能很快上手;订阅源的 *.yaml / *.conf 也能跨工具转换
🔍 真 VPN (WireGuard/OpenVPN) vs 代理工具 (Surge/Clash)
真 VPN (站点到站点隧道)
所有流量整体走一条加密隧道
💻
WireGuard 加密隧道
整管不分流
🏢
特点
• 单一隧道,无分流概念
• 整个 OS 把对端当作"网关"
• 公司内网接入、固定跨境节点
• 协议层处理一切 (路由 + 加密)
典型:WireGuard、OpenVPN、IPsec
iCloud Private Relay (隧道层) 也属此类
代理工具 (本地拦截 + 协议代理)
每个连接独立决定走代理还是直连
💻
Surge
规则引擎
PROXY
DIRECT
🌐
特点
• 本地有规则引擎,按域名/IP/进程分流
• 支持多个代理出口同时存在
• 协议化代理:SS/Trojan/Vless/Hysteria
• 翻墙日常用的就是这类
典型:Surge / Clash / sing-box / V2Ray
🗺 完整总图:从敲 URL 到包真正出网
① 浏览器
解析 URL, 准备 TCP
② DNS (fake-ip)
返回 198.18.0.1
③ 内核路由表
default → utun5
④ TUN utun5
包送进 fd
⑤ Surge
用户态读包
⑥ 规则匹配
命中 PROXY/DIRECT
⑦A PROXY 分支
SS/Trojan/VLESS 封装
→ 远端代理服务器
⑧A 远端解密 → 互联网
代理 VPS 做真正 DNS
访问 google.com
⑦B DIRECT 分支
从物理网卡 en0 重发
⑧B 路由器 NAT → ISP
conntrack 翻译
每个数字都对应了前面某个 step ✓
①浏览器=step7 · ②fake-ip=step22 · ③路由表=step3,12 · ④TUN=step11 · ⑤Surge=step13 · ⑥规则=step15,16 · ⑦⑧=step17,18
🩺 速查表:常见症状 → 原因 → 看哪一步
症状
最可能的原因
看 Step
开了代理,但能查到真实 IP
IPv6 双栈泄漏
step 23
访问 google.com 被运营商劫持
DNS 没走 fake-ip / 远端
step 21-22
开 Surge 后游戏延迟暴涨
游戏 UDP 被强制走代理
step 16
早上开机全网断、WiFi 显示已连接
上次没正常关 Surge,路由残留
step 25
微信、网易云突然连不上
App 用了自有协议被规则误判
step 16,24
只能在浏览器走代理
用的还是应用层代理,没开 TUN 模式
step 7-10
手机 Surge 没 VPN 字样
NetworkExtension profile 没安装/未启
step 26
公司内网网站突然打不开
内网 IP 没命中 DIRECT,被走代理
step 15-16
想看 B 站 4K 但走代理太慢
国内域名应该 DIRECT,加 GEOIP,CN
step 16,19
订阅一切正常但部分网站不通
特定节点丢包 / 协议被针对,换协议
step 27
🎓 通关了 — 你现在能给身边的人讲清"Surge 是怎么把流量分到不同出口的"
主流工具看似一堆,骨架完全一致,学会一个其他都能上手
辨别"真 VPN"和"代理工具"的关键问题:是否会分流?
所有概念串起来:从敲 URL 到包真正出网
最后留张速查表:症状 → 原因 → 复习对应 step
← 上一步
下一步 →
↻ 重播本章
← / → 键也可切换