搭建全程美国 IP、无需手动设置代理的三层隧道
为什么需要一个三层隧道
你所在的 AI 公司是否经常遇到以下情况?
- 需要访问只对美国 IP 开放的应用或大模型 API,如 OpenAI、Anthropic、Google 等
- 需要连接到美国的公司内网,但不想频繁设置代理
很多人搭建的是应用层代理,那么就需要在环境变量中设置 HTTP_PROXY,HTTPS_PROXY 等,但很多软件并不支持直接用环境变量配置代理,例如:
- Docker 容器内部并不会感知到外部的环境变量,如果要用现成的 docker compose 文件,又想让 docker 内的服务自动用上代理,就要折腾一番了。
- Docker 访问 docker.io 拉镜像和 build image 的时候,需要单独配置代理。
- 各种软件源,例如 pip、npm 等,需要单独配置代理。
- 一些软件,如 Google Cloud CLI,并不会从环境变量中读取代理配置,需要单独配置代理。
- 一些软件,如 Cursor,直接使用 IP 地址访问服务器,且使用的是非标准的 Websocket 协议,一些代理软件不兼容,或容易出问题。
- Node.js 服务端的一些库并不会直接检测 HTTP_PROXY 环境变量,而是需要配置 HTTP Proxy Agent,其中一些库(如 axios)在代理模式下还有 bug。
- 一些编译型语言的代码(如 C++、Go)常常自己组装 HTTP 请求发送,可能根本不支持配置 HTTP 代理。
- 一些 App(如 ChatGPT、Claude Code)使用额外的机制检测网络环境,如果发现代理,可能会拒绝服务,或者降低智商(例如用较差的模型代替 SOTA 模型)。
甚至到了 2023 年初,OpenAI 官方 Python 库的 HTTP_PROXY 环境变量还是有问题的!
我 2023 年 3 月给 OpenAI Python 库修了一个 HTTP_PROXY 环境变量的小 bug
很多人在下载试用开源 AI 项目的时候,经常跟网络问题斗争很久,真的很浪费时间。
本教程将手把手教你如何搭建一个全程美国 IP 的三层隧道,实现:
- 不需要在每个应用中手动设置代理
- 所有网络请求都从美国服务器发出
- 支持多种设备(Mac/Linux/iOS/Android/OpenWRT 路由器)
原理与架构
什么是三层隧道?
简单来说,我们要建立一个这样的连接路径:
你的设备
→ 国内服务器
→ 美国服务器
→ 互联网/公司内网
之所以要通过国内服务器中转,是因为很多设备所处的网络环境直接访问美国服务器会比较不稳定,甚至在高峰期无法访问。而如果通过国内服务器中转,公司可以购买国内服务器和美国服务器之间的国际专线,华为、阿里、腾讯等大型云服务商都提供此类专线服务,可选按流量或带宽计费。即使不想购买专线,使用公共互联网,实测也是可以用的。
技术架构
1 | +-----------------+ +------------------+ +----------------+ +-----------+ |
其中,WireGuard 是三层隧道协议。我们选用 WireGuard 是因为它被 Linux 内核直接支持,设计简洁优雅,性能比 PPTP、OpenVPN 等三层隧道协议更高。WireGuard 被 Linus Torvalds 称赞为 a work of art:
1 | Message-ID: <CA+55aFz5EWE9OTbzDoMfsY2ez04Qv9eg0KQhwKfyJY0vFvoD3g@mail.gmail.com> |
之所以要使用 VLESS 协议而不是 WireGuard 协议直连,是因为 WireGuard 协议走的是 UDP,不管是公共互联网还是一些按流量计费的国际专线,都会对 UDP 流量进行一些降级,导致高峰时段丢包率较高。因此,我们把 WireGuard 协议封装后的 UDP 报文通过 VLESS 协议转发,走 TCP + WebSocket 协议,可以使连接更稳定。
数据流传输过程
让我们详细分析数据包如何在这个系统中流动:
本地设备 → 国内服务器:
- 你的设备上运行 WireGuard 客户端,创建一个虚拟网络接口(通常名为
wg0
) - 当应用程序发出网络请求时,操作系统根据路由表将目标流量导向 WireGuard 虚拟接口
- WireGuard 客户端对数据包进行加密,然后通过 UDP 协议发送到国内服务器的指定端口(本文例子中使用 42371 端口)
- 这一阶段使用 WireGuard 原生的 UDP 传输,适合本地到国内服务器的相对稳定的网络环境
- 你的设备上运行 WireGuard 客户端,创建一个虚拟网络接口(通常名为
国内服务器内部处理:
- 国内服务器上的 Xray 通过 dokodemo-door 入站接收到 WireGuard UDP 流量
- 接收到的 WireGuard 加密数据被 Xray 路由系统转发到 VLESS 出站
- 这一步实现了关键的协议转换:从 UDP 到基于 TCP 的 WebSocket
国内服务器 → 美国服务器:
- 转换后的流量通过 VLESS 协议 + WebSocket + TLS(可选)传输到美国服务器
- WebSocket over TCP 协议可以避免 UDP 流量在传输过程中优先级较低的问题
- 可选的 TLS 加密提供了额外的安全层,防止 WireGuard 协议头数据被中间人监听或篡改
美国服务器内部处理:
- 美国服务器上的 Xray 通过 VLESS 入站接收到 WebSocket 流量
- Xray 将收到的数据导向本地的 WireGuard 服务(通过 freedom 出站配置为
127.0.0.1:42371
) - WireGuard 服务解密数据包,并通过 IP 转发将流量发送到目标网站或服务
美国服务器 → 互联网/内网:
- 解密后的数据包从美国服务器的物理网络接口发出
- 对外部服务和公司内网来说,这些请求看起来就像是直接从美国服务器发出的
网络性能考量
这种架构下,需要关注几个性能相关因素:
- 延迟增加:通过国内服务器、美国服务器转发不可避免地会增加一定的网络延迟,但对于大多数应用来说这是可以接受的。
- 下载速度降低:由于是三层隧道,整个 TCP 连接握手过程是在客户端和美国服务器之间直接进行的,慢启动过程的 RTT 也是跨国网络延迟,这会导致下载速度相比传统的 HTTP/HTTPS 代理方式降低。
- MTU 设置:由于多层封装,需要适当调低 MTU 值(如本文中建议的 1280),避免因 IP 分片导致的性能问题。
- 国内网站访问慢:由于是三层隧道,如果需要访问国内网站,就需要从美国绕一圈再访问回来,会变慢很多。
尽管存在这些开销,但这种架构带来的稳定性、兼容性和便利性优势通常更为重要,特别是在企业环境中,能够避免大量的代理配置工作,节省宝贵的开发和运维时间。
准备工作
你需要的资源
- 美国服务器:一台有公网 IP 的美国服务器
- 国内服务器:一台有公网 IP 的国内服务器
- 域名(可选):如果使用 CloudFlare 中转,需要一个域名
服务器要求
- 操作系统:推荐使用 Ubuntu 22.04
- 网络:需要有公网 IP
- 国内服务器需要打开 UDP 42371 端口的防火墙
- 美国服务器需要打开 TCP 10444 端口的防火墙(直连模式)或 TCP 80 端口的防火墙(CloudFlare 转发模式)
安装必要软件
以下命令请在每台服务器上运行:
1 | # 更新系统 |
注意:如果在国内服务器上,上述安装 Xray 的步骤无法正确执行,可以先下载 install-release.sh
,修改其中的 PROXY
配置为一个可用的公共代理,然后再 sudo 运行它安装 Xray。
UUID 生成及管理
在配置 Xray 时需要使用 UUID 作为客户端标识。
方法一:使用 Linux 系统自带工具
1 | cat /proc/sys/kernel/random/uuid |
方法二:使用 Python
1 | python3 -c "import uuid; print(uuid.uuid4())" |
详细配置步骤
第一步:配置美国服务器
1.1 生成 WireGuard 密钥
1 | # 创建WireGuard配置目录 |
上述密钥将需要填写在后续的配置文件中。
1.2 创建 WireGuard 配置文件
1 | sudo nano /etc/wireguard/wg0.conf |
输入以下内容(替换相应的密钥):
1 | [Interface] |
1.3 配置Xray
1 | sudo nano /usr/local/etc/xray/config.json |
输入以下内容(替换 UUID 为前面生成的值):
1 | { |
1.4 启动服务
1 | # 启动WireGuard |
1.5 开启 IP 转发
1 | # 编辑系统配置文件 |
1.6 配置 NAT
IP 转发已经开启,但我们还需要配置 NAT 以使来自 WireGuard 网络的流量能够转发到互联网。这一步是 非常关键 的,否则隧道将无法正常工作。
1 | # 添加 iptables NAT 规则 |
注意:上面的命令中,eth0
是美国服务器的网络接口名称,你需要根据实际情况替换它。可以使用 ip addr
或 ifconfig
命令查看你服务器的网络接口名称。
如果你的服务器重启后,iptables 规则会丢失,可以使用以下方法使 NAT 规则持久化:
1 | # 安装 iptables-persistent |
如果你使用的是 nftables 而不是 iptables(Ubuntu 22.04 默认使用 nftables),则可以使用以下命令:
1 | # 添加 nftables NAT 规则 |
第二步:配置国内服务器
2.1 创建V2Ray/Xray配置文件
1 | sudo nano /usr/local/etc/xray/config.json |
输入以下内容(替换相应的值):
1 | { |
注意:如果直连不稳定,可以使用 CloudFlare 做中转,将 outboundTag 改为 “wireguard-vless-proxy-out”
2.2 启动服务
1 | # 启动Xray |
第三步:配置 CloudFlare 中转(可选)
第三步:配置 CloudFlare 中转(可选)
如果国内直连美国服务器不稳定,可以使用 CloudFlare 作为中转。CloudFlare 可以帮你自动申请 TLS 证书,将 CloudFlare 服务器的 443 端口和用户指定的域名代理到美国服务器的 80 端口,然后再在美国服务器上搭建 Nginx 反向代理将 80 端口代理到 10444 端口。
3.1 注册 CloudFlare 账号并添加域名
- 注册一个 CloudFlare 账号
- 添加你的域名到 CloudFlare
- 将域名的 DNS 服务器修改为 CloudFlare 提供的服务器
3.2 创建 DNS 记录
- 在 CloudFlare 控制面板选择你的域名
- 点击 “DNS” 选项卡
- 添加一条A记录,指向美国服务器IP地址
- 类型: A
- 名称: 子域名(例如:tunnel)
- 内容: 美国服务器 IP
- 代理状态: 已代理(云朵图标为橙色)
3.3 在美国服务器上配置 Nginx 反向代理
由于 CloudFlare 代理到 80 端口,而我们的 Xray 监听的是 10444 端口,需要配置 Nginx 进行转发:
安装 Nginx:
1
sudo apt install -y nginx
创建 Nginx 配置文件:
1
sudo nano /etc/nginx/sites-available/xray
添加以下配置内容(根据你的域名调整):
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;
}
}启用配置并重启 Nginx:
1
2
3sudo ln -s /etc/nginx/sites-available/xray /etc/nginx/sites-enabled/
sudo nginx -t # 检查配置是否有错误
sudo systemctl restart nginx修改国内服务器上的 Xray 配置:
编辑
/usr/local/etc/xray/config.json
文件,将wireguard-vless-proxy-out
出站部分修改为: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"
}
}
}
完成上述配置后,CloudFlare 将代理流量到美国服务器的 80 端口,然后 Nginx 将流量转发到 Xray 的 10444 端口。这种配置无需处理 SSL 证书,简化了部署流程。
注意:这种配置下,流量在 CloudFlare 到美国服务器之间是明文传输的。不过由于 WireGuard 协议本身已经加密,实际安全风险有限。如果对安全性要求较高,建议使用 HTTPS 配置。
第四步:生成 WireGuard 客户端配置
创建一个名为 wg0-client.conf
的文件:
1 | [Interface] |
注意:
AllowedIPs = 0.0.0.0/0, ::/0
表示所有流量都会通过 WireGuard 隧道
第五步:在不同设备上使用
5.1 Windows 客户端
- 下载 WireGuard 官方客户端
- 安装并启动 WireGuard
- 点击 “添加隧道” → “从文件导入”,选择刚才创建的配置文件
- 点击”激活”按钮启用隧道
5.2 macOS 客户端
- 从 App Store 下载WireGuard客户端
- 打开 WireGuard,点击 “+”,选择 “导入从文件或归档”
- 选择配置文件,点击 “添加”
- 点击开关启用隧道
5.3 iOS 客户端
- 从 App Store 下载 WireGuard 客户端
- 打开 WireGuard,点击”+”,选择”创建自二维码”或”创建自文件”
- 导入配置后,点击开关启用隧道
5.4 Android客户端
- 从 Google Play 商店下载 WireGuard 客户端
- 打开 WireGuard,点击 “+”,选择 “从文件导入”
- 选择配置文件,点击 “导入”
- 点击开关启用隧道
5.5 Linux客户端
1 | # 安装WireGuard |
5.6 OpenWRT 路由器
- 登录路由器管理界面
- 安装 WireGuard 包:
- 系统 → 软件包 → 搜索 “wireguard” → 安装
- 网络 → 接口 → 添加新接口
- 名称:WireGuard
- 协议:WireGuard VPN
- 复制配置文件内容到相应字段
- 防火墙设置:
- 防火墙 → 常规设置 → 允许转发
- 添加 WireGuard 接口到WAN区域
验证与测试
连接测试
排障指南
连接问题
无法连接到国内服务器
- 检查防火墙是否开放 42371 端口(UDP)
- 检查 Xray 服务是否正常运行
能连接国内服务器但无法上网
- 检查防火墙是否开放 10444 端口(TCP)
- 检查美国服务器 WireGuard 配置
- 检查 Xray 服务是否正常运行
- 检查 IP 转发是否已启用
连接不稳定
- 尝试使用 CloudFlare 作为中转
- 检查MTU设置,可以尝试调低(例如1200)
查看日志
- WireGuard日志:
sudo journalctl -u wg-quick@wg0
- Xray日志:
sudo cat /var/log/xray/error.log
进阶性能优化
- BBR加速
1 | # 编辑sysctl配置 |
- 调整MTU值
如果网络连接不稳定,可以尝试不同的MTU值(1200-1500之间)。
策略路由:让国内网站直连访问
上面提到,使用全局隧道会导致访问国内网站变慢。这一节我们将讲解如何配置策略路由,使国内网站走直连,国外网站走隧道。
准备中国 IP 地址段列表
首先,我们需要获取中国 IP 地址段列表。
方案一:使用开源项目
1 | # 创建存放中国 IP 段的目录 |
方案二:使用 APNIC 官方数据
1 | # 创建存放中国 IP 段的目录 |
Linux 系统上的配置
1. 创建路由脚本(Linux 系统)
创建 WireGuard up/down 脚本,当 WireGuard 连接建立或断开时自动执行:
1 | sudo nano /etc/wireguard/wg-up.sh |
输入以下内容:
1 |
|
创建 down 脚本以在连接断开时清理路由规则:
1 | sudo nano /etc/wireguard/wg-down.sh |
输入以下内容:
1 |
|
设置脚本执行权限:
1 | sudo chmod +x /etc/wireguard/wg-up.sh |
2. 配置 WireGuard 使用脚本
修改 WireGuard 配置文件,添加 PostUp 和 PostDown 钩子:
1 | sudo nano /etc/wireguard/wg0.conf |
在 [Interface]
部分添加:
1 | PostUp = /etc/wireguard/wg-up.sh |
完整的配置示例:
1 | [Interface] |
3. 重启 WireGuard 服务
1 | sudo systemctl restart wg-quick@wg0 |
4. 验证策略路由是否生效
测试访问国内网站是否走直连:
1 | # 追踪到百度的路由 |
Mac 系统上的配置
macOS 用户可以使用以下脚本实现类似功能:
1 |
|
将此脚本保存为文件(如 ~/wireguard-route.sh
),并在连接 WireGuard 后手动执行:
1 | chmod +x ~/wireguard-route.sh |
常见问题与解决方案
脚本执行失败
- 检查脚本是否有可执行权限
- 确认脚本中的接口名称是否正确
路由未生效
- 使用
ip route show
检查路由表 - 确认中国 IP 列表文件存在且内容正确
- 使用
国内网站仍然很慢
- 检查 DNS 设置,可能 DNS 解析走了国外服务器
- 可以使用国内防污染 DNS
策略路由后无法上网
- 检查默认路由是否正确
- 确认 WireGuard 配置中的 AllowedIPs 设置
通过以上配置,你的设备将实现智能分流:国内网站走直连,国外网站通过三层隧道访问,既保证了访问国外服务的稳定性,又不影响国内网站的访问速度。
添加多个客户端
重要:每个客户端配置仅限单一设备使用
需要注意的是,每个 WireGuard 客户端配置只能同时被一个设备使用。因此,每添加一个新设备,都需要生成新的客户端配置。
步骤:添加新的客户端
1. 在美国服务器上生成新客户端密钥
1 | cd /etc/wireguard |
2. 修改美国服务器上的 WireGuard 配置
编辑 /etc/wireguard/wg0.conf
文件,在末尾添加新的 Peer 部分:
1 | sudo nano /etc/wireguard/wg0.conf |
添加新的 Peer 部分:
1 | # 第一个客户端(原有配置) |
注意:
- 每个客户端需要使用不同的 IP 地址范围(AllowedIPs)
- 你也可以为每个新客户端生成新的预共享密钥(PresharedKey)以提高安全性
3. 重新加载美国服务器上的 WireGuard 配置
1 | sudo wg-quick down wg0 |
4. 创建新的客户端配置文件
创建一个名为 wg0-client2.conf
的新文件:
1 | [Interface] |
5. 将新配置分发到新设备
将 wg0-client2.conf
文件传输到新设备上,并按照前面提到的方法导入到相应平台的 WireGuard 客户端中。
性能优化:选择合适的服务器地区
如果你发现使用美国服务器速度较慢,可以考虑使用日本或新加坡等同样开放 OpenAI、Anthropic、Google 服务的国家的服务器来代替美国服务器。一般来说,中国北方用户访问日本服务器较快,而南方用户访问新加坡服务器较快。这样的替换不会影响到大多数服务的使用,同时可以显著提升网络体验和响应速度。
只需将上述教程中的美国服务器替换为日本或新加坡的服务器,其他配置步骤保持不变即可。选择合适的节点位置,是优化三层隧道性能的重要步骤。