Document
使用 WireGuard 搭建 VPN 访问家庭内网

使用 WireGuard 搭建 VPN 访问家庭内网

不知道从什么时候开始,B 站博主和什么值得买的值友都开始纷纷带货 NAS 了。看了很多人推荐,于是自己也买了一台群晖 NAS 来玩玩。由于 NAS 部署在家中,出门的时候要访问文件就非常不方便。传统的做法是使用群晖的 QuickConnect 或者 DDNS。然而,前者(据说)速度很慢,后者将设备暴

Related articles

Top 10 Best Cloud VPN Providers in 2024 How to Set Up a Node on Mysterium Network and Earn Passively 3.2.1: The Bohr Model How to Start a Cloud Kitchen? Registrations and Licensees Kaspersky Secure Connection VPN Review

不知道从什么时候开始,B 站博主和什么值得买的值友都开始纷纷带货 NAS 了。看了很多人推荐,于是自己也买了一台群晖 NAS 来玩玩。由于 NAS 部署在家中,出门的时候要访问文件就非常不方便。传统的做法是使用群晖的 QuickConnect 或者 DDNS。然而,前者(据说)速度很慢,后者将设备暴露在公网上,安全性又存在一些疑虑,况且我家宽带没有公网 IP。因此,我决定试一试组网工具 WireGuard。

由于家里网络没有公网 IP,因此需要一台具有公网 IP 的服务器作为 WireGuard 网络的“server”。我这里使用的是一台 CentOS  8 服务器。同时,家中也需要有一台设备作为 WireGuard 网络中的节点,以将流量转发给 NAS。当然这台设备也可以是 NAS 本身,但为了简单起见,我使用的是 Mac。最后,我们将使用手机,在 4G 网络下检查 VPN 是否搭建成功。

IP 段的选择

WireGuard 组网需要使用一个不与你的任何设备的网络相冲突的 IP 地址段,你可以在这里查询到所有的保留地址段。像 192.0.2.0/24、198.51.100.0/24 这些分配为用于文档和示例中的“TEST-NET”,似乎是很好的选择,因为这些地址段通常不会被你需要连接的其他网络所使用。

在下面的配置中,我会分别将 192.0.2.1、192.0.2.2、192.0.2.3 分配给公网服务器、家中的 Mac 和 iPhone。

在服务器上配置 WireGuard

要使用 WireGuard,首先需要确保 Linux 内核支持。可使用 modinfo wireguard 命令检查是否内置了 WireGuard。也可用过 uname -r 检查内核版本是否为 5.6 以上。我这里版本还是 4.x,因此需要升级内核:

$ rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

$ yum -y install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm

$ yum --disablerepo="*" --enablerepo="elrepo-kernel" list available

$ yum -y install --enablerepo=elrepo-kernel kernel-ml kernel-ml-devel kernel-ml-headers

# 查看安装之后的内核
$ rpm -qa | grep kernel

# 查看默认内核
$ grubby --default-kernel

# 如果默认内核不是最新的,可以使用如下命令更改
$ grubby --set-default /boot/vmlinuz-5.18.4-1.el8.elrepo.x86_64

# 重启生效
$ reboot

现在使用 modinfo wireguard 命令可以看到正常输出了:

$ modinfo wireguard
filename:       /lib/modules/5.18.4-1.el8.elrepo.x86_64/kernel/drivers/net/wireguard/wireguard.ko.xz
alias:          net-pf-16-proto-16-family-wireguard
alias:          rtnl-link-wireguard
version:        1.0.0
author:         Jason A. Donenfeld <Jason@zx2c4.com>
description:    WireGuard secure network tunnel
license:        GPL v2
srcversion:     746FF227790A0865A542034
depends:        udp_tunnel,curve25519-x86_64,libchacha20poly1305,ip6_udp_tunnel,libcurve25519-generic
retpoline:      Y
intree:         Y
name:           wireguard
vermagic:       5.18.4-1.el8.elrepo.x86_64 SMP preempt mod_unload modversions

然后安装 wireguard-tools:

$ yum install elrepo-release epel-release

$ yum install wireguard-tools

完成服务器端的配置

在服务器端配置文件中,我们需要设置监听的端口,以及所有需要连接到的 Peer 列表。在 WireGuard 中,每一个 Peer (即网络中的每一个设备)都需要一个公钥和私钥。在正确安装 wireguard-tools 后,你可以通过如下命令快速创建一组公钥和私钥。重复多次,以给你的所有设备完成创建:

$ wg genkey | tee peer_A.key | wg pubkey > peer_A.pub && cat peer_A.key && cat peer_A.pub

然后完成配置文件的创建,并保存到 /etc/wireguard/wg0.conf(默认配置文件位置):

[Interface]
PrivateKey = (your server private key here)
Address = 192.0.2.1/24
ListenPort = 51820

[Peer]
# Mac at home
PublicKey = (Mac public key here)
AllowedIPs = 192.0.2.2/32, 192.168.1.0/24

[Peer]
# iPhone
PublicKey = (iPhone public key here)
AllowedIPs = 192.0.2.3/32

在 WireGuard 中,你需要手动给各个设备分配 IP,并确保每个设备都有唯一的 IP。Interface 包含了当前设备的设置,对于“服务端”来说,ListenPort 是必须的。下面的每一个 Peer 段代表了能连接到本设备的一个其他设备。

AllowedIPs 是一个神奇的字段,我至今没有完全理解它的意思。根据网上的说法,这个字段有两个作用:

  • 它会创建一个到指定网络的路由,比如在上述的例子中,目标位置为 192.0.2.2/32 或 192.168.1.0/24 的包会通过 WireGuard 的虚拟网卡发送给第一个 Peer
  • 它会允许来自这个 Peer、且源地址为 192.0.2.2/32 或 192.168.1.0/24 的包被 WireGuard 的虚拟网卡路由。换句话说,来自这个 Peer、且源地址不为 192.0.2.2/32 或 192.168.1.0/24 的包将被丢弃

在完成配置文件的保存后,我们可以使用 wg-quick up wg0 来启用配置文件。wg-quick 会自动配置路由表,无需我们手动设置。

在完成上述所有操作后,还需进入云服务厂商的控制台,开放云主机的防火墙的  51820 端口。注意你的云主机可能也有软件防火墙,记得在这里也要开放相应的端口。

完成 Mac 端的配置

我们仿照服务器端的配置文件,完成 Mac 端的配置文件。由于我的 iPhone 是通过访问公网服务器来访问家庭内网的,并不直接连接家中的 Mac,因此这里的节点列表中并不一定需要添加 iPhone。

[Interface]
PrivateKey = (private key of Mac)
Address = 192.0.2.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = (public key of server)
AllowedIPs = 192.0.2.0/24
Endpoint = (server ip address):51820
PersistentKeepalive = 10

在这里,我们将公网服务器作为唯一的 Peer,通过设置 PersistentKeepalive 来进行连接的保活。这里 AllowedIPs 的作用是确保来自于我们 WireGuard 子网网段来的流量能被本机的 WireGuard 虚拟网卡进行处理,而并不是用于限制 Peer 可以访问本机所在的哪些网段,因此添加 192.168.1.0/24 是绝对错误的。WireGuard 似乎并不能限制 Peer 可以通过本机访问哪些网段,不过我承认我并没有细看它的安全模型,有机会再补补课吧。

在 Mac 上,我们可以下载官方的 GUI 客户端。然后将配置文件导入进来,并一键点击运行。通过这种方式我们可以免去设置防火墙等配置。

另外值得一提的是,在 Mac 上,WireGuard 是可以和 Surge 的网关模式兼容的。因此使用 Mac 作为网关的同学可不必担心兼容性问题。

完成 iPhone 端的配置

为了实现最佳网络体验,在 iPhone 上我也使用了 Surge,并通过 iCloud 实现配置的自动同步。Surge 目前已经支持了 WireGuard 作为代理策略,事实上这正是我决定试一试 WireGuard 的原因。毕竟如果连上家里内网的时候就连不上真正的互联网,那就太糟糕了。

我们在 Surge 的配置文件中添加如下内容:

[Proxy]
wireguard-iphone = wireguard, section-name = iPhone

[WireGuard iPhone]
private-key = (iPhone private key here)
self-ip = 192.0.2.3
dns-server = 223.5.5.5
mtu = 1280
peer = (public-key = (server public key here), allowed-ips = 0.0.0.0/0, endpoint = (server public ip here):51820)

另外我们希望在内网下不使用 WireGuard 连接 NAS,而在公网下使用 WireGuard 连接 NAS,因此新增如下 Surge Module,并按需开启:

#!name=WireGuard 内网访问
#!desc=开启后,可在非家中网络环境访问家庭内网

[Rule]
AND,((OR,((SUBNET,TYPE:CELLULAR), (NOT, ((OR, ((SUBNET,SSID:My 5G WiFi), (SUBNET,SSID:My 2.4G WiFi))))))), (IP-CIDR,192.168.1.0/24)),wireguard-iphone
IP-CIDR,192.0.2.0/24,wireguard-iphone

上述规则中括号非常多,看着很头疼,实际效果如下:

  • 当使用蜂窝网络,并访问 192.168.1.0/24 地址段时,使用名为 wireguard-iphone 的 Proxy
  • 当使用的 WiFi SSID 名称不是 My 5G WiFi 或 My 2.4G WiFi,并访问 192.168.1.0/24 地址段时,使用名为 wireguard-iphone 的 Proxy

通过上述配置,我成功在手机的 4G 网络环境中访问到了家中的 NAS。对 NAS 上部署的测速服务器进行访问,实际带宽大概为 6Mbps 左右,已经跑满了我的云服务器的带宽。这个速率基本上很难满足 1080p 串流需求,只能用于临时的小文件访问。毕竟国内的带宽还是太贵了。不过好消息是,经过上述的折腾,我们不仅可以访问家中的 NAS,也可以访问家中的任意网络服务,而无需额外配置。之后给家里安排上公网 IP 应该会舒服很多,到时候应该至少可以流畅串流 1080p 视频了。

更新:

通过找电信师傅,成功获取了公网 IP。现在 iPhone 通过 DDNS  直连家中 Mac 的 WireGuard 端口,测速可稳定跑满家中宽带的上传带宽 30Mbps 左右。这个速度可以流畅串流 1080p 视频,但对于 4K 视频来说比较困难。一部 20GB、2 小时的 4K  视频的码率为 2.84MB/s,转换成带宽为 22.7Mbps。而这个码率在 4K 电影中已经算非常低的了。如果考虑到协议损耗、上传带宽波动,能够从头开始播放不卡顿已经是万幸,想要实现随时跳转进度体验会不太好。

使用 WireGuard 搭建 VPN 访问家庭内网