Wireguard构建局域网NAT访问

2021-01-24

通过wireguard构建局域网并安全地和家中的unraid等相关内网服务器进行NAT访问

Wireguard构建局域网NAT访问

最近在准备春节回老家后怎么访问城市家中的unraid等内网服务,比如smb文件共享等。光frp等内网穿透工具显然是不够的,而且有一定的安全风险,于是就想到了近几年刚出的wireguard。据说这个东西受到了linus的大力表扬,不仅是因为其核心代码非常简洁,且性能也十分出色,远超目前其他几个VPN软件,同时还保证了安全性和配置简易性。当然对于初次配置的我来说这个配置并不简单,断断续续折腾了几天才彻底明白,这里简单记录下,也算是方便自己方便他人。

环境

首先需要说明下使用需求:目前家里有一台unraid,提供了Nextcloud和smb等内网文件分享服务,通过内网ip:端口号访问Nextcloud(如http://192.168.50.166:12345),smb则在Windows或macOS的网络里直接访问,同时有一台公网服务器gateway。

得益于wireguard中没有client/server的概念,某个NAT中的某台机器与gateway主机建立连接,即可实现共享这台机器的整个NAT内的网络资源给wireguard网络。

设备网络信息:

NAT-A
unraid - 192.168.50.166
unraid - ubuntu20 - 192.168.50.88
gateway
Server - 11.21.31.41 (43155端口tcp/udp开放)
NAT-B
desktop - 移动网络或其他网络

一般情况我们家里的网是没有公网ip的,这时就需要借助一台公网服务器来帮助我们远程访问家中的服务。我的目标就是在老家的时候,NAT-B用移动网络通过wireguard连接公网Server就可以访问到NAT-A中的所有服务。即NAT-B => gateway => NAT-A。这样做连浏览器中的收藏的网址都不用改。已知目标,那么废话不多说,直接开始配置。

配置

安装wireguard就不多说了,参考文章末尾的引用吧。

如果你和我一样用的是unraid,非常建议你在unraid通过虚拟机安装ubuntu20(br0网卡也就是unraid的主网卡),对程序员来说非常友好。

Server - gateway:

# 开启ipv4流量转发
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

wg0.conf:

[Interface]
Address = 5.5.5.1/24
ListenPort = 43155
PrivateKey = {Server_PrivateKey}
# 通过`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]
PublicKey = {NAT-A_PublicKey}
# 下面非常重要,相当于是添加路由表,在启动wireguard的时候也能看到
AllowedIPs = 5.5.5.2/32, 192.168.50.0/24

[Peer]
PublicKey = {NAT-B_PublicKey}
AllowedIPs = 5.5.5.3/32

unraid - ubuntu20 (NAT-A):

# 开启ipv4流量转发
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

wg0.conf:

[Interface]
PrivateKey = {NAT-A_PrivateKey}
Address = 5.5.5.2/24
# 通过`ip addr`获得主网卡名称,unraid的虚拟机可能为enp1s0
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o enp1s0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o enp1s0 -j MASQUERADE

[Peer]
PublicKey = {Server_PublicKey}
AllowedIPs = 5.5.5.0/24
Endpoint = {Server_ip}:43155
PersistentKeepalive = 15

desktop - windows (NAT-B):

wg0.conf:

[Interface]
PrivateKey = {NAT-A_PrivateKey}
Address = 5.5.5.3/24

[Peer]
PublicKey = {Server_PublicKey}
# 下面的路由非常重要,不然系统不知道这个ip要从那个网卡走
AllowedIPs = 5.5.5.0/24, 192.168.50.0/24
Endpoint = {Server_ip}:43155
PersistentKeepalive = 15

通过上面的配置就基本实现了Server访问NAT-A,同时NAT-B也能访问NAT-A。

如果你要NAT-A能反过来访问NAT-B,则需要知道NAT-B的NAT网段(如10.10.10.1/24),然后在Server-Peer-AllowedIPs后加一个10.10.10.0/24,就可以了。配置完成记得要保存并重启wireguard:

wg-quick down wg0 && wg-quick up wg0

当然也可以用systemctl命令来启动或管理:

systemctl start/stop/enable wg-quick@wg0

配置完毕后你就可以现在Server上ping你的NAT-A上的服务了,例如先ping 5.5.5.2 -c4,最重要的是ping 192.168.50.1 -c4能够通,如果这里成功了,那么以后其他任何机器再加入到这个wireguard网络中都可以访问NAT-A(192.168.50.0/24)的服务了。

需要注意的是,在外面通过wireguard访问家中unraid的smb服务时,需要使用另外的账号密码,平常使用unraid的服务时也尽量不用默认的root用户。另外在外网访问时,实际速度受限于每条链路的最大上下速率,例如我这个公网服务器的出口网速只有6M,那么我通过公网节点下载内网内容的最大速率也只有这点。

放一些截图:

image1

image2

虽然文章很简短,但我着实断断续续折腾了3天左右,其中特别要注意的就是AllowedIPsiptables的NAT转发,这两个是实现既定目标的关键。如果想要实现游戏加速,上面的NAT还不够,可以参考下面的文章实现NAT1 - Full Cone Nat。好了,关于wireguard的笔记就到这里了,如有疑问欢迎留言评论!

参考文章

[1] 自建 wireguard 加速游戏并实现NAT1(fullcone)

[2] 通过 Wireguard 构建 NAT to NAT VPN

[3] Ubuntu 20.04 set up WireGuard VPN server

[4] Setting up WireGuard on Windows

笔记经验NAT虚拟专用网

开启我的挖矿之旅

音乐伴我青春