Setting Up a Three-Layer Tunnel with Full US IP, No Manual Proxy Configuration Required
Why You Need a Three-Layer Tunnel
Does your AI company often encounter the following situations?
- Need to access applications or large model APIs that are only open to US IPs, such as OpenAI, Anthropic, Google, etc.
- Need to connect to the company’s internal network in the US but don’t want to frequently set up proxies
Many people set up application layer proxies, which require setting HTTP_PROXY, HTTPS_PROXY, etc., in environment variables. However, many software do not support configuring proxies directly using environment variables, such as:
- Docker containers do not perceive external environment variables. If you want to use existing docker compose files and want the services inside the docker to automatically use the proxy, you’ll have to tinker a bit.
- Docker requires separate proxy configuration when accessing docker.io to pull images and build images.
- Various software sources, such as pip, npm, etc., require separate proxy configuration.
- Some software, like Google Cloud CLI, do not read proxy configurations from environment variables and require separate proxy configuration.
- Some software, like Cursor, directly use IP addresses to access servers and use non-standard WebSocket protocols, which some proxy software are not compatible with or are prone to issues.
- Some Node.js server-side libraries do not directly detect the HTTP_PROXY environment variable and require configuring an HTTP Proxy Agent. Some libraries (like axios) have bugs in proxy mode.
- Some compiled language code (like C++, Go) often assembles HTTP requests themselves and may not support configuring HTTP proxies.
- Some apps (like ChatGPT, Claude Code) use additional mechanisms to detect network environments. If they detect a proxy, they may refuse service or reduce intelligence (e.g., using a poorer model instead of the SOTA model).
Even by early 2023, the HTTP_PROXY environment variable in the official OpenAI Python library still had issues!
In March 2023, I fixed a small bug in the HTTP_PROXY environment variable for the OpenAI Python library
Many people spend a lot of time struggling with network issues when downloading and trying open-source AI projects, which is really a waste of time.
This tutorial will guide you step-by-step on how to set up a three-layer tunnel with full US IP, achieving:
- No need to manually set up proxies in each application
- All network requests are sent from US servers
- Support for multiple devices (Mac/Linux/iOS/Android/OpenWRT routers)
Principles and Architecture
What is a Three-Layer Tunnel?
In simple terms, we want to establish a connection path like this:
Your Device
→ Domestic Server
→ US Server
→ Internet/Company Intranet
The reason for relaying through a domestic server is that the network environment of many devices is relatively unstable when directly accessing US servers, and may even be inaccessible during peak times. By relaying through a domestic server, the company can purchase an international dedicated line between the domestic server and the US server. Large cloud service providers like Huawei, Alibaba, and Tencent offer such dedicated line services, with options for traffic or bandwidth billing. Even if you don’t want to purchase a dedicated line, using the public internet is also feasible in practice.
Technical Architecture
1 | +-----------------+ +------------------+ +----------------+ +-----------+ |
WireGuard is the three-layer tunnel protocol. We choose WireGuard because it is directly supported by the Linux kernel, has a simple and elegant design, and offers higher performance than other three-layer tunnel protocols like PPTP and OpenVPN. WireGuard has been praised by Linus Torvalds as a work of art:
1 | Message-ID: <CA+55aFz5EWE9OTbzDoMfsY2ez04Qv9eg0KQhwKfyJY0vFvoD3g@mail.gmail.com> |
The reason for using the VLESS protocol instead of directly connecting with the WireGuard protocol is that WireGuard uses UDP. Both the public internet and some traffic-billed international dedicated lines will degrade UDP traffic, leading to higher packet loss rates during peak times. Therefore, we encapsulate the UDP packets of the WireGuard protocol and forward them using the VLESS protocol, which uses TCP + WebSocket protocol, making the connection more stable.
Data Flow Transmission Process
Let’s analyze in detail how data packets flow in this system:
Local Device → Domestic Server:
- Your device runs the WireGuard client, creating a virtual network interface (usually named
wg0
) - When an application sends a network request, the operating system routes the target traffic to the WireGuard virtual interface based on the routing table
- The WireGuard client encrypts the data packets and sends them to the specified port on the domestic server via UDP (port 42371 in this example)
- This stage uses WireGuard’s native UDP transmission, suitable for the relatively stable network environment from local to domestic server
- Your device runs the WireGuard client, creating a virtual network interface (usually named
Domestic Server Internal Processing:
- The Xray on the domestic server receives the WireGuard UDP traffic through dokodemo-door inbound
- The received WireGuard encrypted data is forwarded to VLESS outbound by the Xray routing system
- This step achieves the key protocol conversion: from UDP to TCP-based WebSocket
Domestic Server → US Server:
- The converted traffic is transmitted to the US server via VLESS protocol + WebSocket + TLS (optional)
- WebSocket over TCP protocol avoids the issue of low priority for UDP traffic during transmission
- Optional TLS encryption provides an additional security layer, preventing WireGuard protocol header data from being eavesdropped or tampered with by middlemen
US Server Internal Processing:
- The Xray on the US server receives the WebSocket traffic through VLESS inbound
- Xray directs the received data to the local WireGuard service (configured via freedom outbound as
127.0.0.1:42371
) - The WireGuard service decrypts the data packets and forwards the traffic to the target website or service via IP forwarding
US Server → Internet/Intranet:
- The decrypted data packets are sent out from the physical network interface of the US server
- To external services and the company intranet, these requests appear to be directly sent from the US server
Network Performance Considerations
Under this architecture, several performance-related factors need attention:
- Increased Latency: Relaying through domestic and US servers inevitably increases network latency, but this is acceptable for most applications.
- Reduced Download Speed: Due to the three-layer tunnel, the entire TCP connection handshake process is directly between the client and the US server. The slow start process’s RTT is also cross-border network latency, which will reduce download speed compared to traditional HTTP/HTTPS proxy methods.
- MTU Settings: Due to multi-layer encapsulation, the MTU value needs to be appropriately lowered (such as the recommended 1280 in this article) to avoid performance issues caused by IP fragmentation.
- Slow Access to Domestic Websites: Due to the three-layer tunnel, accessing domestic websites requires a round trip from the US, which will be much slower.
Despite these overheads, the stability, compatibility, and convenience advantages brought by this architecture are usually more important, especially in enterprise environments, where it can avoid a lot of proxy configuration work and save valuable development and operation time.
Preparation
Resources You Need
- US Server: A US server with a public IP
- Domestic Server: A domestic server with a public IP
- Domain Name (optional): If using CloudFlare relay, a domain name is needed
Server Requirements
- Operating System: Recommended to use Ubuntu 22.04
- Network: Requires a public IP
- Domestic server needs to open the firewall for UDP port 42371
- US server needs to open the firewall for TCP port 10444 (direct connection mode) or TCP port 80 (CloudFlare relay mode)
Install Necessary Software
Run the following commands on each server:
1 | # 更新系统 |
Note: If the above steps to install Xray on the domestic server do not execute correctly, you can first download install-release.sh
, modify the PROXY
configuration to a usable public proxy, and then run it with sudo to install Xray.
UUID Generation and Management
When configuring Xray, a UUID is needed as the client identifier.
Method 1: Use Linux System Built-in Tool
1 | cat /proc/sys/kernel/random/uuid |
Method 2: Use Python
1 | python3 -c "import uuid; print(uuid.uuid4())" |
Detailed Configuration Steps
Step 1: Configure the US Server
1.1 Generate WireGuard Keys
1 | # 创建WireGuard配置目录 |
The above keys will need to be filled in the subsequent configuration files.
1.2 Create WireGuard Configuration File
1 | sudo nano /etc/wireguard/wg0.conf |
Enter the following content (replace with the corresponding keys):
1 | [Interface] |
1.3 Configure Xray
1 | sudo nano /usr/local/etc/xray/config.json |
Enter the following content (replace UUID with the previously generated value):
1 | { |
1.4 Start the Service
1 | # 启动WireGuard |
1.5 Enable IP Forwarding
1 | # 编辑系统配置文件 |
1.6 Configure NAT
IP forwarding is enabled, but we also need to configure NAT to allow traffic from the WireGuard network to be forwarded to the internet. This step is very critical, otherwise the tunnel will not work properly.
1 | # 添加 iptables NAT 规则 |
Note: In the above command, eth0
is the network interface name of the US server, and you need to replace it according to the actual situation. You can use the ip addr
or ifconfig
command to view the network interface name of your server.
If your server loses iptables rules after rebooting, you can use the following method to make the NAT rules persistent:
1 | # 安装 iptables-persistent |
If you are using nftables instead of iptables (Ubuntu 22.04 uses nftables by default), you can use the following command:
1 | # 添加 nftables NAT 规则 |
Step 2: Configure the Domestic Server
2.1 Create V2Ray/Xray Configuration File
1 | sudo nano /usr/local/etc/xray/config.json |
Enter the following content (replace the corresponding values):
1 | { |
Note: If direct connection is unstable, you can use CloudFlare as a relay and change outboundTag to “wireguard-vless-proxy-out”
2.2 Start the Service
1 | # 启动Xray |
Step 3: Configure CloudFlare Relay (Optional)
Step 3: Configure CloudFlare Relay (Optional)
If the direct connection from the domestic server to the US server is unstable, you can use CloudFlare as a relay. CloudFlare can help you automatically apply for a TLS certificate, proxy the 443 port of the CloudFlare server and the user-specified domain name to the 80 port of the US server, and then set up an Nginx reverse proxy on the US server to proxy the 80 port to the 10444 port.
3.1 Register a CloudFlare Account and Add a Domain
- Register a CloudFlare account
- Add your domain to CloudFlare
- Change the DNS server of the domain to the server provided by CloudFlare
3.2 Create DNS Records
- Select your domain in the CloudFlare control panel
- Click the “DNS” tab
- Add an A record pointing to the US server IP address
- Type: A
- Name: Subdomain (e.g., tunnel)
- Content: US server IP
- Proxy status: Proxied (cloud icon is orange)
3.3 Configure Nginx Reverse Proxy on the US Server
Since CloudFlare proxies to port 80, and our Xray listens on port 10444, we need to configure Nginx for forwarding:
Install Nginx:
1
sudo apt install -y nginx
Create an Nginx configuration file:
1
sudo nano /etc/nginx/sites-available/xray
Add the following configuration content (adjust according to your domain):
1
2
3
4
5
6
7
8
9
10
11
12
13
14server {
listen 80;
server_name tunnel.yourdomain.com; # 替换为你的域名
location /wss {
proxy_pass http://127.0.0.1:10444;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}Enable the configuration and restart Nginx:
1
2
3sudo ln -s /etc/nginx/sites-available/xray /etc/nginx/sites-enabled/
sudo nginx -t # Check for configuration errors
sudo systemctl restart nginxModify the Xray configuration on the domestic server:
Edit the
/usr/local/etc/xray/config.json
file and modify thewireguard-vless-proxy-out
outbound section to:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24"wireguard-vless-proxy-out": {
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "tunnel.yourdomain.com", // 替换为你的 CloudFlare 域名
"port": 80, // 修改为 80 端口
"users": [
{
"id": "<random-uuid>",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "none", // 移除 TLS
"wsSettings": {
"path": "/wss"
}
}
}
After completing the above configuration, CloudFlare will proxy traffic to the 80 port of the US server, and then Nginx will forward the traffic to the 10444 port of Xray. This configuration does not require handling SSL certificates, simplifying the deployment process.
Note: In this configuration, traffic between CloudFlare and the US server is transmitted in plaintext. However, since the WireGuard protocol itself is already encrypted, the actual security risk is limited. If higher security is required, it is recommended to use HTTPS configuration.
Step 4: Generate WireGuard Client Configuration
Create a file named wg0-client.conf
:
1 | [Interface] |
Note:
AllowedIPs = 0.0.0.0/0, ::/0
means all traffic will go through the WireGuard tunnel
Step 5: Use on Different Devices
5.1 Windows Client
- Download the WireGuard official client
- Install and start WireGuard
- Click “Add Tunnel” → “Import from File”, and select the configuration file you just created
- Click the “Activate” button to enable the tunnel
5.2 macOS Client
- Download the WireGuard client from the App Store
- Open WireGuard, click “+”, and select “Import from File or Archive”
- Select the configuration file and click “Add”
- Click the switch to enable the tunnel
5.3 iOS Client
- Download the WireGuard client from the App Store
- Open WireGuard, click “+”, and select “Create from QR Code” or “Create from File”
- After importing the configuration, click the switch to enable the tunnel
5.4 Android Client
- Download the WireGuard client from the Google Play Store
- Open WireGuard, click “+”, and select “Import from File”
- Select the configuration file and click “Import”
- Click the switch to enable the tunnel
5.5 Linux Client
1 | # 安装WireGuard |
5.6 OpenWRT Router
- Log in to the router management interface
- Install the WireGuard package:
- System → Software → Search “wireguard” → Install
- Network → Interfaces → Add New Interface
- Name: WireGuard
- Protocol: WireGuard VPN
- Copy the configuration file content to the corresponding fields
- Firewall Settings:
- Firewall → General Settings → Allow Forwarding
- Add the WireGuard interface to the WAN zone
Verification and Testing
Connection Test
After connecting to WireGuard, ping the internal IP of the US server:
1
ping 10.10.20.1
Visit ip.gs or ip.sb to check your current IP address, which should show as a US IP
Troubleshooting Guide
Connection Issues
Unable to connect to the domestic server
- Check if the firewall is open for port 42371 (UDP)
- Check if the Xray service is running properly
Can connect to the domestic server but cannot access the internet
- Check if the firewall is open for port 10444 (TCP)
- Check the WireGuard configuration on the US server
- Check if the Xray service is running properly
- Check if IP forwarding is enabled
Unstable connection
- Try using CloudFlare as a relay
- Check MTU settings, you can try lowering it (e.g., 1200)
View Logs
- WireGuard logs:
sudo journalctl -u wg-quick@wg0
- Xray logs:
sudo cat /var/log/xray/error.log
Advanced Performance Optimization
- BBR Acceleration
1 | # 编辑sysctl配置 |
- Adjust MTU Value
If the network connection is unstable, you can try different MTU values (between 1200-1500).
Policy Routing: Direct Access to Domestic Websites
As mentioned above, using a global tunnel will slow down access to domestic websites. In this section, we will explain how to configure policy routing so that domestic websites are accessed directly, while foreign websites go through the tunnel.
Preparing a List of Chinese IP Address Ranges
First, we need to obtain a list of Chinese IP address ranges.
Option 1: Use an open-source project
1 | # 创建存放中国 IP 段的目录 |
Option 2: Use APNIC official data
1 | # 创建存放中国 IP 段的目录 |
Configuration on Linux Systems
1. Create Routing Scripts (Linux Systems)
Create WireGuard up/down scripts to automatically execute when the WireGuard connection is established or disconnected:
1 | sudo nano /etc/wireguard/wg-up.sh |
Enter the following content:
1 |
|
Create a down script to clean up routing rules when the connection is disconnected:
1 | sudo nano /etc/wireguard/wg-down.sh |
Enter the following content:
1 |
|
Set script execution permissions:
1 | sudo chmod +x /etc/wireguard/wg-up.sh |
2. Configure WireGuard to Use Scripts
Modify the WireGuard configuration file to add PostUp and PostDown hooks:
1 | sudo nano /etc/wireguard/wg0.conf |
Add the following in the [Interface]
section:
1 | PostUp = /etc/wireguard/wg-up.sh |
Complete configuration example:
1 | [Interface] |
3. Restart the WireGuard Service
1 | sudo systemctl restart wg-quick@wg0 |
4. Verify if Policy Routing is Effective
Test if accessing domestic websites is done directly:
1 | # 追踪到百度的路由 |
Configuration on Mac Systems
macOS users can use the following script to achieve similar functionality:
1 |
|
Save this script as a file (e.g., ~/wireguard-route.sh
) and execute it manually after connecting to WireGuard:
1 | chmod +x ~/wireguard-route.sh |
Common Issues and Solutions
Script Execution Failure
- Check if the script has executable permissions
- Ensure the interface name in the script is correct
Routing Not Effective
- Use
ip route show
to check the routing table - Ensure the Chinese IP list file exists and its content is correct
- Use
Domestic Websites Still Slow
- Check DNS settings, as DNS resolution might be going through foreign servers
- You can use domestic anti-pollution DNS
Unable to Access the Internet After Policy Routing
- Check if the default route is correct
- Ensure the AllowedIPs setting in the WireGuard configuration
With the above configuration, your device will achieve intelligent traffic splitting: domestic websites are accessed directly, while foreign websites are accessed through a three-layer tunnel, ensuring the stability of accessing foreign services without affecting the speed of accessing domestic websites.
Adding Multiple Clients
Important: Each Client Configuration is Limited to a Single Device
It is important to note that each WireGuard client configuration can only be used by one device at a time. Therefore, for each new device added, a new client configuration needs to be generated.
Steps: Adding a New Client
1. Generate New Client Keys on the US Server
1 | cd /etc/wireguard |
2. Modify the WireGuard Configuration on the US Server
Edit the /etc/wireguard/wg0.conf
file and add a new Peer section at the end:
1 | sudo nano /etc/wireguard/wg0.conf |
Add a new Peer section:
1 | # 第一个客户端(原有配置) |
Note:
- Each client needs to use a different IP address range (AllowedIPs)
- You can also generate a new pre-shared key (PresharedKey) for each new client to enhance security
3. Reload the WireGuard Configuration on the US Server
1 | sudo wg-quick down wg0 |
4. Create a New Client Configuration File
Create a new file named wg0-client2.conf
:
1 | [Interface] |
5. Distribute the New Configuration to the New Device
Transfer the wg0-client2.conf
file to the new device and import it into the WireGuard client on the respective platform as mentioned earlier.
Performance Optimization: Choosing the Right Server Location
If you find the speed using the US server is slow, consider using servers in Japan or Singapore, which also allow access to OpenAI, Anthropic, and Google services, instead of the US server. Generally, users in northern China have faster access to Japanese servers, while users in southern China have faster access to Singapore servers. Such a replacement will not affect the use of most services and can significantly improve network experience and response speed.
Simply replace the US server in the above tutorial with a server in Japan or Singapore, and keep the other configuration steps unchanged. Choosing the right node location is an important step in optimizing the performance of the three-layer tunnel.