需求
本来想给内网的树莓派做 frp 一类的公网映射以便能够在外面访问 Samba 服务器,但是后来想想似乎把设备暴露在公网不太安全。换个角度想,其实没有必要把树莓派映射出去,只要能够连接进来就好了。所以选用 VPN 建虚拟专用网就好了,这里使用的 WireGuard 将我的各个设备连到一个子网内部。
WireGuard 和大部分 VPN 类似,是使用一个公网服务器做 Endpoint,内网的数据通过该服务器进行转发,因此子网的各个设备可以没有固定的 IP,只要都能连接公网服务器就好了。
安装
由于不同的系统安装方法不一样,建议参照 WireGuard 官网的安装说明 和各个系统的 Wiki,Android 手机可以搜索下载 WireGuard 的 APK 进行安装。
配置
首先需要生成公钥和私钥,建议将其设置为只有拥有者才能操作,我这里放在 /etc/wireguard
这个目录里面,这个目录应该是只有 root 才可以访问的。服务器和客户端都需要分别进行这一步。
服务端
然后需要手写配置文件,这一步对于服务端和客户端不一样,先进行服务端的配置。
首先在 /etc/wireguard
目录下面建立 wg0.conf
(如果你已经有一个了就 wg1
,依此类推),服务端的配置文件内容看起来像这个样子:
然后我们依次分析每个字段的内容,首先是 Interface,这个部分指的是 WireGuard 在本机上面的接口,它是以内核模块的形式工作的,Address
指本机在子网内的私有 IP 地址,我这里分配了保留段 10.0.0.0/24
作为子网网段(看不懂的自己去复习计网),你也可以用 10.0.0.0/8
这个网段再进行划分,这个主机地址是你自己随意分配的,只要不冲突就行。ListenPort
是监听的服务器 UDP 端口,这个也是自己设置,只要不冲突就行。PrivateKey
则是刚刚 服务端 生成的 privatekey
这个文件的内容。PostUp
和 PostDown
是配置 iptables 的命令,建议直接复制即可,如果你服务器的公网网卡不是 eth0
则需要自己修改。DNS
则是解析域名用的 DNS,这里直接使用 8.8.8.8
。
然后每一个 Peer 字段对应了一个客户端(或其他服务端,WireGuard 实际上是 P2P 的),需要分别将该客户端的 publickey
文件的内容贴到 PublicKey
,以及需要转发到该客户端的流量的 IP 地址范围贴到 AllowedIPs
,我这里直接给每个客户端设置固定的 IP,因此就写了 10.0.0.2/32
(看不懂的自己去复习计网),意思是该客户端对应的 IP 就是这个,所有向这个 IP 发送的流量都会被转发到这个客户端。
每添加一个新的客户端,就要在这个文件里添加一个 Peer 字段,然后设置 PublicKey
和 AllowedIPs
。
然后在服务器的 /etc/sysctl.conf
最后加上一句 net.ipv4.ip_forward=1
,开启 IPv4 流量转发,然后运行下面的命令加载新设置:
客户端
客户端也需要在 /etc/wireguard
目录下面建立 wg0.conf
(如果你已经有一个了就 wg1
,依此类推),内容看起来是这样:
Interface 字段自然是客户端本机的设置,Address
还是给本机分配的 IP,这里要和服务器在同一个子网,并且要和服务器配置文件里允许的 IP 段对上。PrivateKey
则是刚刚 客户端 生成的 privatekey
这个文件的内容。
然后通过添加 Peer 字段来添加服务端,服务端作为这个网络的出口和转发点,首先需要填写对应的 服务端 的公钥,然后这里的 AllowedIPs
设置的是 该客户端有哪些 IP 段的流量要通过该服务端进行转发,由于我只希望内网的流量进行转发,自然设置的是内网的 IP 段 10.0.0.0/24
(看不懂的你计网挂科了!),然后需要设置 Endpoint
以便能正确的在公网上找到服务器(虚拟专用网,连不上网还哪来的虚拟网啊?),格式就是 服务器公网 IP:你设置的监听端口
。PersistentKeepalive
则是用来保持连接的参数,直接复制即可。
如果你有多个服务器,就在这里添加多个 Peer,分别设置不同的 AllowedIPs
让他们转发,但 不需要让客户端之间互相添加 Peer,本来我们要解决的问题就是客户端之间不能互相连接,所有的流量是经由公网的服务端进行转发才可以到达,公网的服务器是各个不固定的客户端的接头地点。所以只需要保证服务端和所有的客户端认识就可以了。
启动
在分别配置好客户端和服务端之后就可以启动了,这一步两边都一样。注意把 wg0
换成你配置文件的名字。
然后使用 wg
命令可以查看状态,由于这些涉及到网络配置,都需要 root 权限。服务端和客户端输出的结果是不一样的,下面这个是我的笔记本输出的结果。
建立成功的话,子网之间是可以使用内网地址互相 ping 的:
如果你确定没有问题,就可以使用 Systemd 管理连接,首先关闭刚才的连接:
然后启动现成的 Unit:
后记
如果你需要在内网之间传递数据,建议选择一个访问较快的服务器,因为数据转发要通过这个服务器。
但如果你想使用 WireGuard 访问一些被河蟹的内容也可以,首先需要一个在海外的服务器,然后设置客户端该服务器的 AllowedIPs
为 0.0.0.0/0
(意思就是所有 IP 都经过这个服务器转发啦!或者你知道该设置某些网段也行!或者避开内网和本地地址!我不建议用这个番茄!所以就写个最蠢的!),就可以了!记得不用时候关掉,不然一些国内 App 也会走海外的!