WireGuard on Raspberry Pi

上一篇提到整了个树莓派, 为了解决出门在外也能连上的问题, 这一篇整一个 WireGuard 来实现.

WireGuard 是一个号称又快又安全的 VPN tunnel, 当然你拿来翻墙也没有什么问题..

安装

WireGuard 是基于 Linux 内核实现的, 不过目前支持了 macOS 和 Adnroid 以及 iOS, 至于 Windows 的支持, coming soon 很久了…

WireGuard Installation

由于总所周知万物起源于 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

配置

Quick Start

其实 WireGuard 有一篇 Quick Start 来做参考的, 不过这个 Quick Start 自然是没有开机自启的, 对于非常容易就重启的树莓派来说当然不太合适, 尽管可以通过开机脚本或者 systemd service 来实现, 但实际上不是很方便.

幸好 systemd 拯救世界!

systemdsystemd-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, 否则就会被丢弃而无法进行通讯.

发表评论

电子邮件地址不会被公开。 必填项已用*标注