共同作者:tmlxs 和 adr13n
WireGuard 是一个适用于 IPv4 和 IPv6 的网络隧道(VPN),采用 UDP 协议。如今,大部分代码都驻留在 Linux 内核中,但跨平台的实现正在进行中。WireGuard 采用类似于 SSH 的认证机制,VPN 服务器和每个客户端都有自己的非对称密钥对。授权新客户端只需将其公钥添加到服务器配置文件中。需要注意的是,WireGuard 可以配置为使用预共享密钥,作为现有非对称密钥的附加安全层。这是可选的,但可以提高对量子攻击的抵抗力。
WireGuard 的优势
WireGuard 的优势在于其简单性和可审计性:其代码量约为 4 KLoC,而大多数替代方案的代码量超过 100 KLoC,难以审计。它使用现代加密原语(Curve25519、HKDF、ChaCha20、Poly1305、BLAKE2s、SipHash24)并具有高效的实现,使其成为 OpenVPN 和 IPsec 的优秀替代品。WireGuard 作为虚拟网络接口(例如,wg0)运行。这意味着可以使用标准的 ip(8)
工具管理该接口。
WireGuard 也是当前速度最快的 VPN(请参见基准测试),在吞吐量测试中超过了 OpenVPN。它隐秘且安静,因为它不会对未认证的消息发送回复,使其难以被网络扫描器发现。此外,它提供完美的前向保密。
需要注意的是,WireGuard 仍处于实验阶段,因此尚未准备好投入生产使用。
WireGuard 的基本概念
WireGuard 引入了端点(Endpoints)、对等体(Peers)和允许的 IP(AllowedIPs)的概念。对等体是一个远程主机,通过其公钥进行标识。每个对等体都有一个允许的 IP 列表。从服务器的角度来看,允许的 IP 是对等体可以使用的源 IP 地址。对客户端而言,它们充当了一种路由表,确定数据包应为哪个对等体加密。如果对等体发送的数据包源 IP 不在服务器的允许 IP 列表中,则该数据包将被服务器直接丢弃。端点是对等体的 IP 地址(或主机名)和端口的组合。它会自动更新为来自对等体的正确身份验证数据包的最新源 IP 地址和端口。这意味着,例如,在移动网络之间跳转的对等体(其外部 IP 地址发生变化)仍然能够接收传入流量,因为每当其向服务器发送身份验证消息时,端点都会更新。这是因为对等体通过其公钥进行标识。
WireGuard 的安装与设置
安装
WireGuard 的安装过程相当简单。请检查您的发行版是否提供了相应的包,链接如下:WireGuard 安装指南。如果没有,您需要按照说明从源代码编译。
安装过程需要在服务器和所有希望连接的客户端上进行。
服务器设置
首先,请确保启用 IP 转发,通过在 /etc/sysctl.conf
中添加以下内容:
bash
net.ipv4.ip_forward=1
运行以下命令以应用上述设置:
bash
$ sudo sysctl -p
同时,请确保 WireGuard 使用的端口在防火墙上开放(本教程使用默认端口 UDP/51820)。现在将设置 WireGuard。需要选择一个用于隧道中的主机范围。在本博客中,我们选择使用 192.168.3.0/24
,其中 192.168.3.1
分配给服务器,192.168.3.2
分配给客户端。
以下是以 root 身份运行的命令,以生成服务器的配置文件(将保存在 /etc/wireguard/wg0.conf
中):
```bash
[Interface] Address = 192.168.3.1/24 ListenPort = 51820 PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o IFACE -j MASQUERADE PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o IFACE -j MASQUERADE PrivateKey = $(wg genkey) SaveConfig = true
[Peer] PublicKey = CLIENT_PUBLIC_KEY AllowedIPs = CLIENT_VPN_IP/32 _EOF ```
确保用您面向互联网的接口名称(如 eth0)替换 IFACE。可以按照下面的部分说明,填写 [Peer] 块中的客户端信息。该块中的以下内容需要替换:
-
CLIENT_PUBLIC_KEY
是客户端的公钥。 -
CLIENT_VPN_IP
是分配给客户端的隧道范围内的 IP。
PostUp
和 PostDown
命令由 Bash 在接口启动或关闭后执行,分别启用和禁用 NAT 和转发。
最后,使用以下命令启动 WireGuard:
bash
$ sudo wg-quick up wg0
可以使用以下命令关闭 VPN 服务:
bash
$ sudo wg-quick down wg0
请注意,wg-quick(8)
只是 wg(8)
的 Bash 包装器,可能会直接集成到 ip(8)
中。配置文件中的 SaveConfig = true
条目告诉 WireGuard 在添加新客户端时自动更新配置文件,如下文所述。
接口启动后,可以使用以下命令查看连接的对等体:
bash
$ sudo wg show
运行上述命令时,将显示服务器的公钥。您还可以通过将生成的配置文件中的私钥粘贴到命令 wg pubkey
中并按 CTRL+d 来获取它。此公钥将在下面设置客户端时使用。
客户端设置
客户端也需要安装 WireGuard。安装方式与上述安装部分描述的相同。完成后,您可以继续。
工具 resolvconf
用于在启动 WireGuard 隧道时动态更改 DNS 服务器。如果您的发行版没有 resolvconf
,请安装它或将下面的 resolvconf
调用更改为适合您特定配置的内容。
现在以 root 身份运行以下命令设置客户端配置文件:
```bash
[Interface] Address = 192.168.3.2/24 PostUp = echo nameserver DNS_SERVER | resolvconf -a tun.%i -m 0 -x PostDown = resolvconf -d tun.%i PrivateKey = $(wg genkey)
[Peer] PublicKey = SERVER_PUB_KEY AllowedIPs = 0.0.0.0/0 Endpoint = PUBLIC_VPN_IP:51820 _EOF ```
其中:
- DNS_SERVER
是您希望在通过 VPN 隧道时使用的 DNS 服务器的 IP(例如,使用 Google 的 DNS 可填入 8.8.8.8
)。
- SERVER_PUB_KEY
是在前一部分生成的服务器公钥。
- PUBLIC_VPN_IP
是客户端将连接的 VPN 公共 IP。
与服务器相同,公钥可以通过将配置文件中创建的私钥粘贴到命令 wg pubkey
中并按 CTRL+d 来获取。
启用/禁用 VPN 隧道
在客户端,可以使用 wg-quick(8)
启用 VPN:
bash
$ sudo wg-quick up wg0
要禁用 VPN:
bash
$ sudo wg-quick down wg0
可以使用以下命令获取连接信息:
bash
$ sudo wg show
在服务器上添加新客户端
每个新客户端必须执行上述客户端设置。然后,只需在服务器上添加新客户端:
bash
$ sudo wg set wg0 peer CLIENT_PUB_KEY allowed-ips CLIENT_VPN_IP/32
由于配置条目 SaveConfig = true
,新添加的客户端将在下次关闭 WireGuard 时保存在配置文件中(wg-quick down wg0
)。CLIENT_PUB_KEY
需要替换为客户端的公钥,CLIENT_VPN_IP
是分配给客户端的隧道范围内的 IP(与客户端配置文件中的 Address
相同)。
深入了解
在这里,我们设置了一个 VPN,将所有流量通过隧道路由(在客户端配置中使用了 0.0.0.0/0, ::/0
的 AllowedIPs
),但这可以减少到特定范围(从而仅允许特定 IP 通过隧道路由)。此外,还可以设置多个配置。
WireGuard 的简单性和高效性使其成为现代 VPN 的理想选择。如果您正在寻找快速连接的 VPN 产品,WireGuard 绝对值得推荐。