注意⚠️ 本文存在一些疏漏,请不要照搬。有空我会逐个修复。
此外,我不再推荐使用第三方图形化的sing-box客户端,我已经不止一次遇到图形上的性能问题。
以下为文章:
这次折腾,是为了能够在singbox上使用WireGuard,为指定程序走WireGuard出站,实现远程异地组网。
以前这比较好写配置文件,但是随着singbox1.11.0诞生,配置文件的很多字段发生了更改,基本上大改了,之前有的字段已经废弃了,于是本文记录踩坑过程(~o ̄3 ̄)~
预备知识
假设你了解局域网,假设你知道手机热点大概工作原理,假设你基本了解网络拓扑,假设你基本了解云服务器,假设你基本了解Linux。
需求:
- 可以随时随地远程连接WireGuard局域网里的设备
- 可以随时随地访问家里的局域网里的设备
- 拥有良好远程串流体验
要达到的效果
-
家中任何一台电脑,运行SingBox,就可以通过这台机器接入WireGuard网络。
实现出门在外随时随地连接到家里的设备,也可以与家里的设备串流。
目前环境
设备: ECS服务器:Ubuntu 24.04.1 LTS PC:Windows 11 安装了 GUI.for.SingBox 平板:HUAWEI Matepad Pro 11 冤种2022款 安装了WireGuard客户端 手机:HUAWEI P30 Pro 安装了WireGuard客户端
模拟的网络布局
这里用Cisco Packet Tracer连几根线意思一下,示意图。

| 家中网络 | WireGuard网络 | 远程网络 |
|---|---|---|
| 192.168.6.0/24 | 10.1.0.0/24 | 叽叽咕咕我不知道是啥捏 |
开始战斗了⚔️
服务器里的设置:
首先你要有一台公网IP的云服务器。
我选择的是一年99元阿里云ECS,不需要域名,省去备案的麻烦。
安装WireGuard和ufw
apt update
apt install -y wireguard ufw
ufw allow 22/tcp
ufw allow 22/udp
ufw allow 51820/tcp
ufw allow 51820/udp
ufw enable
sysctl -w net.ipv4.ip_forward=1生成密钥对:
cd /etc/wireguard
wg genkey | tee gw-privatekey | wg pubkey > gw-publickey
wg genkey | tee mypc-privatekey | wg pubkey > mypc-publickey
wg genkey | tee matepad-privatekey | wg pubkey > matepad-publickey生成云服务器上的配置:
cat > wg0.conf <<EOF
[Interface]
ListenPort = 51820 # 客户端连过来填写的端口,安全组的tcp和udp都要放行
Address = 10.1.0.1/24 #wg之前通信组网的内网ip和段
PrivateKey = $(cat gw-privatekey) # 使用 shell 读取gateway的私钥到这里
PostUp = iptables -I FORWARD -s 10.1.0.0/24 -i wg0 -d 10.1.0.0/24 -j ACCEPT
PostUp = iptables -I FORWARD -s 10.1.0.0/24 -i wg0 -d 192.168.6.0/24 -j ACCEPT
PostUp = iptables -I FORWARD -s 192.168.6.0/24 -i wg0 -d 10.1.0.0/24 -j ACCEPT
PostDown = iptables -D FORWARD -s 10.1.0.0/24 -i wg0 -d 10.1.0.0/24 -j ACCEPT
PostDown = iptables -D FORWARD -s 10.1.0.0/24 -i wg0 -d 192.168.6.0/24 -j ACCEPT
PostDown = iptables -D FORWARD -s 192.168.6.0/24 -i wg0 -d 10.1.0.0/24 -j ACCEPT
# mypc
[Peer]
PublicKey = $(cat pc-publickey)
AllowedIPs = 10.1.0.2/32,192.168.6.0/24
# matepad
[Peer]
PublicKey = $(cat home-pc-publickey)
AllowedIPs = 10.1.0.3/32
EOF家中电脑的配置:
cat > mypc.conf <<EOF
[Interface]
PrivateKey = $(cat mypc-privatekey)
Address = 10.1.0.2/24 #wg之前通信组网的内网ip和段,主机位每个得不一样
[Peer]
PublicKey = $(cat gw-publickey) # gateway的公钥
AllowedIPs = 10.1.0.0/24, 192.168.6.0/24
Endpoint = $(curl -s ip.sb):51820 #gateway 公网ip和端口
PersistentKeepalive = 30 # 心跳时间
EOF平板的配置:
cat > matepad.conf <<EOF
[Interface]
PrivateKey = $(cat matepad-privatekey)
Address = 10.1.0.3/24 #wg之前通信组网的内网ip和段,主机位每个得不一样
[Peer]
PublicKey = $(cat gw-publickey) # gateway的公钥
AllowedIPs = 10.1.0.0/24
Endpoint = $(curl -s ip.sb):51820 # gateway 公网ip和端口
PersistentKeepalive = 10 # 心跳时间
EOF在云服务器上启动WireGuard服务( ̄︶ ̄)
wg-quick up wg0
# WireGuard会默认读取 /etc/wireguard/$name.conf 作为启动的配置文件
# 若要手动指定配置文件启动WireGuard: wg-quick up /etc/wireguard/wg0.conf
wg-quick down wg0如果要查看组网状态,输入 wg 回车即可
WireGuard半自动搭建脚本:
SingBox配置:
我的老天爷,这玩意儿的配置折腾了好久好久,在SingBox里配置WireGuard总是出现问题。
结果是需要为endpoints里加入detour字段,设置endpoints的出站,但他文档里没写哇。
(╬▔皿▔)╯!!!!!!!
因此需要在SingBox配置里加入endpoints的部分:
{
"endpoints": [
{
"type": "wireguard",
"tag": "wg-ep",
"system": false,
"name": "wg0",
"mtu": 1408,
"detour": "🎯 全球直连",
"address": [
"10.1.0.2/32"
],
"private_key": "私钥",
"peers": [
{
"address": "47.119.127.104",
"port": 51820,
"public_key": "公钥",
"allowed_ips": [
"10.1.0.0/24","192.168.6.0/24"
],
"persistent_keepalive_interval": 30,
"reserved": [ 0, 0, 0 ]
}
]
}
]
}整个配置的结构示意:
注意哦⚠️,这里跟以前不一样了,WireGuard配置不需要写在outbounds里了,而是单独拿出来写在了endpoints里。
{
"log": {},
"dns": {},
"ntp": {},
"endpoints": [],//在这里插入配置
"inbounds": [],
"outbounds": [],
"route": {},//在这里加入路由
"experimental": {}
}针对几个远程串流的软件,路由规则还需要加上:
"process_name": [
"parsecd.exe",
"pservice.exe",
"mstsc.exe",
"sunshine.exe"
],
"outbound": "wg-ep"这是我不知道从哪里抄来,然后简单改改的,单个可以启动的SingBox配置文件:
{
"log": {
"disabled": false,
"level": "info"
},
"dns": {
"servers": [
{
"address": "udp://223.6.6.6"
}
]
},
"inbounds": [
{
"type": "tun",
"address": [
"172.18.0.1/30"
],
"auto_route": true,
"route_address": [
"10.1.0.0/24"
],
"route_exclude_address": [
"47.119.127.104/32"
],
"stack": "gvisor"
}
],
"endpoints": [
{
"type": "wireguard",
"tag": "out-proxy",
"system": false,
"name": "wg0",
"mtu": 1408,
"detour": "out-direct",
"address": [
"10.1.0.2/32"
],
"private_key": "私钥",
"peers": [
{
"address": "47.119.127.104",
"port": 51820,
"public_key": "公钥",
"allowed_ips": [
"0.0.0.0/0"
],
"persistent_keepalive_interval": 10,
"reserved": [ 0, 0, 0 ]
}
]
}
],
"outbounds": [
{
"type": "direct",
"tag": "out-direct"
}
],
"route": {
"rules": [
{
"type": "logical",
"mode": "and",
"rules": [
{
"process_name": [
"parsecd.exe",
"pservice.exe",
"mstsc.exe",
"cmd.exe"
], "ip_cidr": [
"10.1.0.0/24"
]
}
],
"outbound": "out-proxy"
}
],
"auto_detect_interface": true
}
}针对GUI.for.SingBox所做的设置:
在配置里的【混入和脚本】所做的设置:
混入设置:
{
"endpoints": [
{
"type": "wireguard",
"tag": "wg-ep",
"system": false,
"name": "wg0",
"mtu": 1408,
"detour": "🎯 全球直连", //1.12.0-beta已经不在需要,这个参数更像是用来掩盖问题的
"address": [
"10.1.0.2/32"
],
"private_key": "私钥",
"peers": [
{
"address": "47.119.127.104",
"port": 51820,
"public_key": "公钥",
"allowed_ips": [
"10.1.0.0/24","192.168.6.0/24"
],
"persistent_keepalive_interval": 30,
"reserved": [ 0, 0, 0 ]
}
]
}
]
}脚本操作:
const onGenerate = async (config) => {
config.inbounds.forEach((inbound) => {
if (true) {
if (inbound.route_address) {
inbound.route_exclude_address = [
"47.119.127.104/32",
];
}
}
});
config.route.rules.push({
"process_name": [
"parsecd.exe",
"pservice.exe",
"mstsc.exe",
"sunshine.exe"
], //"ip_cidr": [
//"10.1.0.0/24"
//],
"outbound": "wg-ep"
});
return config;
};真是一场酣畅淋漓的战斗⚔️💦
经过测试,如果需要访问家里局域网的设备,需要在云服务器配置里的“allowed_ips”,加上局域网的网络,同时在局域网里的设备(任意一台)的“allowed_ips”也要加上局域网的网络。也就说这台设备是是内网与外部网络的互访的桥梁。
如果没有加入局域网的网络,Sunshine串流会失败,暂未找到具体的原因。其他远程访问方式正常(微软远程桌面,Todesk,Parsec)
原因已经找到:在sing-box中需要加入路由才可以正常访问。
示例如下:
{
"action": "route",
"ip_cidr": "10.66.66.0/24",
"outbound": "wg-ep"
},如果加入了局域网的网络,一切正常,Sunshine可以正常串流。
目前确定不是Windows防火墙的问题
不是云服务防火墙的问题(100%确定)
参考:
https://zhangguanzhang.github.io/2020/08/05/wireguard-for-personal/#/centos7