通过wireguard异地组网
诉求
希望通过wireguard建设自己的虚拟网络,完成节点之间的互访与路由转发。
Cloud ┌─────────┐ public:1.2.3.4
┌─────────────►│ Relay │ wg:10.0.0.1
│ └───────▲─┘
│ │
│ │
┌──────────┼────────────────┐ │
│ Home │ │ │
│ ┌──┼──┐ 192.168.1.7 │ │
│ │ NUC │ wg:10.0.0.2 │ │
│ └──┬──┘ │ │
│ │ │ │
│ ┌──▼───┐ 192.168.1.8│ ┌───┴────┐wg:10.0.0.3
│ │Server│ │ │ Laptop │
│ └──────┘ │ └────────┘
└───────────────────────────┘ Outside
在家庭终端NUC,公网云服务器Relay和个人电脑Laptop都安装wireguard客户端并加入虚拟网络。
实现在server不安装任何软件的前提下通过laptop对家庭server的访问。
实现
前提:公网服务器Relay必须有公网地址且能被NUC和Laptop访问。
公网服务器Relay
作为中继节点,公网地址为1.2.3.4分配虚拟地址10.0.0.1
sudo apt install wireguard
# 生成公私钥
wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey
# 复制privatekey备用
sudo vim /etc/wireguard/wg0.conf
配置内容,interface是虚拟网络地址,其中eth0要换成自己的出口网卡
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = YOUR_SERVER_PRIVATE_KEY
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
打开ip4转发(重要!)
sudo vi /etc/sysctl.conf
# 取消注释以下行
net.ipv4.ip_forward=1
# 保存并应用
sudo sysctl -p
# 防火墙放行udp端口51280(如果启用了ufw)
sudo ufw allow 51820/udp
本地配置生效
# 限制权限
sudo chmod 600 /etc/wireguard/*
# 启动接口
sudo wg-quick up wg0
# 检查接口状态和配置
sudo wg show wg0
# 验证接口状态
ip a show wg0
# 开机自启动
sudo systemctl enable wg-quick@wg0
到此公网服务器Relay设置完成
家庭跳板机NUC
作为跳板节点内网地址192.168.1.7分配虚拟地址10.0.0.2
类似Relay安装wireguard并开启ipv4转发,生成公钥和私钥填写wg0.conf
注意Peer部分的配置差异,需要填入公网Relay服务器的信息
[Interface]
PrivateKey = YOUR_CLIENT_PRIVATE_KEY
Address = 10.0.0.2/24
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = YOUR_SERVER_PUBLIC_KEY
Endpoint = 1.2.3.4:51820
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 30
外网终端Laptop
和NUC设置相同,分配虚拟地址10.0.0.3并对Peer Relay添加192.168.1.0/24的路由。
[Interface]
PrivateKey = YOUR_CLIENT_PRIVATE_KEY
Address = 10.0.0.3/24
[Peer]
PublicKey = YOUR_SERVER_PUBLIC_KEY
Endpoint = 1.2.3.4:51820
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24
PersistentKeepalive = 30
将Peer添加到Relay
为实现双向互访,还需要在Relay放行其他Peer
sudo wg set wg0 peer ${NUC公钥} allowed-ips 10.0.0.2/32,192.168.1.0/24
sudo wg set wg0 peer ${Laptop公钥} allowed-ips 10.0.0.3/32
现在Laptop可以直接ping通192.168.1.8
查疑
关于AllowedIPs的理解
对于客户端:修改当前设备的路由表,将AllowedIPs命中的流量指向wg0网卡。
对于中继器:告诉wg0命中AllowedIPs的流量从当前Peer流出。
能够ping通无法ssh
ping通证明路由没问题,使用telnet命令排查laptop能够收到来自server的握手消息
$ telnet 192.168.1.8 22
Trying 192.168.1.8...
Connected to 192.168.1.8.
Escape character is '^]'.
SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.5
Reddit指出ssh卡死可能是wg0的MTU设置太大,Relay使用ip addr | grep mtu
查看已有网卡设置
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
2: enp1s0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
18: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 65456 qdisc noqueue state UNKNOWN group default qlen 1000
在wg0.conf
修改为MTU = 1420后问题解决,注意要先断开wg否则配置修改被覆盖
sudo wg-quick down wg0
sudo vi /etc/wireguard/wg0.conf
# [Interface]
# Address = 10.0.0.1/24
# MTU = 1420
sudo wg-quick up wg0
参考
使用 WireGuard 组网实现内网穿透 | varkai
Only SSH not working over Wireguard, everything else is : r/WireGuard