上一篇提到整了个树莓派, 为了解决出门在外也能连上的问题, 这一篇整一个 WireGuard 来实现.
WireGuard 是一个号称又快又安全的 VPN tunnel, 当然你拿来翻墙也没有什么问题..
安装
WireGuard
是基于 Linux 内核实现的, 不过目前支持了 macOS 和 Adnroid 以及 iOS, 至于 Windows 的支持, coming soon 很久了…
由于总所周知万物起源于 Arch Linux, 于是…
pacman -S wireguard-tools
首先安装好用户态的工具, 这是用来在用户态管理 WireGuard 相关的东西, 除此以外还需要内核模块.
WireGuard 的内核模块在 Arch 上是 wireguard-dkms
包, 安装 dkms 的模块一般需要编译, 而编译就需要提供 kernel headers, 而 headers 默认是没安装的, 需要自己根据内核安装.
树莓派用的是 linux-raspberrypi
的内核, 因此对应的 headers 包是 linux-raspberrypi-headers
, 其他的自己随机应变一下.
pacman -S linux-raspberrypi-headers wireguard-dkms
然后检测一下有没有装上内核模块
modprobe wireguard
配置
其实 WireGuard 有一篇 Quick Start 来做参考的, 不过这个 Quick Start 自然是没有开机自启的, 对于非常容易就重启的树莓派来说当然不太合适, 尽管可以通过开机脚本或者 systemd service
来实现, 但实际上不是很方便.
幸好 systemd
拯救世界!
systemd
的 systemd-networkd
提供了对于 WireGuard 的良好支持, 我们只需要编写一个 netdev
文件就足够了.
密钥生成
首先需要生成一个非对称密钥:
当然需要在树莓派和服务器上都生成一个, 什么? 你说没有服务器? 那只能按一下 Ctrl + W
了…
wg genkey > wg_priv
然后提取出公钥
wg pubkey < wg_priv
生成好的私钥和公钥备用.
Interface 设置
前面说了 systemd
拯救世界, 那么接下来就是如何拯救了.
man systemd.netdev
一下可以看到详细的参数说明, 如果看不懂英文的话没关系.
首先进入 /etc/systemd/network
目录下, 创建一个 wg.netdev
的文件, 内容格式这样:
[NetDev]
Description=Wireguard 0
Name=wg0
Kind=wireguard
[WireGuard]
PrivateKey=<私钥>
[WireGuardPeer]
PublicKey=<对端公钥>
AllowedIPs=10.0.0.1/32
Endpoint=<>
PersistentKeepalive=60
来详细说明一下
[NetDev]
段声明了我们的接口名称和类型, Name 就是网卡接口的名字, Description 没什么太大关系, 自己根据需求改一下就好.
[WireGuard]
段的 PrivateKey 就是之前生成的私钥, base64 编码的填进去. 大概是这样子的 udrtO0xA8tHtqNbKWgnhrS3KW7zE8W0dJ0N0gYavG10=
这种. (别想用这个来测试我服务器, 这是 openssl rand -base64
随便生成的实例).
[WireGuardPeer]
这段则是用来指定 peer 的
其中 PublicKey
需要填服务器上生成的对应的公钥, 而 AllowedIPs
是服务器上对应的 wg interface 绑定的ip 这个之后再详细说.
Endpoint
是服务器的 IP 加上 [WireGuard]
段的 ListenPort
设定, 例如 1.1.1.1:1234
这种.
PersistentKeepalive
则是表示每隔 60s 给 peer 发送一个空包来保活, 这一点对于 NAT 设备后面的 peer 是有用的, 避免因为长时间没有通信而被路由器或者之类的 NAT 设备给切断连接.
有了这个配置之后, 系统启动后会自动创建一个 wg0 的网卡设备, type 是 wireguard, 并且给他配置好
但光有这个还不够
如果你足够聪明已经发现了问题, 这个 wg0 网卡上还没给绑定 IP 呢!
接下来就是给这个网卡绑定一个 IP. Arch 上用的是 netctl 来进行管理的.
对应的配置文件目录在 /etc/netctl
这里.
进入这个目录之后创建一个文件名字格式一般是 <网卡>-<名字>
, 例如我创一个 wg0-hk
, 内容大概是
Description='Wireguard to tx-hk-01'
Interface=wg0
Connection=ethernet
IP=static
Address=10.0.0.2/24
Description
不用说了吧…
Interface
就是上面 netdev
里面的 Name
指定的
Address
就是给这个网卡上绑定的 IP.
创建好之后可以用 netctl list
来查看, 并且用 netctl start
启动这个 profile,
以及使用 netctl enable
设定为开机自动加载.
上面是树莓派作为客户端上该有的配置
同样在服务器上也需要进行差不多的配置, 只不过在 netdev
设置的时候, 需要在 [WireGuard]
段额外加一个 ListenPort
的参数, 以使服务器上的 WireGuard 端点固定下来, 方便客户端连接.
同样的 [WireGuardPeer]
段的公钥需要填客户端生成的公钥.
而服务器上的 WireGuardPeer 里面是不需要填 Endpoint 的, 因为你是被连的, 而且因为客户端是在 NAT 设备后面的, 要想填上去需要在客户端 NAT 设备上做一些设定
但这并不代表服务器上完全不能填 Endpoint
而服务器的操作系统根据个人喜好什么的, 可能没有 netctl 之类的东西, 那么关于分配 IP 的方式也不相同, 自己找找资料吧.
End
关于 AllowedIPs
, 这个参数是必须要有的, 并且需要根据 peer 来进行设定, 例如服务器上的 peer 的 AllowedIPs
就需要填客户端上的绑定的IP, 否则就会被丢弃而无法进行通讯.