为什么需要一个三层隧道

你所在的 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(如 OpenAI)使用额外机制检测网络环境,如果发现代理,可能会导致拒绝服务,或者降低智商(例如用较差的模型代替 SOTA 模型)。

甚至到了 2023 年初,OpenAI 官方 Python 库的 HTTP_PROXY 环境变量还是有问题的!

我 2023 年 3 月给 OpenAI Python 库修了一个 HTTP_PROXY 环境变量的小 bug我 2023 年 3 月给 OpenAI Python 库修了一个 HTTP_PROXY 环境变量的小 bug

很多人在下载试用开源 AI 项目的时候,经常跟网络问题斗争很久,真的很浪费时间。

本教程将手把手教你如何搭建一个全程美国 IP 的三层隧道,实现:

  1. 不需要在每个应用中手动设置代理
  2. 所有网络请求都从美国服务器发出
  3. 支持多种设备(Mac/Linux/iOS/Android/OpenWRT 路由器)

原理与架构

什么是三层隧道?

简单来说,我们要建立一个这样的连接路径:

你的设备国内服务器美国服务器互联网/公司内网

之所以要通过国内服务器中转,是因为很多设备所处的网络环境直接访问美国服务器会比较不稳定,甚至在高峰期无法访问。而如果通过国内服务器中转,公司可以购买国内服务器和美国服务器之间的国际专线,华为、阿里、腾讯等大型云服务商都提供此类专线服务,可选按流量或带宽计费。即使不想购买专线,使用公共互联网,实测也是可以用的。

技术架构

1
2
3
4
5
+-----------------+       +------------------+       +----------------+       +-----------+
| 你的设备 | | 国内服务器 | | 美国服务器 | | 互联网 |
| WireGuard客户端 | ====> | WireGuard接收 | ====> | VLESS接收 | ====> | /公司内网 |
| | | VLESS转发 | | WireGuard发送 | | |
+-----------------+ +------------------+ +----------------+ +-----------+

其中,WireGuard 是三层隧道协议。我们选用 WireGuard 是因为它被 Linux 内核直接支持,设计简洁优雅,性能比 PPTP、OpenVPN 等三层隧道协议更高。WireGuard 被 Linus Torvalds 称赞为 a work of art:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Message-ID: <CA+55aFz5EWE9OTbzDoMfsY2ez04Qv9eg0KQhwKfyJY0vFvoD3g@mail.gmail.com>
Date: Thu, 2 Aug 2018 10:15:40 -0700
From: Linus Torvalds <torvalds@...ux-foundation.org>
To: David Miller <davem@...emloft.net>
Cc: Andrew Morton <akpm@...ux-foundation.org>,
Network Development <netdev@...r.kernel.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: Re: [GIT] Networking

On Wed, Aug 1, 2018 at 9:37 PM David Miller <davem@...emloft.net> wrote:
>
> Fixes keep trickling in:

Pulled.

Btw, on an unrelated issue: I see that Jason actually made the pull
request to have wireguard included in the kernel.

Can I just once again state my love for it and hope it gets merged
soon? Maybe the code isn't perfect, but I've skimmed it, and compared
to the horrors that are OpenVPN and IPSec, it's a work of art.

Linus

之所以要使用 VLESS 协议而不是 WireGuard 协议直连,是因为 WireGuard 协议走的是 UDP,不管是公共互联网还是一些按流量计费的国际专线,都会对 UDP 流量进行一些降级,导致高峰时段丢包率较高。因此,我们把 WireGuard 协议封装后的 UDP 报文通过 VLESS 协议转发,走 TCP + WebSocket 协议,可以使连接更稳定。

数据流传输过程

让我们详细分析数据包如何在这个系统中流动:

  1. 本地设备 → 国内服务器:

    • 你的设备上运行 WireGuard 客户端,创建一个虚拟网络接口(通常名为 wg0
    • 当应用程序发出网络请求时,操作系统根据路由表将目标流量导向 WireGuard 虚拟接口
    • WireGuard 客户端对数据包进行加密,然后通过 UDP 协议发送到国内服务器的指定端口(本文例子中使用 42371 端口)
    • 这一阶段使用 WireGuard 原生的 UDP 传输,适合本地到国内服务器的相对稳定的网络环境
  2. 国内服务器内部处理:

    • 国内服务器上的 Xray 通过 dokodemo-door 入站接收到 WireGuard UDP 流量
    • 接收到的 WireGuard 加密数据被 Xray 路由系统转发到 VLESS 出站
    • 这一步实现了关键的协议转换:从 UDP 到基于 TCP 的 WebSocket
  3. 国内服务器 → 美国服务器:

    • 转换后的流量通过 VLESS 协议 + WebSocket + TLS(可选)传输到美国服务器
    • WebSocket over TCP 协议可以避免 UDP 流量在传输过程中优先级较低的问题
    • 可选的 TLS 加密提供了额外的安全层,防止 WireGuard 协议头数据被中间人监听或篡改
  4. 美国服务器内部处理:

    • 美国服务器上的 Xray 通过 VLESS 入站接收到 WebSocket 流量
    • Xray 将收到的数据导向本地的 WireGuard 服务(通过 freedom 出站配置为 127.0.0.1:42371
    • WireGuard 服务解密数据包,并通过 IP 转发将流量发送到目标网站或服务
  5. 美国服务器 → 互联网/内网:

    • 解密后的数据包从美国服务器的物理网络接口发出
    • 对外部服务和公司内网来说,这些请求看起来就像是直接从美国服务器发出的

网络性能考量

这种架构下,需要关注几个性能相关因素:

  1. 延迟增加:通过国内服务器、美国服务器转发不可避免地会增加一定的网络延迟,但对于大多数应用来说这是可以接受的。
  2. 下载速度降低:由于是三层隧道,整个 TCP 连接握手过程是在客户端和美国服务器之间直接进行的,慢启动过程的 RTT 也是跨国网络延迟,这会导致下载速度相比传统的 HTTP/HTTPS 代理方式降低。
  3. MTU 设置:由于多层封装,需要适当调低 MTU 值(如本文中建议的 1280),避免因 IP 分片导致的性能问题。
  4. 国内网站访问慢:由于是三层隧道,如果需要访问国内网站,就需要从美国绕一圈再访问回来,会变慢很多。

尽管存在这些开销,但这种架构带来的稳定性、兼容性和便利性优势通常更为重要,特别是在企业环境中,能够避免大量的代理配置工作,节省宝贵的开发和运维时间。

准备工作

你需要的资源

  1. 美国服务器:一台有公网 IP 的美国服务器
  2. 国内服务器:一台有公网 IP 的国内服务器
  3. 域名(可选):如果使用 CloudFlare 中转,需要一个域名

服务器要求

  • 操作系统:推荐使用 Ubuntu 22.04
  • 网络:需要有公网 IP

安装必要软件

以下命令请在每台服务器上运行:

1
2
3
4
5
6
7
8
9
10
11
# 更新系统
sudo apt update && sudo apt upgrade -y

# 安装基本工具
sudo apt install -y curl wget git unzip net-tools

# 安装 WireGuard
sudo apt install -y wireguard

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

UUID 生成及管理

在配置 Xray 时需要使用 UUID 作为客户端标识。

方法一:使用 Linux 系统自带工具

1
cat /proc/sys/kernel/random/uuid

方法二:使用 Python

1
python3 -c "import uuid; print(uuid.uuid4())"

详细配置步骤

第一步:配置美国服务器

1.1 生成 WireGuard 密钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 创建WireGuard配置目录
sudo mkdir -p /etc/wireguard
cd /etc/wireguard

# 生成密钥对
wg genkey | tee server_private.key | wg pubkey > server_public.key
wg genpsk > preshared.key

# 查看生成的密钥(记录下来)
echo "服务器私钥: $(cat server_private.key)"
echo "服务器公钥: $(cat server_public.key)"
echo "预共享密钥: $(cat preshared.key)"

# 生成客户端密钥对
wg genkey | tee client_private.key | wg pubkey > client_public.key

# 查看生成的密钥
echo "客户端私钥: $(cat client_private.key)"
echo "客户端公钥: $(cat client_public.key)"

1.2 创建 WireGuard 配置文件

1
sudo nano /etc/wireguard/wg0.conf

输入以下内容(替换相应的密钥):

1
2
3
4
5
6
7
8
9
10
[Interface]
Address = 10.10.20.1/16
ListenPort = 42371
PrivateKey = <server-private-key>
MTU = 1280

[Peer]
PublicKey = <client-public-key>
PresharedKey = <preshared-key>
AllowedIPs = 10.10.0.0/24

1.3 配置Xray

1
sudo nano /usr/local/etc/xray/config.json

输入以下内容(替换 UUID 为前面生成的值):

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
{
"log": {
"access": "/var/log/xray/access.log",
"error": "/var/log/xray/error.log",
"loglevel": "debug"
},
"inbounds": [
{
"tag": "wireguard-vless-in",
"port": 10444,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "<random-uuid>",
"level": 0
}
],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/wss"
}
}
}
],
"outbounds": [
{
"tag": "wireguard-out",
"protocol": "freedom",
"settings": {
"redirect": "127.0.0.1:42371"
}
}
],
"routing": {
"rules": [
{
"type": "field",
"inboundTag": ["wireguard-vless-in"],
"outboundTag": "wireguard-out"
}
]
}
}

1.4 启动服务

1
2
3
4
5
6
7
8
9
10
11
# 启动WireGuard
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

# 启动Xray
sudo systemctl enable xray
sudo systemctl restart xray

# 检查状态
sudo systemctl status wg-quick@wg0
sudo systemctl status xray

1.5 开启 IP 转发

1
2
3
4
5
6
7
8
# 编辑系统配置文件
sudo nano /etc/sysctl.conf

# 添加或修改以下行
net.ipv4.ip_forward = 1

# 应用更改
sudo sysctl -p

1.6 配置 NAT

IP 转发已经开启,但我们还需要配置 NAT 以使来自 WireGuard 网络的流量能够转发到互联网。这一步是 非常关键 的,否则隧道将无法正常工作。

1
2
3
4
5
# 添加 iptables NAT 规则
sudo iptables -t nat -A POSTROUTING -s 10.10.0.0/16 -o eth0 -j MASQUERADE

# 查看添加的规则
sudo iptables -t nat -L -v

注意:上面的命令中,eth0 是美国服务器的网络接口名称,你需要根据实际情况替换它。可以使用 ip addrifconfig 命令查看你服务器的网络接口名称。

如果你的服务器重启后,iptables 规则会丢失,可以使用以下方法使 NAT 规则持久化:

1
2
3
4
5
# 安装 iptables-persistent
sudo apt install -y iptables-persistent

# 保存当前 iptables 规则
sudo netfilter-persistent save

如果你使用的是 nftables 而不是 iptables(Ubuntu 22.04 默认使用 nftables),则可以使用以下命令:

1
2
3
4
5
6
7
8
# 添加 nftables NAT 规则
sudo nft add table nat
sudo nft 'add chain nat postrouting { type nat hook postrouting priority 100; }'
sudo nft add rule nat postrouting ip saddr 10.10.0.0/16 oif eth0 masquerade

# 保存 nftables 规则
sudo nft list ruleset > /etc/nftables.conf
sudo systemctl enable nftables

第二步:配置国内服务器

2.1 创建V2Ray/Xray配置文件

1
sudo nano /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
72
73
74
75
76
77
78
79
80
81
82
83
{
"log" : {
"access": "/var/log/xray/access.log",
"error": "/var/log/xray/error.log",
"loglevel": "debug"
},
"inbounds": [
{
"listen": "0.0.0.0",
"port": 42371,
"protocol": "dokodemo-door",
"settings": {
"address": "127.0.0.1",
"port": 42371,
"network": "udp"
},
"tag": "wireguard-in"
}
],
"outbounds": [
{
"tag": "wireguard-vless-direct-out",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "<us-server-ip>",
"port": 10444,
"users": [
{
"id": "<random-uuid>",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/wss"
}
}
},
{
"tag": "wireguard-vless-proxy-out",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "<cloudflare-reverse-proxy-domain-name>",
"port": 443,
"users": [
{
"id": "<random-uuid>",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"wsSettings": {
"path": "/wss"
}
}
}
],
"routing": {
"strategy": "rules",
"rules": [
{
"type": "field",
"inboundTag": [
"wireguard-in"
],
"outboundTag": "wireguard-vless-direct-out"
}
]
}
}

注意:如果直连不稳定,可以使用 CloudFlare 做中转,将 outboundTag 改为 “wireguard-vless-proxy-out”

2.2 启动服务

1
2
3
4
5
6
# 启动Xray
sudo systemctl enable xray
sudo systemctl restart xray

# 检查状态
sudo systemctl status xray

第三步:配置 CloudFlare 中转(可选)

如果国内直连美国服务器不稳定,可以使用 CloudFlare 作为中转。

3.1 注册 CloudFlare 账号并添加域名

  1. 注册一个 CloudFlare 账号
  2. 添加你的域名到 CloudFlare
  3. 将域名的 DNS 服务器修改为 CloudFlare 提供的服务器

3.2 创建 DNS 记录

  1. 在 CloudFlare 控制面板选择你的域名
  2. 点击 “DNS” 选项卡
  3. 添加一条A记录,指向美国服务器IP地址
    • 类型: A
    • 名称: 子域名(例如:tunnel)
    • 内容: 美国服务器 IP
    • 代理状态: 已代理(云朵图标为橙色)

3.3 配置 SSL/TLS 设置

  1. 在 CloudFlare 控制面板中,进入 “SSL/TLS” 选项卡
  2. 将 SSL/TLS 加密模式设置为 “完全” 或 “完全(严格)”

第四步:生成 WireGuard 客户端配置

创建一个名为 wg0-client.conf 的文件:

1
2
3
4
5
6
7
8
9
10
11
12
[Interface]
PrivateKey = <client-private-key>
Address = 10.10.0.1/16
DNS = 8.8.8.8, 8.8.4.4
MTU = 1280

[Peer]
PublicKey = <server-public-key>
PresharedKey = <preshared-key>
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = <domestic-ip>:<domestic-port>
PersistentKeepalive = 25

注意AllowedIPs = 0.0.0.0/0, ::/0 表示所有流量都会通过WireGuard隧道

第五步:在不同设备上使用

5.1 Windows 客户端

  1. 下载 WireGuard 官方客户端
  2. 安装并启动 WireGuard
  3. 点击 “添加隧道” → “从文件导入”,选择刚才创建的配置文件
  4. 点击”激活”按钮启用隧道

5.2 macOS 客户端

  1. 从 App Store 下载WireGuard客户端
  2. 打开 WireGuard,点击 “+”,选择 “导入从文件或归档”
  3. 选择配置文件,点击 “添加”
  4. 点击开关启用隧道

5.3 iOS 客户端

  1. 从 App Store 下载 WireGuard 客户端
  2. 打开 WireGuard,点击”+”,选择”创建自二维码”或”创建自文件”
  3. 导入配置后,点击开关启用隧道

5.4 Android客户端

  1. 从 Google Play 商店下载 WireGuard 客户端
  2. 打开 WireGuard,点击 “+”,选择 “从文件导入”
  3. 选择配置文件,点击 “导入”
  4. 点击开关启用隧道

5.5 Linux客户端

1
2
3
4
5
6
7
8
9
# 安装WireGuard
sudo apt install wireguard

# 复制配置文件
sudo cp wg0-client.conf /etc/wireguard/wg0.conf

# 启用隧道
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

5.6 OpenWRT 路由器

  1. 登录路由器管理界面
  2. 安装 WireGuard 包:
    • 系统 → 软件包 → 搜索 “wireguard” → 安装
  3. 网络 → 接口 → 添加新接口
    • 名称:WireGuard
    • 协议:WireGuard VPN
    • 复制配置文件内容到相应字段
  4. 防火墙设置:
    • 防火墙 → 常规设置 → 允许转发
    • 添加 WireGuard 接口到WAN区域

验证与测试

连接测试

  1. 连接 WireGuard 后,ping 美国服务器内网IP:

    1
    ping 10.10.20.1
  2. 访问 ip.gsip.sb 查看你当前的 IP 地址,应该显示为美国IP

排障指南

连接问题

  1. 无法连接到国内服务器

    • 检查防火墙是否开放 42371 端口(UDP)
    • 检查 Xray 服务是否正常运行
  2. 能连接国内服务器但无法上网

    • 检查防火墙是否开放 10444 端口(TCP)
    • 检查美国服务器 WireGuard 配置
    • 检查 Xray 服务是否正常运行
    • 检查 IP 转发是否已启用
  3. 连接不稳定

    • 尝试使用 CloudFlare 作为中转
    • 检查MTU设置,可以尝试调低(例如1200)

查看日志

  • WireGuard日志:sudo journalctl -u wg-quick@wg0
  • Xray日志:sudo cat /var/log/xray/error.log

进阶性能优化

  1. BBR加速
1
2
3
4
5
6
7
8
9
10
11
12
# 编辑sysctl配置
sudo nano /etc/sysctl.conf

# 添加以下内容
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr

# 应用设置
sudo sysctl -p

# 检查是否启用
sudo sysctl net.ipv4.tcp_congestion_control
  1. 调整MTU值

如果网络连接不稳定,可以尝试不同的MTU值(1200-1500之间)。

策略路由:让国内网站直连访问

上面提到,使用全局隧道会导致访问国内网站变慢。这一节我们将讲解如何配置策略路由,使国内网站走直连,国外网站走隧道。

准备中国 IP 地址段列表

首先,我们需要获取中国 IP 地址段列表。

方案一:使用开源项目

1
2
3
4
5
# 创建存放中国 IP 段的目录
sudo mkdir -p /etc/wireguard/chnroute

# 下载中国 IP 段列表
sudo curl -o /etc/wireguard/chnroute/chnroute.txt https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt

方案二:使用 APNIC 官方数据

1
2
3
4
5
# 创建存放中国 IP 段的目录
sudo mkdir -p /etc/wireguard/chnroute

# 使用 APNIC 官方数据
sudo bash -c "curl 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | grep ipv4 | grep CN | awk -F\| '{ printf(\"%s/%d\\n\", \$4, 32-log(\$5)/log(2)) }' > /etc/wireguard/chnroute/chnroute.txt"

Linux 系统上的配置

1. 创建路由脚本(Linux 系统)

创建 WireGuard up/down 脚本,当 WireGuard 连接建立或断开时自动执行:

1
sudo nano /etc/wireguard/wg-up.sh

输入以下内容:

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
#!/bin/bash

# 定义路由表 ID (用一个不常用的 ID,避免冲突)
TABLE_ID=200
# IP规则优先级
RULE_PRIO=100

# 创建新的路由表
ip rule add prio $RULE_PRIO table $TABLE_ID

# 添加默认路由到 WireGuard 接口
ip route add default dev wg0 table $TABLE_ID

# 将国内IP段添加到主路由表,使其走默认网关
if [ -f "/etc/wireguard/chnroute/chnroute.txt" ]; then
while read -r line; do
# 排除空行和注释行
[[ "$line" == "" || "$line" == \#* ]] && continue
# 添加路由规则,让中国IP走默认网关
ip route add $line via $(ip route | grep default | awk '{print $3}') dev $(ip route | grep default | awk '{print $5}')
done < "/etc/wireguard/chnroute/chnroute.txt"
echo "中国 IP 路由规则已添加"
else
echo "中国 IP 列表文件不存在"
fi

# 添加常见国内 DNS 服务器的路由
for dns in 114.114.114.114 114.114.115.115 223.5.5.5 223.6.6.6 180.76.76.76 119.29.29.29; do
ip route add $dns via $(ip route | grep default | awk '{print $3}') dev $(ip route | grep default | awk '{print $5}')
done

echo "WireGuard 策略路由配置完成"

创建 down 脚本以在连接断开时清理路由规则:

1
sudo nano /etc/wireguard/wg-down.sh

输入以下内容:

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
#!/bin/bash

# 定义与 g-up.sh 相同的参数
TABLE_ID=200
RULE_PRIO=100

# 删除路由表规则
ip rule del prio $RULE_PRIO table $TABLE_ID 2>/dev/null

# 删除所有中国 IP 路由规则
if [ -f "/etc/wireguard/chnroute/chnroute.txt" ]; then
while read -r line; do
# 排除空行和注释行
[[ "$line" == "" || "$line" == \#* ]] && continue
# 删除路由规则
ip route del $line 2>/dev/null
done < "/etc/wireguard/chnroute/chnroute.txt"
echo "中国IP路由规则已删除"
fi

# 删除DNS服务器的路由
for dns in 114.114.114.114 114.114.115.115 223.5.5.5 223.6.6.6 180.76.76.76 119.29.29.29; do
ip route del $dns 2>/dev/null
done

echo "WireGuard 策略路由已清理"

设置脚本执行权限:

1
2
sudo chmod +x /etc/wireguard/wg-up.sh
sudo chmod +x /etc/wireguard/wg-down.sh

2. 配置 WireGuard 使用脚本

修改 WireGuard 配置文件,添加 PostUp 和 PostDown 钩子:

1
sudo nano /etc/wireguard/wg0.conf

[Interface] 部分添加:

1
2
PostUp = /etc/wireguard/wg-up.sh
PostDown = /etc/wireguard/wg-down.sh

完整的配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Interface]
PrivateKey = <client-private-key>
Address = 10.10.0.1/16
DNS = 8.8.8.8, 8.8.4.4
MTU = 1280
PostUp = /etc/wireguard/wg-up.sh
PostDown = /etc/wireguard/wg-down.sh

[Peer]
PublicKey = <server-public-key>
PresharedKey = <preshared-key>
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = <domestic-ip>:<domestic-port>
PersistentKeepalive = 25

3. 重启 WireGuard 服务

1
sudo systemctl restart wg-quick@wg0

4. 验证策略路由是否生效

测试访问国内网站是否走直连:

1
2
3
4
5
6
7
8
# 追踪到百度的路由
traceroute www.baidu.com

# 查看当前路由表
ip route show

# 查看策略路由规则
ip rule list

Mac 系统上的配置

macOS 用户可以使用以下脚本实现类似功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash

# 定义变量
WIREGUARD_INTERFACE="utun3" # 根据实际情况调整WireGuard接口名称
DEFAULT_INTERFACE=$(route -n get default | grep interface | awk '{print $2}')
DEFAULT_GATEWAY=$(route -n get default | grep gateway | awk '{print $2}')
CHNROUTE_FILE="$HOME/chnroute.txt"

# 下载中国IP列表
curl -s 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > "$CHNROUTE_FILE"

# 添加中国IP路由规则
while read -r line; do
sudo route add -net "$line" "$DEFAULT_GATEWAY"
done < "$CHNROUTE_FILE"

# 添加常用中国DNS服务器路由
for dns in 114.114.114.114 114.114.115.115 223.5.5.5 223.6.6.6; do
sudo route add "$dns" "$DEFAULT_GATEWAY"
done

echo "macOS策略路由配置完成"

将此脚本保存为文件(如 ~/wireguard-route.sh),并在连接 WireGuard 后手动执行:

1
2
chmod +x ~/wireguard-route.sh
sudo ~/wireguard-route.sh

常见问题与解决方案

  1. 脚本执行失败

    • 检查脚本是否有可执行权限
    • 确认脚本中的接口名称是否正确
  2. 路由未生效

    • 使用 ip route show 检查路由表
    • 确认中国 IP 列表文件存在且内容正确
  3. 国内网站仍然很慢

    • 检查 DNS 设置,可能 DNS 解析走了国外服务器
    • 可以使用国内防污染 DNS
  4. 策略路由后无法上网

    • 检查默认路由是否正确
    • 确认 WireGuard 配置中的 AllowedIPs 设置

通过以上配置,你的设备将实现智能分流:国内网站走直连,国外网站通过三层隧道访问,既保证了访问国外服务的稳定性,又不影响国内网站的访问速度。

添加多个客户端

重要:每个客户端配置仅限单一设备使用

需要注意的是,每个 WireGuard 客户端配置只能同时被一个设备使用。因此,每添加一个新设备,都需要生成新的客户端配置。

步骤:添加新的客户端

1. 在美国服务器上生成新客户端密钥

1
2
3
4
5
6
7
8
cd /etc/wireguard

# 生成新客户端密钥对
wg genkey | tee client2_private.key | wg pubkey > client2_public.key

# 查看生成的密钥
echo "新客户端私钥: $(cat client2_private.key)"
echo "新客户端公钥: $(cat client2_public.key)"

2. 修改美国服务器上的 WireGuard 配置

编辑 /etc/wireguard/wg0.conf 文件,在末尾添加新的 Peer 部分:

1
sudo nano /etc/wireguard/wg0.conf

添加新的 Peer 部分:

1
2
3
4
5
6
7
8
9
10
11
# 第一个客户端(原有配置)
[Peer]
PublicKey = <client-public-key>
PresharedKey = <preshared-key>
AllowedIPs = 10.10.0.0/24

# 第二个客户端(新添加)
[Peer]
PublicKey = <client2-public-key>
PresharedKey = <preshared-key>
AllowedIPs = 10.10.1.0/24

注意

  • 每个客户端需要使用不同的 IP 地址范围(AllowedIPs)
  • 你也可以为每个新客户端生成新的预共享密钥(PresharedKey)以提高安全性

3. 重新加载美国服务器上的 WireGuard 配置

1
2
3
4
5
sudo wg-quick down wg0
sudo wg-quick up wg0

# 或者使用以下命令重新加载配置(不断开现有连接)
sudo wg syncconf wg0 <(wg-quick strip wg0)

4. 创建新的客户端配置文件

创建一个名为 wg0-client2.conf 的新文件:

1
2
3
4
5
6
7
8
9
10
11
12
[Interface]
PrivateKey = <client2-private-key>
Address = 10.10.1.1/16
DNS = 8.8.8.8, 8.8.4.4
MTU = 1280

[Peer]
PublicKey = <server-public-key>
PresharedKey = <preshared-key>
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = <domestic-ip>:<domestic-port>
PersistentKeepalive = 25

5. 将新配置分发到新设备

wg0-client2.conf 文件传输到新设备上,并按照前面提到的方法导入到相应平台的 WireGuard 客户端中。

Comments