如何使用 Wireguard 在 Ubuntu 20.04 上创建 VPN
Wireguard 是一款现代且非常易于设置的 VPN,可在多个操作系统上使用。该应用程序可在 Ubuntu 20.04 官方存储库中找到,因此安装也非常容易。与 OpenVPN 等基于 ssl 证书使用的其他软件不同,Wireguard 基于密钥对的使用。在本教程中,我们将了解如何通过几个简单的步骤在最新稳定版本的 Ubuntu 上配置 VPN 服务器和客户端对等点。
在本教程中您将学习:
如何在 Ubuntu 20.04 Focal Fossa 上安装 Wireguard
如何创建公钥和私钥对
如何配置服务器和客户端对等点
如何将所有传入流量重定向到 VPN
Ubuntu 20.04 上的 Wireguard VPN
安装
Wireguard 已在 Ubuntu 20.04 的“universe”存储库中正式提供,因此我们可以通过 apt 安装它。在撰写本文时,可用版本为 1.0.20200319-1ubuntu1
:
$ sudo apt install wireguard
系统会要求我们确认要安装该程序及其依赖项,并将在几秒钟内完成操作。
生成密钥
我们必须为要在 VPN 中使用的每台计算机生成公钥和私钥。私钥应在机器上保密,公钥用于从其他对等点访问该机器。
要生成密钥,我们可以使用 wg
实用程序。在 Wireguard 配置文件中,我们需要引用机器的私钥,而公钥将用于其他对等点。请注意,我们将直接引用密钥,因此理论上我们不需要将它们存储到文件中。但无论如何,我们都会这样做,只是为了方便。
要为我们的服务器生成私钥,我们必须使用 wg
的 genkey
子命令。该命令将创建的密钥输出到stdout;要将密钥写入文件,我们可以使用 shell 重定向的功能:
$ wg genkey > server_private_key
该命令将生成密钥并将其存储到 server_private_key
文件中,但会引发以下警告:
Warning: writing to world accessible file.
Consider setting the umask to 077 and trying again.
这是因为使用默认用户 umask (002
) 时,文件是使用模式 664
创建的,因此是世界可读的,不建议这样做。为了解决这个问题,我们可以在创建文件之前更改当前 shell 会话中使用的 umask:
$ umask 077
或者在创建后将文件权限更改为 600
。这里我们将采用后一种解决方案。
一旦我们的私钥准备好,我们就可以生成基于它的公共私钥。为了完成该任务,我们使用 wg
的 pubkey
子命令。就像之前我们使用 shell 重定向一样:首先将 server_private_key
文件的内容传递到命令的 stdin
,然后将生成的密钥重定向到 >server_public_key
文件:
$ wg pubkey < server_private_key > server_public_key
为了节省一些输入,我们可以仅使用一个命令来生成两个密钥,其中涉及使用 shell |
(管道)运算符和 tee
命令:
$ wg genkey | tee server_private_key | wg pubkey > server_public_key
管道运算符 (|
) 左侧命令的输出将传递到其右侧程序的标准输入。相反,tee 命令允许我们将命令的输出重定向到文件和标准输出(有关 shell 重定向的更多信息请参见此处)。
一旦我们的密钥准备好,我们就可以创建服务器配置文件。
服务器配置文件
要配置 Wireguard 安装,我们可以创建一个名为 wg0.conf
的配置文件,其中包含以下内容:
[Interface]
PrivateKey = <private key of the server (the content of the server_private_key file)>
Address = 10.0.0.1/24
ListenPort = 51820
请注意,文件的名称是任意的,但它应该基于我们将用于接口的名称,在本例中为 wg0
。启动服务时将引用该名称,如下所示。
在我们的例子中。配置文件的 [interface]
部分包含以下字段:
私钥
地址
侦听端口
PrivateKey字段值只不过是我们之前生成的服务器私钥。
在地址字段中,我们使用CIDR表示法指定分配给VPN中接口的地址以及子网掩码。在本例中,我们使用 10.0.0.1/24
,因此 VPN 内的 Wireguard“服务器”地址将为 10.0.0.1
,该地址位于可用的地址范围内从 10.0.0.1
到 10.0.0.254
。
最后,在 ListenPort 字段中,我们指定 Wireguard 将侦听传入流量的端口。还必须将允许上述流量的规则添加到我们的防火墙中。我们将在下一节中执行此操作。
我们现在可以更改文件的权限并将它们移动到 /etc/wireguard
目录:
$ chmod 600 server_public_key server_private_key wg0.conf
$ sudo mv server_private_key server_public_key wg0.conf /etc/wireguard
现在,我们可以启动 wg-quick
服务,并在单元名称中的 @
之后指定 Wireguard 接口的名称。这个记法是什么?这是 systemd 的一项功能:使用它,我们可以在“模板”文件的基础上生成多个单元文件,并在名称中的 @
符号后面传递将在模板中替换的值单位的。这是 wg-quick@.service
单元的内容:
[Unit]
Description=WireGuard via wg-quick(8) for %I
After=network-online.target nss-lookup.target
Wants=network-online.target nss-lookup.target
Documentation=man:wg-quick(8)
Documentation=man:wg(8)
Documentation=https://www.wireguard.com/
Documentation=https://www.wireguard.com/quickstart/
Documentation=https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
Documentation=https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/wg-quick up %i
ExecStop=/usr/bin/wg-quick down %i
Environment=WG_ENDPOINT_RESOLUTION_RETRIES=infinity
[Install]
WantedBy=multi-user.target
启动或停止时,我们将在单元名称中的 @
之后指定的值,将替换 ExecStart
和 中的
行。在本例中,我们将使用 %i
ExecStopwg0
:
$ sudo systemctl enable --now wg-quick@wg0
通过上面的命令,我们启动了服务,并使其在启动时自动启动。要验证我们的配置是否已应用,我们可以运行 wg
命令。生成的输出应显示有关 wg0
接口的信息:
$ sudo wg
interface: wg0
public key: nNx3Zpcv9D2dtgHDsoYGBNr64zG5jTJ4Z4T2sE759V4=
private key: (hidden)
listening port: 51820
现在,让我们继续配置防火墙和数据包转发。
防火墙和网络设置
在本教程中,我将假设使用 ufw
。正如我们之前所说,我们必须添加一条规则以允许传入流量通过我们在配置文件中指定的端口 51820
。我们通过运行一个非常简单的命令来做到这一点:
$ sudo ufw allow 51820/udp
我们还需要允许在我们的系统上转发数据包。为了完成该任务,我们从 /etc/sysctl.conf
文件的第 28
行删除注释,使其看起来像这样:
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
为了使更改生效而无需重新启动系统,我们需要运行以下命令:
$ sudo sysctl -p
在下一步中,我们将配置客户端。
客户端密钥生成
现在让我们继续我们想要用作客户端的系统。我们需要在上面安装Wireguard;完成后,我们可以像在服务器上一样生成密钥对:
$ wg genkey | tee client_private_key | wg pubkey > client_public_key
就像我们在服务器端所做的那样,我们创建了 wg0.conf 配置文件。这次的内容是:
[Interface]
PrivateKey = <client_private_key>
Address = 10.0.0.2/24
[Peer]
PublicKey = <server_public_key>
EndPoint = <server_public_ip>:51820
AllowedIPs = 0.0.0.0/0
当我们生成服务器配置时,我们已经看到了 Interface 部分中包含的字段的含义。在这里,我们只是根据客户端调整了这些值(它将在 VPN 中具有 10.0.0.2
地址)。
在此配置中,我们使用了一个新部分[Peer]
。在其中,我们可以指定与对等点相关的信息,在本例中是我们用作“服务器”的信息。我们使用的字段是:
公钥
端点
允许的IP
在 PublicKey 字段中,我们指定对等方的公钥,因此,在本例中,是我们在服务器上生成的公钥。
EndPoint 是对等点的公共 IP 地址或主机名,后跟冒号和对等点侦听的端口号(在我们的示例中为 51820
)。
最后,传递到 AllowedIPs 字段的值是一个以逗号分隔的 IP 地址和带有 CIDR 表示法的子网掩码列表。仅允许来自指定地址的定向到对等方的流量。在本例中,我们使用 0.0.0.0/0
作为值:它作为“包罗万象”的值,因此所有流量都将发送到 VPN 对等点(服务器)。
就像我们在服务器端所做的那样,我们设置适当的权限并将密钥和配置文件移动到 /etc/wireguard
目录:
$ chmod 600 client_public_key client_private_key wg0.conf
$ sudo mv client_public_key client_private_key wg0.conf /etc/wireguard
配置文件到位后,我们就可以启动服务了:
$ sudo systemctl enable --now wg-quick@wg0
最后,必须将与客户端相关的 [Peer]
部分添加到我们之前在服务器上创建的配置文件中。我们附加以下内容:
[Peer]
PublicKey = <public key of the client>
AllowedIPs = 10.0.0.2/32
此时我们重启服务:
$ sudo systemctl restart wg-quick@wg0
有关关联对等点的信息现在应在 wg
命令的输出中报告:
$ sudo wg
interface: wg0
public key: nNx3Zpcv9D2dtgHDsoYGBNr64zG5jTJ4Z4T2sE759V4=
private key: (hidden)
listening port: 51820
peer: t5pKKg5/9fJKiU0lrNTahv6gvABcmCjQq5gF3BxwiDQ=
allowed ips: 10.0.0.2/32
此时,从“客户端”系统,我们应该能够 ping 10.0.0.1
地址处的服务器:
$ ping -c 3 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=2.82 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=38.0 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=3.02 ms
--- 10.0.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 2.819/14.613/37.999/16.536 ms
结论
在本教程中,我们了解了如何在最新稳定版本的 Ubuntu:20.04 Focal Fossa 上使用 Wireguard 创建 VPN。该软件的安装和配置非常简单,特别是与其他解决方案(例如 OpenVpn)相比。
我们了解了如何生成用于我们设置的公钥和私钥,以及如何配置服务器和客户端以便所有流量都重定向到 VPN。按照给定的说明,您将获得一个工作设置。欲了解更多信息,请查看项目页面。