In the previous article, “Set Up an Install-Free IKEv2 Layer-3 Tunnel to Bypass Cursor Region Restrictions”, we introduced how to use an IKEv2 layer-3 tunnel to bypass geo-restrictions of software like Cursor. Although the IKEv2 solution has the advantage of not requiring a client installation, layer-3 tunnels themselves have some inherent performance issues.

This article will introduce a more efficient alternative: using Clash Verge’s TUN mode together with the VLESS protocol, which keeps things transparent to applications while avoiding the performance overhead brought by layer-3 tunnels.

Performance Pitfalls of Layer-3 Tunnels

The IKEv2 + VLESS/WebSocket architecture from the previous article has three main performance issues:

  1. TCP over TCP: application-layer TCP is encapsulated and transported inside the tunnel’s TCP (WebSocket), so two layers of TCP state machines interfere with each other
  2. Head-of-Line Blocking: multiple application connections are multiplexed over the same tunnel; packet loss on one connection blocks all connections
  3. QoS Limits on Long Connections: a single long-lived connection is easily throttled by middleboxes on the network

The TCP over TCP Problem

In the previous article’s architecture, we used VLESS over WebSocket over TLS to encapsulate IKEv2’s UDP traffic. Although IKEv2 itself uses UDP, when upper-layer applications use TCP, the entire data path ends up with TCP over TCP:

1
2
3
4
5
6
7
应用层 TCP 连接(如 Cursor 的 HTTP/2)
↓ 封装
IKEv2 隧道(ESP over UDP)
↓ 封装
VLESS over WebSocket over TLS(底层是 TCP)

物理网络传输

This nested TCP connection leads to serious performance issues:

  1. Retransmission Storms: when packet loss occurs on the underlying network, both the outer TCP (WebSocket connection) and the inner TCP (application connection) trigger their retransmission mechanisms. Packets retransmitted by the outer TCP may include data that the inner TCP has already successfully transmitted, causing大量无效重传.

  2. Conflicting Congestion Control: the two TCP layers each maintain independent congestion windows and RTT estimates. When network conditions change, their congestion control algorithms may make conflicting decisions, reducing bandwidth utilization.

  3. Accumulated Latency: each TCP layer has its own acknowledgment mechanism and timeout-based retransmission, and the resulting latency stacks up layer by layer.

Head-of-Line Blocking Problem

When multiple upper-layer connections are multiplexed over a single tunnel, Head-of-Line Blocking occurs:

1
2
3
4
5
6
7
连接 A 的数据包: [A1] [A2] [A3]
连接 B 的数据包: [B1] [B2]
连接 C 的数据包: [C1]

复用到同一条隧道

隧道数据流: [A1] [B1] [A2] [C1] [A3] [B2]

If a packet in the tunnel (say A2) is lost, the tunnel’s TCP connection pauses while waiting for retransmission. Even if B1, C1, A3, and B2 have already arrived, they cannot be read by the upper-layer applications, because TCP guarantees in-order delivery. This means:

  • Connections B and C are blocked by packet loss on connection A
  • Even if the data of connections B and C is intact, they still have to wait

This problem is especially severe on high-latency, high-loss cross-border links.

QoS Limits on Long Connections

Middleboxes on the network (such as ISP traffic management devices, firewalls, etc.) often apply QoS (Quality of Service) throttling to connections that have existed for a long time or that transmit large amounts of data:

  1. Connection Duration Detection: some middleboxes mark connections that live beyond a threshold (e.g., 30 minutes), and then lower their priority or limit their bandwidth.

  2. Traffic Pattern Identification: a single connection with sustained high bandwidth is easily identified as “abnormal traffic”, triggering throttling policies.

  3. Fairness Scheduling: to ensure fairness, ISPs may limit how much bandwidth a single connection can occupy.

Layer-3 tunnels usually maintain one or just a few long-lived connections to carry all traffic, which makes them particularly prone to hitting these limits.

Design Principles of Clash Verge TUN Mode

Clash Verge’s TUN mode offers an elegant solution: it keeps things transparent to applications while avoiding the aforementioned performance issues.

What Is TUN Mode?

TUN (network tunnel) is a virtual network device provided by the operating system. When TUN mode is enabled:

  1. Clash creates a virtual network interface (e.g., utun or tun0)
  2. The system routing table is modified to direct traffic to this virtual interface
  3. All traffic passing through this virtual interface is captured and processed by Clash

This means any application’s network traffic is transparently proxied, without needing to configure browser or per-application proxy settings.

Key Design: User-Space Protocol Stack

Clash’s TUN mode uses a user-space TCP/IP protocol stack (such as gVisor’s netstack), which is the key to avoiding the TCP over TCP problem:

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
传统三层隧道:
┌─────────────────────────────────────────┐
│ 应用 TCP 连接 │
│ ↓ │
│ 内核 TCP/IP 协议栈 │
│ ↓ │
│ 隧道封装(保留完整 TCP 头) │
│ ↓ │
│ 隧道 TCP 连接 │
│ ↓ │
│ 内核 TCP/IP 协议栈 │
└─────────────────────────────────────────┘

Clash TUN 模式:
┌─────────────────────────────────────────┐
│ 应用 TCP 连接 │
│ ↓ │
│ TUN 虚拟网卡捕获 IP 包 │
│ ↓ │
│ 用户态协议栈解析,提取 TCP 载荷 │
│ ↓ │
│ 建立新的代理连接(VLESS/WebSocket) │
│ ↓ │
│ 只传输应用层数据,不传输 TCP 头 │
└─────────────────────────────────────────┘

One-to-One Connection Mapping

Another key design in Clash TUN mode is the one-to-one mapping between upper-layer connections and underlying tunnel connections:

  • Each application TCP connection corresponds to an independent proxy connection
  • Each application UDP session corresponds to an independent proxy connection

This design brings significant benefits:

  1. Eliminates Head-of-Line Blocking: packet loss on connection A does not affect connections B and C, because they use independent underlying connections.

  2. Avoids TCP over TCP: the user-space protocol stack terminates the application’s TCP connection locally, extracts the application-layer data, and then sends it over a new TCP connection (VLESS/WebSocket). Although the underlying transport is still TCP, the application’s TCP state machine (sequence numbers, acknowledgments, retransmissions) is not encapsulated and transported, so there is no interference between two TCP state machines.

  3. Evades Long-Connection Limits: each application connection exists independently, and its lifecycle matches application behavior, so there is no single ultra-long-lived connection.

  4. Better Congestion Control: another important benefit of terminating the application’s TCP connection is that the long cross-border path is split into multiple shorter segments. In a layer-3 tunnel, the application’s TCP congestion control has to deal with the entire path from the client to the US server and then to the target website, resulting in a long RTT and poor bandwidth utilization. In Clash TUN mode, since Clash terminates the application-layer TCP connection, the RTT on each segment is shorter, congestion control can converge to optimal bandwidth more quickly, and overall throughput is higher.

Transparent to Applications

Unlike traditional HTTP/SOCKS proxies, TUN mode is completely transparent to applications:

Feature HTTP/SOCKS Proxy TUN Mode
Requires app support Yes No
Requires proxy configuration Yes No
Supports TCP Yes Yes
Supports UDP Partial (SOCKS5) Yes
Supports ICMP No Yes
Supports HTTP/2 Depends on app Yes

This means various hard-to-configure applications can work normally:

  • Cursor / Claude Code: these AI coding tools use HTTP/2 long connections and do not offer proxy configuration options
  • Docker Container: when developing with Dev Container mode, containers need to download dependencies from GitHub, npm, PyPI, etc., and configuring proxies is very troublesome
  • Command-line Tools: tools like git clone, npm install, and pip install can be configured to use a proxy via environment variables, but each tool has different configuration methods and it’s easy to miss some

TUN mode operates at the system network layer, is transparent to all applications, and requires no per-app configuration.

How DNS Works

DNS handling is another key component of Clash TUN mode.

Why Does DNS Need Special Handling?

In traditional HTTP/SOCKS proxies, applications usually perform DNS resolution first, then send the resolved IP address to the proxy server. This leads to two problems:

  1. DNS Leakage: DNS queries are sent directly to the local DNS server (usually the ISP’s), exposing the domains you access
  2. DNS Poisoning: some domains get incorrect IP addresses, making them inaccessible

Fake IP Mode

Clash’s TUN mode uses Fake IP mode by default to solve these problems:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1. 应用请求解析 google.com

2. 系统 DNS 请求被 Clash 劫持

3. Clash 返回一个假 IP(如 198.18.0.5)
并记录映射关系:198.18.0.5 → google.com

4. 应用使用 198.18.0.5 发起 TCP 连接

5. 连接被 TUN 虚拟网卡捕获

6. Clash 根据目标 IP 198.18.0.5 反查出域名 google.com

7. Clash 通过代理服务器连接 google.com
(真正的 DNS 解析在代理服务器端进行)

Advantages of this design:

  • Zero DNS leakage: no real DNS resolution happens locally
  • Bypass DNS poisoning: DNS resolution is performed in the proxy server’s network environment
  • Supports domain-based routing: even if the application only sends IP addresses, Clash still knows the original domain name
  • Reduced latency: eliminates the local DNS resolution round-trip

DNS Hijacking

To make Fake IP mode work, Clash needs to hijack system DNS requests. In TUN mode, this is done as follows:

  1. The TUN virtual interface takes over all network traffic
  2. Any request sent to a DNS server (port 53) is intercepted by Clash
  3. Clash’s built-in DNS server handles these requests

This is why, after enabling TUN mode, DNS requests are always handled by Clash regardless of the system’s DNS settings.

Architecture Design

Following the idea from “Cleverly Using Hong Kong Relay to Build a Smooth and Stable China–US Layer-3 Multi-Hop Tunnel”, we also adopt a three-hop architecture here, but using the VLESS protocol end-to-end:

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
+---------------------------+
| Your Device |
| (Clash Verge TUN Mode) |
+---------------------------+
|
VLESS over WS+TLS (TCP 443)
|
v
+---------------------------+
| China Server |
| (cn-gw.01.me) |
|---------------------------|
| Xray: |
| In: VLESS/WS/TLS |
| Out: VLESS/WS/TLS |
+---------------------------+
|
VLESS over WS+TLS (TCP 443)
|
v
+---------------------------+
| Hong Kong Server |
| (hk.01.me) |
|---------------------------|
| Xray: |
| In: VLESS/WS/TLS |
| Out: VLESS/WS/TLS |
+---------------------------+
|
VLESS over WS+TLS (TCP 443)
|
v
+---------------------------+
| US Server |
| (us-west.01.me) |
|---------------------------|
| Xray: |
| In: VLESS/WS/TLS |
| Out: freedom |
+---------------------------+
|
v
<-- Internet -->

Why Use Three Hops?

Just like with the IKEv2 solution, the three-hop architecture has the following advantages:

  1. Mainland China -> Hong Kong: leverage cloud providers’ optimized routes, with low latency and high stability
  2. Hong Kong -> United States: Hong Kong is a major network hub in Asia and has high-quality international bandwidth
  3. US Exit: the final IP is in the United States, which bypasses geo-restrictions

Why use VLESS end-to-end?

  1. Unified protocol: Simplifies configuration and maintenance
  2. Great performance: VLESS is lightweight with low overhead
  3. WebSocket transport: Masquerades as normal HTTPS traffic, strong penetration capability
  4. TLS encryption: End-to-end encryption, high security

Preparation

1. Server requirements

  • Mainland China server (in this article we use cn-gw.01.me as an example)
  • Hong Kong server (in this article we use hk.01.me as an example)
  • US server (in this article we use us-west.01.me as an example)

2. Domain names and certificates

Prepare a domain name and request an SSL certificate for each server:

1
2
3
4
5
6
7
8
9
10
11
12
# 在每台服务器上安装 certbot 并申请证书
sudo apt update
sudo apt install -y certbot

# 国内服务器
sudo certbot certonly --standalone -d cn-gw.01.me --non-interactive --agree-tos -m [email protected]

# 香港服务器
sudo certbot certonly --standalone -d hk.01.me --non-interactive --agree-tos -m [email protected]

# 美国服务器
sudo certbot certonly --standalone -d us-west.01.me --non-interactive --agree-tos -m [email protected]

3. Generate UUID

Generate a UUID for each hop’s VLESS connection:

1
2
3
4
5
6
7
export UUID_CLIENT_CN=$(uuidgen)
export UUID_CN_HK=$(uuidgen)
export UUID_HK_US=$(uuidgen)

echo "客户端 -> 国内: ${UUID_CLIENT_CN}"
echo "国内 -> 香港: ${UUID_CN_HK}"
echo "香港 -> 美国: ${UUID_HK_US}"

Step 1: Configure the US egress server

1.1 Install Xray

1
2
3
4
5
6
7
8
9
10
11
12
sudo apt update
sudo apt install -y curl

# 安装 Xray
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install

# 开启 BBR
sudo tee -a /etc/sysctl.conf > /dev/null << EOF
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
EOF
sudo sysctl -p

1.2 Configure Xray

Create /usr/local/etc/xray/config.json:

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
sudo tee /usr/local/etc/xray/config.json > /dev/null << EOF
{
"log": { "loglevel": "warning" },
"inbounds": [
{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "${UUID_HK_US}",
"level": 0
}
],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"certificates": [
{
"certificateFile": "/etc/letsencrypt/live/us-west.01.me/fullchain.pem",
"keyFile": "/etc/letsencrypt/live/us-west.01.me/privkey.pem"
}
]
},
"wsSettings": {
"path": "/wss_us"
}
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
}
]
}
EOF

1.3 Start the service

1
2
sudo systemctl enable --now xray
sudo systemctl status xray

Step 2: Configure the Hong Kong relay server

2.1 Install Xray

1
2
3
4
5
6
7
8
9
sudo apt update
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install

# 开启 BBR
sudo tee -a /etc/sysctl.conf > /dev/null << EOF
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
EOF
sudo sysctl -p

2.2 Configure Xray

Create /usr/local/etc/xray/config.json:

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
62
63
64
65
66
67
68
69
70
71
sudo tee /usr/local/etc/xray/config.json > /dev/null << EOF
{
"log": { "loglevel": "warning" },
"inbounds": [
{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "${UUID_CN_HK}",
"level": 0
}
],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"certificates": [
{
"certificateFile": "/etc/letsencrypt/live/hk.01.me/fullchain.pem",
"keyFile": "/etc/letsencrypt/live/hk.01.me/privkey.pem"
}
]
},
"wsSettings": {
"path": "/wss_hk"
}
}
}
],
"outbounds": [
{
"tag": "proxy-us",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "us-west.01.me",
"port": 443,
"users": [
{
"id": "${UUID_HK_US}",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"wsSettings": {
"path": "/wss_us"
}
}
}
],
"routing": {
"rules": [
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy-us"
}
]
}
}
EOF

2.3 Start the service

1
2
sudo systemctl enable --now xray
sudo systemctl status xray

Step 3: Configure the mainland China ingress server

3.1 Install Xray

1
2
3
4
5
6
7
8
9
sudo apt update
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install

# 开启 BBR
sudo tee -a /etc/sysctl.conf > /dev/null << EOF
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
EOF
sudo sysctl -p

3.2 Configure Xray

Create /usr/local/etc/xray/config.json:

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
62
63
64
65
66
67
68
69
70
71
sudo tee /usr/local/etc/xray/config.json > /dev/null << EOF
{
"log": { "loglevel": "warning" },
"inbounds": [
{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "${UUID_CLIENT_CN}",
"level": 0
}
],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"certificates": [
{
"certificateFile": "/etc/letsencrypt/live/cn-gw.01.me/fullchain.pem",
"keyFile": "/etc/letsencrypt/live/cn-gw.01.me/privkey.pem"
}
]
},
"wsSettings": {
"path": "/wss_cn"
}
}
}
],
"outbounds": [
{
"tag": "proxy-hk",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "hk.01.me",
"port": 443,
"users": [
{
"id": "${UUID_CN_HK}",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"wsSettings": {
"path": "/wss_hk"
}
}
}
],
"routing": {
"rules": [
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy-hk"
}
]
}
}
EOF

3.3 Start the service

1
2
sudo systemctl enable --now xray
sudo systemctl status xray

Step 4: Configure the Clash Verge client

4.1 Install Clash Verge

Download and install the version suitable for your OS from Clash Verge Rev.

4.2 Create the configuration file

The Clash Verge configuration is very simple: you only need to define the proxy servers and rules. TUN mode, DNS, and other settings can be enabled in the GUI and don’t need to be written into the config file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
proxies:
- name: "xray-cn-hk-us"
type: vless
server: cn-gw.01.me # 替换为你的入口服务器
port: 443
uuid: xxx # 替换为你的 UUID
tls: true
udp: true
network: ws
ws-opts:
path: /wss_cn

proxy-groups:
- name: Auto
type: select
proxies:
- "xray-cn-hk-us"

rules:
- MATCH,Auto

Configuration notes:

  • type: vless: Use the VLESS protocol
  • tls: true: Enable TLS encryption
  • udp: true: Support UDP forwarding (needed for DNS, QUIC, etc.)
  • network: ws: Use WebSocket transport
  • rules: MATCH,Auto: Send all traffic through the proxy

If you need direct access for domestic traffic, you can add split-routing rules:

1
2
3
rules:
- GEOIP,CN,DIRECT
- MATCH,Auto

4.3 Enable TUN mode

  1. Open Clash Verge
  2. Import the above configuration file
  3. In Settings, enable TUN Mode (Clash Verge will automatically configure DNS hijacking and Fake IP)
  4. macOS/Linux users need to grant administrator privileges
  5. Windows users need to run as administrator

After enabling TUN mode, Clash Verge will automatically:

  • Create a TUN virtual network interface
  • Configure the system routing table
  • Enable DNS hijacking and Fake IP mode

Verification and testing

1
2
3
4
5
# 检查出口 IP
curl ifconfig.me

# 测试 HTTP/2 支持(Cursor 等应用需要)
curl -I --http2 https://api.anthropic.com

Comparison with the IKEv2 solution

Feature IKEv2 + VLESS/WS tunnel Clash Verge TUN + VLESS
Client installation Not required Required
TCP over TCP Exists (app TCP over IKEv2 over WebSocket) None (user-space stack terminates app TCP)
HOL Blocking Exists (multiple connections multiplexed over a single tunnel) None (one-to-one connection mapping)
Long-connection limits Easily triggered (single long connection) Harder to trigger (independent short connections)
Congestion control End-to-end long path, high RTT Segmented short paths, low RTT, higher bandwidth
HTTP/2 support Yes Yes
UDP support Yes Yes
Transparent to apps Yes Yes
Traffic splitting rules Not supported Supported
Suitable scenarios No-client-install scenarios High performance

Summary

The Clash Verge TUN mode + VLESS solution, through its user-space protocol stack and one-to-one connection mapping, cleverly avoids the traditional L3 tunnel issues of TCP over TCP and head-of-line blocking. More importantly, by terminating application-layer TCP, it splits a long cross-border path into multiple shorter segments, each with independent congestion control, shorter RTT, and better bandwidth utilization. At the same time, independent short connections are less likely to trigger QoS limits imposed by middleboxes.

Compared with the IKEv2 solution, this approach requires installing a client, but in return provides better performance and flexible traffic-splitting rule support. For developers who need high-performance proxies (especially users of tools like Cursor), this is a solution worth considering.

Each solution has its pros and cons:

  • IKEv2: Suitable when you don’t want to install extra software
  • Clash Verge TUN: Suitable when you pursue performance and need split-routing rules

Choose the solution that best matches your actual needs.

Comments