跳到主要内容

使用wireguard搭建中继服务器实现异地组网

· 阅读需 8 分钟
JovenKing

前言

说起异地组网,之前一直在使用zerotier-planet进行搭建,使用了一段时间也挺稳定,唯一的不足就是ios平台由于系统限制没办法修改planet文件,也就没法进行组网。

网上找了一圈,看到很早就有人在官方论坛里面提过这个需求,但是官方似乎对此兴趣好像不大,没办法只能研究其他组网方式,找了一圈后最后确定下来使用wireguard搭建中继服务器进行组网,wireguard的各平台支持也都比较齐全,其功能也都满足我的需求,在此记录下组网过程。

准备工作

需要入网的设备的准备工作如下

# 安装wireguard
apt install -y wireguard
# 生成公钥私钥,也可为其他客户端生成公私钥
cd /etc/wireguard/
wg genkey | tee privatekey | wg pubkey > publickey
# 添加下面的配置到 /etc/sysctl.conf 后执行 sysctl -p 生效
net.ipv4.ip_forward = 1

搭建中继服务器

确保中继服务器有公网ip,开放端口28378。编辑/etc/wireguard/wg0.conf文件,如下配置请根据实际情况修改

[Interface]
PrivateKey = {中继服务器私钥}
# 中继服务器内网ip,10.0.1.1
Address = 10.0.1.1/24
ListenPort = 28378
# 通过`ip addr`获得主网卡名称,这里为eth0
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# 内网NAS
PublicKey = {NAS服务器公钥}
# 10.0.1.2/32 配置了NAS服务器的内网ip,10.0.1.2
# (可选)192网段的配置可选,这里配置允许其他服务访问NAS内网的网段为192.168.50.X和内网ip为192.168.1.1的服务
AllowedIPs = 10.0.1.2/32,192.168.50.0/24,192.168.1.1/32
# 保持会话的持续连接,单位秒,NAT网络依靠这个参数向中继服务器定期主动发送数据以保持连接
PersistentKeepalive = 25

[Peer]
# Win电脑
PublicKey = {Win电脑公钥}
# 内网ip,10.0.1.3
AllowedIPs = 10.0.1.3/32
PersistentKeepalive = 25

[Peer]
# iphone
PublicKey = {iphone公钥}
# 内网ip,10.0.1.100
AllowedIPs = 10.0.1.100/32
PersistentKeepalive = 25

测试配置

# 启动
wg-quick up wg0

其他的一些命令

# 关闭
wg-quick down wg0
# 测试没问题之后,配置开机启动
systemctl enable wg-quick@wg0 --now
# 查看服务状态
systemctl status wg-quick@wg0
# 查看wireguard状态
wg
# 查看配置
wg showconf wg0

NAS服务器的配置

编辑/etc/wireguard/wg0.conf文件

[Interface]
PrivateKey = {NAS服务器私钥}
Address = 10.0.1.2/24
# 通过`ip addr`获得主网卡名称,这里是enp2s0
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o enp2s0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o enp2s0 -j MASQUERADE

[Peer]
PublicKey = {中继服务器公钥}
# nas内网ip,注意这里最后面是24
AllowedIPs = 10.0.1.1/24
# 这里配置为中继服务器的ip加端口
Endpoint = x.x.x.x:28378
PersistentKeepalive = 25

使用wg-quick up wg0启动配置,ping中继服务器内网ip10.0.1.1以测试网络是否正常,确定没问题后设置为开机启动。

Windows客户端配置

安装wireguard-amd64-xxx.msi文件,启动程序,点击左下角下拉菜单,新建空隧道,配置填写如下

[Interface]
PrivateKey = {Win电脑私钥}
# win电脑内网ip
Address = 10.0.1.3/24

[Peer]
# 192.168.50.0/24、192.168.1.1/32设置网段用来访问NAS内网的服务
PublicKey = {中继服务器公钥}
AllowedIPs = 10.0.1.1/24, 192.168.50.0/24,192.168.1.1/32
# 这里配置为中继服务器的ip加端口
Endpoint = x.x.x.x:28378
PersistentKeepalive = 25

保存之后点击主界面连接,之后可以在浏览器输入内网网址192.168.50.X访问局域网服务进行测试

iPhone客户端配置

配置如下,和Win电脑配置区别不大

[Interface]
PrivateKey = {iphone私钥}
Address = 10.0.1.100/24

[Peer]
PublicKey = {中继服务器公钥}
AllowedIPs = 10.0.1.1/24, 192.168.50.0/24,192.168.1.1/32
# 这里配置为中继服务器的ip加端口
Endpoint = x.x.x.x:28378
PersistentKeepalive = 25

上面的配置可以保存到文件,在手机wireguard客户端导入,或者生成二维码扫描导入

一些优化

设置了开机启动后,默认的wg-quick服务只会在系统开机后启动一次,这样在遇到网络异常问题时机器会直接离线,因此需要修改wg-quick@.service保证服务在网络波动恢复后自动进行重连

# 编辑/lib/systemd/system/wg-quick@.service
# 修改[Service]下的配置,修改Type类型并添加重试参数
Type=simple
Restart=always
RestartSec=5
StartLimitInterval=0
#之后重新加载服务并重启
systemctl daemon-reload
systemctl restart wg-quick@wg0

update at 2024/04/15

上面的自动重连设置运行了一段时间之后发现还是存在一些问题,有时外网IP变化了,wg服务并未报错,但是也没有重连到中继服务器上,造成机器离线,这里新增一个watchdog服务进行连接保活监控,脚本参考自 Codebreaker101/watchdog.service

# 新建watchdog服务
vim /lib/systemd/system/wg-watchdog.service
# 添加下面代码到service中
[Unit]
Description=Wireguard Watchdog
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=always
RestartSec=10
ExecStart=/etc/wireguard/watchdog.sh

[Install]
WantedBy=multi-user.target
# 新建脚本
vim /etc/wireguard/watchdog.sh

# 添加下面代码到watchdog.sh中

#!/bin/bash
# TARGET_HOST 根据实际情况修改,这里是中继服务器的内网IP
TARGET_HOST='10.0.1.1' # this is your wireguard network server IP
UP=false
while true
do

count=$(ping -c 1 $TARGET_HOST | grep rtt | wc -l)
if [ $count -eq 0 ]; then
echo "$(date)" "Target host" $TARGET_HOST "unreachable, reinitiating wireguard wg0 interface!"
systemctl restart wg-quick@wg0
UP=false
else
if [ $UP = false ]; then
echo "$(date)" "Wireguard connection reestablished!"
fi
UP=true
fi
sleep 10

done

最后启动服务

systemctl daemon-reload
systemctl start wg-watchdog
systemctl enable wg-watchdog

脚本原理是每隔10秒ping一下中继服务器IP,如果ping不通则说明本机离线,检测到离线后就重启wg服务,这样就可以保证机器一直在线了

参考