在树莓派上设置 VPN 服务器

Jinku Hu 2022年5月18日
在树莓派上设置 VPN 服务器

本文将演示在 Raspberry Pi 设备上设置 VPN 服务器。

在 Raspberry Pi OS 上配置 WireGuard VPN 包

一般来说,VPN 服务器有许多不同的协议和实现,但本文选择 WireGuard 软件作为当代流行的选择。

该软件包通常在默认存储库中可用,你应该能够使用以下命令安装它:

sudo apt install wireguard

一旦安装了 wireguard 软件包,你的 Raspberry Pi 系统上将可以使用几个命令行工具来操作 WireGuard 配置和接口。

WireGuard 通常会为系统添加一个新的虚拟网络接口。WireGuard 实现了 CryptoKey Routing 概念,通过将公钥/私钥关联到每个对等方来表示。

也就是说,对等点只是 VPN 隧道中的参与者,每个参与者都由唯一的公钥标识。因此,我们需要生成这些密钥并将它们包含在相应的配置文件中。

由于配置文件和私钥应该被视为敏感信息,我们在生成密钥并将它们存储在/etc/wireguard 目录之前调用 umask 0700 命令。

因此,只有这些文件的所有者才能在以后读取/写入内容。

umask 0700; wg genkey | sudo tee /etc/wireguard/private.key

样本输出:

2RzKFbGMx5g7fG0BrWCI7JIpGvcwGkqUaCoENYueJw4=

前面的命令会将密钥存储在 private.key 文件中并打印出来以便轻松复制。

接下来,我们将在同一 /etc/wireguard 目录中创建一个名为 wg0.conf 的配置文件,并在其中包含以下内容:

[Interface]
PrivateKey = 2RzKFbGMx5g7fG0BrWCI7JIpGvcwGkqUaCoENYueJw4=
Address = 10.10.10.1/24
ListenPort = 51820

请注意,此配置文件适用于 Raspberry Pi 对等体,你可以根据需要重命名 wg0 部分。

你应该将 PrivateKey 值复制为使用上一个命令生成的密钥。此外,你可以指定将接受传入连接的端口和对等方的地址。

现在我们可以转到另一个节点(节点 A),它应该连接到 Raspberry Pi。此时,我们假设另一台机器是基于 Linux 的,并且你已相应地在其上安装了 WireGuard 包。

Peer A 配置将遵循相同的步骤来重用命令来生成公钥并执行它。请注意,密钥可以在一台机器上生成,但由于私钥是保密的,我们正在相应的对等机器上开发它们。

生成私钥后,在 /etc/wireguard 目录中创建一个配置文件(例如 wg0.conf)并插入以下行:

[Interface]
PrivateKey = 9jalV3EEBnVXahro0pRMQ+cHlmjE33Slo9tddzCVtCw=
Address = 10.10.10.2/32

请注意,此处的 PrivateKey 值是任意的,你必须将其替换为有效值。同时,如果你有特定的网络配置需求,IP 地址可能会修改。

在此之后,我们必须生成公钥并将它们存储在它们的配置文件中。公钥是从私钥派生的,在我们的例子中,需要在两个设备上生成。

使用以下命令在 Raspberry Pi 上生成一个公钥,在另一台机器上生成第二个公钥:

sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key

现在,让我们将 peer 部分插入到配置文件中。以下行需要附加到 Raspberry Pi /etc/wireguard/wg0.conf 文件中:

[Peer]
PublicKey = PRIVATE_KEY_OF_PEER_A
AllowedIPs = 10.10.10.2/32

请注意,AllowedIPs 值与 Peer A 配置文件的 Address 值中指定的 IP 地址相同。

此外,将 PRIVATE_KEY_OF_PEER_A 替换为在 Peer A 上生成的私钥。另一方面,将以下行附加到 Peer A 机器上的 wg0.conf 文件中。

确保将私钥值替换为对应的值,并将端点地址替换为 Raspberry Pi 设备的地址。请注意,以下配置将使 VPN 连接单向连接,因为只有 Peer A 可以访问 Raspberry Pi 网络。

[Peer]
PublicKey = PRIVATE_KEY_OF_RASPBERRY
AllowedIPs = 0.0.0.0/0
Endpoint = 172.16.0.134:51820

最后,你应该使用以下命令在树莓派端启动相应的服务:

sudo systemctl enable wg-quick@wg0.service

虽然 Peer A 每次想要创建隧道接口并连接到它时都会使用以下命令:

sudo wg-quick up wg0

你可以使用以下命令删除接口并终止来自 Peer A 的现有连接:

sudo wg-quick down wg0

如何通过 Raspberry Pi 路由所有 Peer A 流量

此时,Peer A 将无法访问 Internet,只能访问 Raspberry Pi 网络。我们需要在配置文件中添加额外的参数来实现这一点。

让我们从 Peer A wg0.conf 文件开始,并在 [Interface] 部分添加以下行:

DNS = DNS_ADDRESS_USED_BY_RASPBERRY

此 DNS 地址值取决于网络配置,因此你应该检索当前活动的地址并在将来由于某种原因发生更改时对其进行更新。

另一方面,你应该将这些额外的行附加到 Raspberry Pi wg0.conf 文件中:

PostUp = ufw route allow in on wg0 out on eth0
PostUp = iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
PostUp = ip6tables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
PreDown = ufw route delete allow in on wg0 out on eth0
PreDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PreDown = ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

请注意,如果你为配置文件创建不同的文件名,则需要在这些行中更改 wg0 名称。

保存 wg0.conf 更改后,打开 /etc/sysctl.conf 文件并取消注释/修改行:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

通常,只有在配置文件中还包含 IPv6 地址时才需要 net.ipv6.conf.all.forwarding。在此之后,你必须运行以下命令才能使更改生效:

sudo sysctl -p

现在,你应该通过 Raspberry Pi 连接并转发来自 Peer A 的所有 Internet 流量。不过,如果你在树莓派上运行防火墙,请务必为 Peer A 设置相应的规则,否则它将无法访问网络。

你可以在这里看到我们对 ufw 防火墙的介绍。

Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相关文章 - Raspberry Pi