前言

众所周知,TJ-DORM-WIFI 分配给各个设备的 IP 地址是无法从同一网络上的其他设备直接访问的。

但是好巧不巧,我能数出来的电子设备就有 5 台(未来可能还有更多)。这意味着,在需要用其他设备访问本机内容(如最近在用的 fava 或者网页的 Live Preview)时,我需要手动将需要使用的设备连接到另外一个本地网络(一般是热点)中,然后再进行操作。

烦死了给我,所以我愤而租了一年的上海服务器,用来组虚拟专用网。

开整!

在这里,我选择 111.222.33.441a1a::1 分别作为示例的服务器公网 IPv4 和 IPv6 位址。

Prerequisite

安装 wireguard

[bai@shanghai-vps ~]$ sudo apt install wireguard -y

来个钥匙

如果你不想把密钥输出到控制台,那么在本小节中,所有的 some_command | tee some_file 都可以换成 some_command > some_file

首先,先生成一个服务器的私钥:

sudo wg genkey | sudo tee /etc/wireguard/server_private.key

安全起见,我们给服务器的私钥设置一个权限,使非 root 用户都不得访问:

sudo chmod 600 /etc/wireguard/server_private.key

再生成私钥对应的公钥:

sudo cat /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key

接下来,查看服务器上的网络接口:

ip a

输出大概长这个样子:

1: lo: ...
2: enp0s1: <BROADCAST,...>
    link/ether ...
    inet ...

注意:由于不同 ISP 的设置有差异,你的以太网络设备名称不一定是 enp0s1。(别问我怎么知道的) 在接下来的博文中,我还是会用 enp0s1 作为示例,在实际环境中记得把它替换成你自己跑出来的名称(大概长这样:enpXsY, $X, Y \in \mathbb{N}_{+}$)。

整个配置

用你喜欢的编辑器打开 /etc/wireguard/wg0.conf,然后键入以下内容:

[Interface]
Address = 10.114.5.1/24
SaveConfig = true
PrivateKey = ... # 这个是你自己生成的 server_private.key 的内容
PostUp = ufw route allow in on wg0 out on enp0s1
PostUp = iptables -t nat -I POSTROUTING -o enp0s1 -j MASQUERADE
PreDown = ufw route delete allow in on wg0 out on enp0s1
PreDown = iptables -t nat -D POSTROUTING -o enp0s1 -j MASQUERADE
ListenPort = 51820

解释一下的话,Address 字段代表你要分配给需要组网的设备的私有 IP 段。当然,在你的实际配置中,Address 不一定要和我一起填 10.114.5.1/24,可以按照下面的规范填点别的;如果你有多个 IP 段以供分配,可以使用逗号分隔。比如 Address = 10.114.5.1/24,fd00::/7

私有 IP 段是指: IPv4: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16; IPv6: fd00::/7。 如果你和以前的我一样看不懂这是个啥,简单来说就是 /x 代表二进制表示的前 x 位是固定的。

ListenPort 字段定义 WireGuard 监听的端口,可以填一个 1 - 65535 之间你喜欢的数字。注意不要与其他应用抢端口哦——(

为什么端口号不能是 0 捏?其实当然可以(小声),参考 USTC Hackergame 2020 - 从零开始的 HTTP 链接

加个设备

在 WireGuard 的配置中,每个设备都会有一个私钥和公钥。生成私钥和对应公钥的流程和上文提到的一模一样(只不过不用设置成只有 root 可以访问)。 接下来,我们就可以开始写配置文件了:

[Interface]
PrivateKey = ... # 你生成的设备(客户端)私钥
Address = 10.114.5.14/24
DNS = 8.8.8.8 # 当然填什么 9.9.9.9 也行

[Peer]
PublicKey = ... # 你服务器的公钥
AllowedIPs = 0.0.0.0/0
Endpoint = 111.222.33.44:51820 # 如果改过 ListenPort,端口号要改成对应的
PersistentKeepalive = 15

其中,[Interface] 段的 Address 是你要给客户端分配的 IP 地址,只要它在 wg0 中定义的 IP 段内就没问题。 [Peer] 中的 PersistentKeepalive 的单位是秒,在设置后,客户端会每隔这一段定义的时间给服务器发送数据,以保持正常的通信。

然后,在 /etc/wireguard/wg0.conf 的末尾加入一段对客户端的定义:

[Peer]
PublicKey = ... # 你客户端的公钥
AllowedIPs = 10.114.5.14/32 # 要和刚才配置文件中的 Interface.Address 相对应

开个服务

一把梭。

sudo systemctl start [email protected]
sudo systemctl enable [email protected]

如果你的服务器上配置了 ufw,那么要在上面放行你 wg0.conf 里设置的 ListenPort 对应的端口,使其能接受外部的 UDP 连接。如果你的 ISP 设置了安全组,也要在 ISP 处一并放行。

sudo ufw allow 51820/udp

接下来,开启 IPv4 Forwarding。

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p # 刷新一下

然后配置一下网络设备:

sudo iptables -t nat -A POSTROUTING -s 10.114.5.0/24 -o enp0s1 -j MASQUERADE
sudo iptables-save | sudo tee /etc/iptables/rules.v4 # 保存一下
# 如果你也配置了 IPv6 网络,那么跑一下下面这段
sudo ip6tables -t nat -A POSTROUTING -s fd00::/7 -o enp0s1 -j MASQUERADE
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6

连接!

下载你客户端系统对应的 WireGuard 程序,把你的配置文件导入进去,点击 Connect,然后——

完成!现在你已经连接上了属于自己的虚拟专用网(!