坑边闲话:自笔者来到英国学习之后,已经有接近两年的时间没关心过科学上网了。作为一个即将回国的科研工作者,怎么能放弃学习呢?没了 Claude/Codex, 写代码可怎么办!因此有必要花一天时间重拾过往的技术。本文详细介绍 Singbox 的工作原理和配置文件,以及我本人如何使用这些工具。

免责声明

本文并不想说「技术无罪」之类的话,在高手眼里,一草一木皆为杀人兵器。科研需要科学上网在科研界几乎是共识,因此本文的初衷就是为了访问外部科研资料,同时管理自己的内网设备。

如果要在受管理的网络环境里部署代理服务器,请提前阅读相关公告,防止为运维人员添麻烦!

1. sing-box: 新一代通用代理平台·

1.1 sing-box 是什么·

sing-box 是一个用 Go 编写的通用代理平台(The Universal Proxy Platform),由 SagerNet 团队(核心开发者 nekohasekai)于 2022 年开源。它不是某个特定协议的实现,而是一个可以同时承载多种代理协议的统一框架。

在 sing-box 出现之前,代理工具领域经历了这样的演化:

1
2
3
4
5
6
7
8
9
v2ray-core (2015)
|
+---> xray-core (2020, fork, 侧重隐蔽性)
|
+---> clash (2018, 侧重易用性和路由规则)
|
+---> clash-premium (闭源增强版, 引入 TUN)

sing-box (2022, 全新设计, 吸收上述所有优点)

sing-box 的设计目标是:在一个二进制文件里,同时做好协议支持、流量路由、透明代理这三件事。

与前辈相比:

  • v2ray-core 内存占用约 240MB,sing-box 仅约 70MB
  • clash 缺少 VLESS/REALITY 等现代协议支持
  • xray-core 侧重隐蔽但不擅长做透明代理网关

sing-box 支持的主要协议包括:Shadowsocks、VMess、VLESS、Trojan、Hysteria2、WireGuard、ShadowTLS 等。

1.2 sing-box 的核心架构·

sing-box 的配置由三大模块构成:

1
2
3
+-----------+      +---------+      +------------+
| Inbound | ---> | Route | ---> | Outbound |
+-----------+ +---------+ +------------+
  • Inbound:流量入口。可以是 TUN 虚拟网卡(捕获系统流量)、VLESS 监听端口(接收代理连接)、SOCKS/HTTP 代理端口等。
  • Route:路由引擎。根据目标 IP、域名、协议等条件,决定流量走哪个 Outbound。
  • Outbound:流量出口。可以是 direct(直连)、某个代理服务器(如 VLESS 出站)、或者 block(丢弃)。

一条流量的生命周期:

1
2
3
4
5
6
7
8
9
10
11
12
[App traffic] --> [Inbound: tun/vless/socks]
|
v
[Route engine]
match rules:
ip_cidr? domain? protocol?
|
v
[Outbound: direct/vless/block]
|
v
[Destination]

这个架构的精髓在于:一个 sing-box 实例可以同时监听多个 Inbound,通过路由规则将不同来源、不同目标的流量分发到不同的 Outbound。 这使得一台机器既可以是代理服务器,也可以是代理客户端,甚至可以同时充当两者。

2. 为什么选择 VLESS + REALITY·

2.1 伪装的必要性·

在某些网络环境中,WireGuard 等 VPN 协议的流量特征非常明显。WireGuard 使用固定的 UDP 端口,其握手包有显著的特征码,很容易被 DPI(深度包检测)识别并阻断。

VLESS + REALITY 的组合解决了这个问题:

  • VLESS 是一个极简的代理协议,去掉了 VMess 中冗余的加密层(因为外层已有 TLS),性能更好。
  • REALITY 是 XTLS 团队开发的 TLS 伪装技术。它不需要你购买域名或申请证书,而是直接"借用"一个真实网站的 TLS 指纹(如 www.apple.com)。DPI 看到的是一个正常的、指向 Apple 服务器的 TLS 连接。
1
2
3
4
5
6
7
8
                        DPI sees:
"Normal TLS to www.apple.com"
|
[Client] ---TLS(REALITY)---> [sing-box server] ---> [Destination]
|
+-- Actually carries VLESS proxy traffic
+-- Server Name: www.apple.com
+-- uTLS fingerprint: Chrome browser

REALITY 的关键参数:

  • private_key / public_key:X25519 密钥对,用于客户端和服务端之间的认证
  • short_id:额外的认证令牌
  • server_name:伪装的目标网站域名
  • handshake.server:当非认证客户端连接时,将其流量真正转发到该网站,保持伪装的完整性

2.2 为什么不用 VLESS + WireGuard 隧道嵌套·

一个自然的想法是:既然 VLESS 能穿透审查,WireGuard 能承载所有协议(包括 UDP 和 ICMP),为什么不把 WireGuard 跑在 VLESS 隧道里面?

答案是:TCP 熔毁 (TCP Meltdown).

1
2
3
4
5
6
7
8
9
10
11
12
Without nesting (pure VLESS):
[TCP data] --> [VLESS/TLS] --> Internet
One layer of TCP congestion control. Throughput: ~200 Mbps

With nesting (WireGuard over VLESS):
[TCP data] --> [WireGuard UDP] --> [VLESS/TLS(TCP)] --> Internet
| | |
TCP #1 Encap as UDP TCP #2
but carried over
TCP anyway!

Two layers of TCP congestion control. Throughput: ~10 Mbps

WireGuard 本身是 UDP 协议,有自己的重传逻辑。当它被包裹在 VLESS(TCP)里时:

  1. 内层 WireGuard 检测到丢包,触发重传
  2. 外层 TCP 也检测到丢包,同时触发重传
  3. 两层重传互相放大,导致带宽剧烈下降

实测数据(iperf3,lab → fra):

  • 纯 VLESS 直连:~200 Mbps
  • WireGuard over VLESS:~10 Mbps(性能下降 95%)

结论:在 TCP 隧道上跑 WireGuard 是不可接受的。 如果你追求性能,应该用纯 VLESS 承载 TCP 流量,而不是在里面再套一层 VPN。

代价:纯 VLESS 只能代理 TCP 流量。ICMP(ping)和 UDP 无法通过 VLESS 隧道传输。这是一个必须接受的折中。

3. 双向隧道:构建跨国局域网互通·

3.1 网络拓扑·

我们的目标是连通三个节点:

1
2
3
4
5
6
7
+------------------+        WireGuard         +------------------+        VLESS x2        +------------------+
| bham-openwrt | <-----(UDP, fast)------> | fra-debian | <-----(TCP, stealth)-->| lab-openwrt |
| Birmingham, UK | | Frankfurt, DE | | Beijing, CN |
| 10.4.0.0/16 | | Public IP: | | 10.2.0.0/16 |
| WG: 10.100.4.1 | | 72.111.31.161 | | Public IP: |
+------------------+ | WG: 10.100.5.1 | | 124.16.111.172 |
+------------------+ +------------------+
  • bham ↔ fra:WireGuard 直连。英国到德国之间网络环境宽松,WireGuard 的 UDP 协议不会被干扰。
  • fra ↔ lab:VLESS + REALITY。中国到德国之间需要伪装,所以使用 VLESS 隧道。

3.2 为什么需要两条 VLESS 隧道·

VLESS 是一个请求-响应式的代理协议,不是全双工隧道。每条 VLESS 连接的方向是固定的:客户端发起连接,通过服务端转发到目标地址。服务端不能主动通过已建立的连接向客户端推送流量。

这意味着:

1
2
3
4
One VLESS session (lab --> fra):
lab connects to fra:443
lab can reach 10.4.0.0/16 (bham) via fra [OK]
bham CANNOT reach 10.2.0.0/16 (lab) via fra [FAIL - no reverse path]

要实现双向互通,我们需要两条独立的 VLESS 连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Session 1: lab --> fra:443     (Forward path)
Carries: lab -> bham traffic (10.4.0.0/16)

Session 2: fra --> lab:8443 (Reverse path)
Carries: bham -> lab traffic (10.2.0.0/16)

Together they form bidirectional connectivity:

bham (10.4.0.0/16) lab (10.2.0.0/16)
| |
| WireGuard | VLESS (reverse, fra->lab)
v v
fra ----VLESS (forward, lab->fra)---> lab
fra <---VLESS (reverse, fra->lab)---- lab
^ ^
| WireGuard |
| |
bham lab LAN

为什么 sing-box 不能基于现有连接做反向代理?

VLESS 底层是 TLS over TCP. TLS 连接有明确的客户端/服务端角色区分,服务端不能主动在已有的 TLS 会话上向客户端发送未经请求的数据流。这不是 sing-box 的限制,而是 TLS 协议本身的设计。要实现反向流量,必须让对方也建立一条新的出站连接。

3.3 完整的数据流·

3.3.1 正向:lab 访问 bham·

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
lab (10.2.2.10)                  fra                     bham (10.4.1.10)
| | |
| 1. App sends TCP | |
| to 10.4.1.10:22 | |
| | |
| 2. tun0 captures | |
| (route_address: | |
| 10.4.0.0/16) | |
| | |
| 3. Route engine: | |
| ip_cidr match | |
| -> vless-reality-out | |
| | |
| 4. VLESS/REALITY -------> fra:443 |
| (looks like HTTPS | 5. Decapsulate, |
| to apple.com) | route to |
| | 10.4.1.10 |
| | |
| | 6. Via wg0 (WireGuard) |
| | -> 10.4.1.10 --------->|
| | |
| | 7. Reply comes back |
| |<--------- wg0 -----------|
| | |
| 8. Reply via VLESS <------ | |
| same TCP session | |
| | |
| 9. tun0 delivers | |
| to App | |

3.3.2 反向:bham 访问 lab·

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
bham (10.4.1.10)                 fra                     lab (10.2.2.10)
| | |
| 1. App sends TCP | |
| to 10.2.2.10:80 | |
| | |
| 2. Via wg0 (WireGuard) | |
| -> 10.100.5.1 --------->| |
| | |
| | 3. tun0 captures |
| | (route_address: |
| | 10.2.0.0/16) |
| | |
| | 4. Route engine: |
| | ip_cidr match |
| | -> vless-to-lab |
| | |
| | 5. VLESS/REALITY ------->|
| | -> lab:8443 |
| | (looks like HTTPS |
| | to apple.com) |
| | |
| | 6. Decapsulate,
| | deliver to
| | 10.2.2.10:80
| | |
| | 7. Reply via VLESS |
| |<------------------------- |
| | |
| 8. Reply via wg0 <--------| |
| | |

3.4 配置文件详解·

3.4.1 lab.json(北京节点)·

lab 既是 VLESS 客户端(出站到 fra),也是 VLESS 服务端(接收 fra 的反向连接):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
{
"log": { "level": "info" },
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"interface_name": "tun0",
"mtu": 1400,
"address": ["172.19.0.1/30", "fdfe:dcba:9876::1/126"],
"auto_route": true,
"auto_redirect": true,
"route_address": ["10.4.0.0/16"]
},
{
"type": "vless",
"tag": "vless-reality-in",
"listen": "0.0.0.0",
"listen_port": 8443,
"users": [
{ "uuid": "92971569-58ff-4baa-9d87-5201dac190de" }
],
"tls": {
"enabled": true,
"server_name": "www.apple.com",
"reality": {
"enabled": true,
"handshake": { "server": "www.apple.com", "server_port": 443 },
"private_key": "<REALITY_PRIVATE_KEY>",
"short_id": ["a1b2c3d4"]
}
}
}
],
"outbounds": [
{
"type": "vless",
"tag": "vless-reality-out",
"server": "72.111.31.161",
"server_port": 443,
"uuid": "de6d864a-7e15-407c-b005-2385522c6af9",
"network": "tcp",
"tls": {
"enabled": true,
"server_name": "www.apple.com",
"utls": { "enabled": true, "fingerprint": "chrome" },
"reality": {
"enabled": true,
"public_key": "<REALITY_PUBLIC_KEY>",
"short_id": "a1b2c3d4"
}
}
},
{ "type": "direct", "tag": "direct" }
],
"route": {
"rules": [
{ "ip_cidr": ["10.4.0.0/16"], "outbound": "vless-reality-out" }
],
"final": "direct"
}
}

关键点:

  • tun inboundroute_address: ["10.4.0.0/16"] 表示只捕获目标为 bham 网段的流量,其他流量不经过 sing-box。
  • vless inbound:监听 8443 端口,接收 fra 发来的反向隧道连接。这里不能用 443/80/445(被防火墙策略禁止)。
  • vless outbound:连接 fra:443,发送正向流量。
  • 路由规则:只有 10.4.0.0/16 走 VLESS,其余 direct 直连。

3.4.2 fra.json(法兰克福节点)·

fra 是双向流量的中转枢纽:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
{
"log": { "level": "info" },
"inbounds": [
{
"type": "vless",
"tag": "vless-reality-in",
"listen": "0.0.0.0",
"listen_port": 443,
"users": [
{ "uuid": "de6d864a-7e15-407c-b005-2385522c6af9" }
],
"tls": {
"enabled": true,
"server_name": "www.apple.com",
"reality": {
"enabled": true,
"handshake": { "server": "www.apple.com", "server_port": 443 },
"private_key": "<REALITY_PRIVATE_KEY>",
"short_id": ["a1b2c3d4"]
}
}
},
{
"type": "tun",
"tag": "tun-in",
"interface_name": "tun0",
"mtu": 1400,
"address": ["172.19.0.1/30"],
"auto_route": true,
"route_address": ["10.1.0.0/16", "10.2.0.0/16"]
}
],
"outbounds": [
{
"type": "vless",
"tag": "vless-to-lab",
"server": "124.16.111.172",
"server_port": 8443,
"uuid": "92971569-58ff-4baa-9d87-5201dac190de",
"network": "tcp",
"tls": {
"enabled": true,
"server_name": "www.apple.com",
"utls": { "enabled": true, "fingerprint": "chrome" },
"reality": {
"enabled": true,
"public_key": "<REALITY_PUBLIC_KEY>",
"short_id": "a1b2c3d4"
}
}
},
{ "type": "direct", "tag": "direct" }
],
"route": {
"rules": [
{ "ip_cidr": ["10.1.0.0/16", "10.2.0.0/16"], "outbound": "vless-to-lab" }
],
"final": "direct"
}
}

关键点:

  • vless inbound:接收 lab 的正向连接(端口 443,伪装为 HTTPS)。
  • tun inboundroute_address: ["10.1.0.0/16", "10.2.0.0/16"] 捕获从 WireGuard(wg0)过来的、目标为 lab 网段的流量。
  • vless outbound:连接 lab:8443,发送反向流量。
  • fra 本身没有 auto_redirect,因为它是 Debian 服务器,不需要重定向本机流量。

3.4.3 bham-openwrt WireGuard 配置·

bham 不需要运行 sing-box。它通过 WireGuard 连接 fra,fra 的路由表负责将 10.2.0.0/16 的流量交给 sing-box 处理:

1
2
3
4
5
6
7
8
9
10
11
12
[Interface]
Address = 10.100.4.1/32
ListenPort = 7980
PrivateKey = <WG_PRIVATE_KEY>
MTU = 1280

# fra-debian
[Peer]
PublicKey = CK3CHKWhSNrNVAkwoCdBrMTalT0A9jQXkHUFt0rHJDA=
PresharedKey = <WG_PSK>
AllowedIPs = 10.100.1.1/32, 10.100.2.1/32, 10.100.3.1/32, 10.100.5.1/32, 10.1.0.0/16, 10.2.0.0/16, 10.3.0.0/16
Endpoint = 72.111.31.161:7980

AllowedIPs 中包含了 10.2.0.0/16,这意味着 bham 发往 lab 网段的流量会通过 WireGuard 发给 fra,然后由 fra 的 sing-box 接管。

4. 理解 TUN 虚拟网卡·

4.1 什么是 TUN·

TUN(Network TUNnel)是操作系统内核提供的一种虚拟网络设备。它工作在 OSI 第三层(网络层),能够:

  • 捕获系统路由表导向它的 IP 数据包
  • 将这些数据包交给用户空间程序(如 sing-box)处理
  • 将用户空间程序生成的数据包注入网络栈
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
+---------------------+
| Application |
| (curl, ssh...) |
+---------------------+
| TCP/UDP
v
+---------------------+
| Kernel TCP/IP |
| Stack |
+---------------------+
| IP packets
| (routing decision)
v
/-----|------\
/ | \
v v v
eth0 wg0 tun0
(LAN) (WG) (sing-box)

sing-box 通过 TUN 设备实现透明代理:应用程序不需要知道代理的存在,它们正常发送 TCP/UDP 数据包,内核根据路由表将特定目标的流量导向 tun0,sing-box 在用户空间接收这些包并通过代理协议转发。

4.2 auto_routeroute_address·

sing-box 的 TUN 配置中有两个关键参数:

  • auto_route: true:sing-box 自动向系统路由表添加规则,将流量导向 tun0。
  • route_address:限定哪些目标地址段的流量被 tun0 捕获。

如果不设置 route_addressauto_route 会捕获所有流量(0.0.0.0/0),这在网关设备上是危险的——它会劫持 SSH 连接和管理流量,导致设备失联。

1
2
3
4
{
"type": "tun",
"route_address": ["10.4.0.0/16"]
}

上面的配置表示:只有目标为 10.4.0.0/16 的流量经过 tun0,其他流量走正常路由。这确保了设备的可管理性。

踩坑经验

在 OpenWrt 路由器上重启 sing-box 时,auto_route + auto_redirect 会重置路由表,导致 SSH 连接中断。务必使用 route_address 限制捕获范围,并确保管理流量不会被 tun0 劫持。

4.3 为什么 fra 也需要 TUN·

一个常见的疑问:fra 已经有了 VLESS inbound 来接收 lab 的正向流量,为什么还需要 tun0?

答案在于反向流量的来源。当 bham 发往 10.2.0.0/16 的流量通过 WireGuard 到达 fra 时,这些流量从 wg0 接口进入 fra 的内核网络栈。sing-box 的 VLESS inbound 只监听特定端口(443),它不会主动去「捞」 wg0 上的流量。

我们需要 tun0 来捕获这些来自 WireGuard 的流量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bham -> WireGuard -> fra's wg0
|
| Kernel routing:
| dst 10.2.0.0/16
| -> tun0 (auto_route)
|
v
sing-box tun inbound
|
| Route engine:
| ip_cidr 10.2.0.0/16
| -> vless-to-lab
|
v
VLESS outbound -> lab:8443

没有 tun0,从 wg0 来的流量会直接被内核尝试路由到 10.2.0.0/16,但 fra 没有到达这个网段的直接路径,流量会被丢弃。

4.4 OpenWrt DSA 架构简介·

在 OpenWrt 设备上部署 sing-box,需要理解其现代网络架构——DSA(Distributed Switch Architecture)

传统的 OpenWrt 使用 swconfig 管理交换机,将物理端口映射为 VLAN,再绑定到 eth0.1eth0.2 等子接口。DSA(自 OpenWrt 21.02 起成为默认)彻底改变了这一模型:

1
2
3
4
5
6
7
8
9
10
11
12
Traditional (swconfig):                DSA:

+-------+ +-------+
| br-lan| | br-lan|
+---+---+ +---+---+
| | | |
eth0.1 lan1 lan2 lan3
| | | |
+---+---+ +---+---+---+
| switch| (opaque, swconfig) | switch0 | (each port is
| driver| | | a netdev)
+-------+ +------------+

DSA 的核心变化:

  • 每个物理交换机端口都是独立的网络设备(lan1lan2wan
  • VLAN 通过标准的 bridge vlan 命令管理,而非专有的 swconfig
  • 网桥(br-lan)直接桥接物理端口设备

这对 sing-box 部署的影响:

  • TUN 接口(tun0)与 br-lanwg0 并列存在于网络栈中
  • auto_route 添加的路由规则会影响所有接口的流量转发
  • 需要确保 ip_forward=1sysctl net.ipv4.ip_forward),否则跨接口转发不生效

更详细的 DSA 文档可参考 OpenWrt DSA 指南

5. 性能测试与验证·

5.1 用 iperf3 测试吞吐量·

iperf3 是网络性能测试的标准工具。客户端向服务端上传数据,结果反映链路的实际吞吐能力。

测试方法(以 lab → fra 为例):

1
2
3
4
5
# fra (server side):
iperf3 -s -p 5201

# lab (client side):
iperf3 -c 10.100.5.1 -p 5201 -t 10

我们在不同隧道方案下的实测结果:

方案 吞吐量 说明
纯 VLESS (lab → fra) ~200 Mbps 单层 TCP,性能最优
WireGuard over VLESS ~10 Mbps TCP 熔毁,性能灾难
纯 WireGuard (bham ↔ fra) ~300 Mbps UDP 直连,无额外开销

5.2 为什么不能用 ping 测试·

VLESS 是 TCP 代理协议,无法转发 ICMP 数据包(ping 使用的协议)。当 sing-box 的 TUN 捕获到 ICMP 流量时,行为取决于实现:

  • sing-box 可能在本地生成伪造的 ICMP 回复(显示 <1ms 的延迟)
  • 或者直接丢弃
1
2
3
# This does NOT work through VLESS:
$ ping 10.4.1.10
PING 10.4.1.10: 64 bytes, time<1ms # FAKE! Generated locally by tun0

正确的验证方法是使用 TCP:

1
2
3
4
5
6
7
# Test SSH connectivity:
$ nc -zv 10.4.1.10 22
Connection to 10.4.1.10 22 port [tcp/ssh] succeeded!

# Test HTTP with timing:
$ curl -o /dev/null -w "TCP connect: %{time_connect}s, Total: %{time_total}s\n" http://10.4.1.10/
TCP connect: 0.532s, Total: 0.534s

5.3 防火墙注意事项·

在 OpenWrt 上运行 sing-box 的 VLESS inbound 时,需要在防火墙中放行对应端口。以 lab 的 8443 端口为例:

1
2
3
4
5
6
7
8
9
# OpenWrt UCI 防火墙规则:
uci add firewall rule
uci set firewall.@rule[-1].name='Allow-Singbox-8443'
uci set firewall.@rule[-1].src='wan'
uci set firewall.@rule[-1].dest_port='8443'
uci set firewall.@rule[-1].proto='tcp'
uci set firewall.@rule[-1].target='ACCEPT'
uci commit firewall
/etc/init.d/firewall restart

如果不开放端口,fra 连接 lab:8443 时会得到 connection refused,反向隧道无法建立。

6. 扩展用途:SOCKS5 和 HTTP 代理·

6.1 为什么要加代理 Inbound·

除了透明隧道,sing-box 还可以作为显式代理服务器使用。典型场景:

  • 在 Firefox 中配置 SOCKS5 代理,让浏览器流量通过远端节点出站,实现"异地浏览"
  • 在 iOS 设备上配置 HTTP 代理,让手机 App 看起来在另一个城市
  • 临时测试某个网站在不同地区的访问效果

6.2 配置示例·

在现有配置的 inbounds 中增加 SOCKS5 和 HTTP 监听:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"inbounds": [
// ... existing tun and vless inbounds ...
{
"type": "socks",
"tag": "socks-in",
"listen": "0.0.0.0",
"listen_port": 1080
},
{
"type": "http",
"tag": "http-in",
"listen": "0.0.0.0",
"listen_port": 8080
}
]
}

这两个 Inbound 默认走 route.final 指定的 Outbound(在我们的配置中是 direct)。如果你希望代理流量走 VLESS 出站,可以添加路由规则:

1
2
3
4
5
6
7
8
9
10
11
12
{
"route": {
"rules": [
// ... existing rules ...
{
"inbound": ["socks-in", "http-in"],
"outbound": "vless-reality-out"
}
],
"final": "direct"
}
}

这样,通过 SOCKS5/HTTP 代理进来的流量会被转发到 fra,再从 fra 出站到互联网,实现"在德国上网"的效果。

6.3 客户端配置·

Firefox (SOCKS5)·

1
2
3
4
5
Settings -> Network Settings -> Manual proxy configuration
SOCKS Host: <sing-box IP>
Port: 1080
SOCKS v5: checked
Proxy DNS when using SOCKS v5: checked (important!)

iOS (HTTP Proxy)·

1
2
3
Settings -> Wi-Fi -> (i) -> HTTP Proxy -> Manual
Server: <sing-box IP>
Port: 8080

注意:SOCKS5 代理支持 TCP 和 UDP(如果客户端支持),HTTP 代理仅支持 TCP。对于浏览器场景,两者效果相同。iOS 系统级只支持 HTTP 代理,因此提供 HTTP inbound 是必要的。

7. 总结与架构全景·

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
+============================================================+
| Network Architecture |
+============================================================+

INTERNET
|
+-------------------+-------------------+
| | |
v v v

+--------+ +---------+ +--------+
| bham | WG | fra | VLESS | lab |
| (UK) |<------>| (DE) |<------->| (CN) |
| | UDP | | TCP x2 | |
+--------+ +---------+ +--------+
10.4.0.0/16 sing-box + 10.2.0.0/16
wg0 wg0 + tun0 sing-box +
tun0

Protocols in use:
bham <-> fra : WireGuard (UDP, fast, no DPI concern)
fra <-> lab : VLESS + REALITY x2 (TCP, stealth)
Session 1: lab ---> fra:443 (forward, lab reaches bham)
Session 2: fra ---> lab:8443 (reverse, bham reaches lab)

+------------------------------------------------------------+
| Key design decisions: |
| |
| 1. No WireGuard over VLESS (TCP meltdown, 95% speed loss) |
| 2. Two VLESS sessions for bidirectional (protocol limit) |
| 3. TUN with route_address (selective capture, safe) |
| 4. REALITY with apple.com SNI (DPI evasion) |
| 5. Optional SOCKS5/HTTP inbound (browser proxy) |
+------------------------------------------------------------+

整个方案的核心理念是:在审查环境和自由环境之间,用最合适的协议做最合适的事。 WireGuard 适合无审查的链路(快、简单、全协议支持),VLESS + REALITY 适合需要伪装的链路(隐蔽、TCP 性能优秀)。通过在中间节点(fra)同时运行两种协议栈,我们实现了跨越审查边界的双向局域网互通。