WireGuard (简体中文)

From ArchWiki

Tango-preferences-desktop-locale.png本文或本节需要翻译。要贡献翻译,请访问简体中文翻译团队Tango-preferences-desktop-locale.png

附注: 翻译中,但未同步最新的英文版本(在 Talk:WireGuard (简体中文)# 中讨论)

引用自 WireGuard 项目主页:

WireGuard 是一种极其简单但快速且现代的 VPN,它利用了最先进的加密技术。它的目标是比 IPsec 更快、更简单、更精简和更有用,同时避免令人头疼的问题。旨在提供比 OpenVPN 更高的性能。WireGuard 被设计为在嵌入式接口和超级计算机等上运行的通用 VPN,适用于许多不同的环境。最初仅支持 Linux 平台,现在可以进行跨平台(Windows、macOS、BSD、iOS、Android)的广泛部署。目前仍然在大力开发中,但已经被认为是业内最安全、最容易使用和最简单的 VPN 解决方案。

警告: WireGuard 尚未经过适当程度的安全审计,协议仍有可能更改。[1]

安装

  1. 安装 wireguard-tools
  2. 对于版本小于 5.6 的 Linux 内核,需要额外安装合适的内核模块(当使用默认的 linux 包时不需要):
提示: systemd-networkdNetworkManager 都为 WireGuard 接口设置提供原生支持,它们只需要内核模块。

使用

在 peer 上生成公钥和私钥:

$ wg genkey | tee privatekey | wg pubkey > publickey

下面的指令会演示如何以表中的配置建立一条两个 peer 之间的隧道

Peer A Peer B
公网地址 10.10.10.1/24 10.10.10.2/24
内网地址 10.0.0.1/24 10.0.0.2/24
wireguard 监听端口 UDP/4857 UDP/3981

Peer 应当已经拥有公网地址。例如,peer A 应当能够通过 ping 10.10.10.2 ping 通 peer B,反之亦然。内部地址是由下文 ip 命令创建的新地址,并且将在 WireGuard 网络中共享。IP地址中 /24 的含义详见 CIDR

Peer A 配置

这个 peer 将监听 UDP 端口 48574,通过将 peer B 的公钥与其内部和外部 IP 地址关联,接受来自 peer B 的连接。

# ip link add dev wg0 type wireguard
# ip link set dev wg0 mtu 1420
# ip addr add 10.0.0.1/24 dev wg0
# wg set wg0 listen-port 4857 private-key ./privatekey
# wg set wg0 peer [Peer B public key] persistent-keepalive 25 allowed-ips 10.0.0.2/32 endpoint 10.10.10.2:3981
# ip link set wg0 up

[Peer B public key] 的格式应当如同 EsnHH9m6RthHSs+sd9uM6eCHe/mMVFaRh93GYadDDnM=allowed-ips 是 peer A 能够向之发送流量的地址列表。allowed-ips 0.0.0.0/0 将允许向任意地址发送流量。

Peer B 配置

如同 Peer A,只不过 wireguard 守护监听 UDP 端口 39814 并且只接受 peer A 的连接

# ip link add dev wg0 type wireguard
# ip link set dev wg0 mtu 1420
# ip addr add 10.0.0.2/24 dev wg0
# wg set wg0 listen-port 3981 private-key ./privatekey
# wg set wg0 peer [Peer A public key] persistent-keepalive 25 allowed-ips 10.0.0.1/32 endpoint 10.10.10.1:4857
# ip link set wg0 up

基本检查

不带任何参数使用 wg 命令可以快速查看当前的配置。

例如,当 peer A 配置好之后,我们可以看见它的身份和与之关联的 peers。

 peer-a$ wg
 interface: wg0
   public key: UguPyBThx/+xMXeTbRYkKlP0Wh/QZT3vTLPOVaaXTD8=
   private key: (hidden)
   listening port: 4857
 
 peer: 9jalV3EEBnVXahro0pRMQ+cHlmjE33Slo9tddzCVtCw=
   endpoint: 10.10.10.2:3981
   allowed ips: 10.0.0.2/32

此时我们可以 ping 通隧道的另一端:

 peer-a$ ping 10.0.0.2

配置持久化

配置可以通过 showconf 来保存

# wg showconf wg0 > /etc/wireguard/wg0.conf
# wg setconf wg0 /etc/wireguard/wg0.conf

示例 peer 配置

/etc/wireguard/wg0.conf
[Interface]
PrivateKey = [CLIENT PRIVATE KEY]
MTU = 1420

[Peer]
PublicKey = [SERVER PUBLICKEY]
AllowedIPs = 10.0.0.0/24, 10.123.45.0/24, 1234:4567:89ab::/48
Endpoint = [SERVER ENDPOINT]:5182
PersistentKeepalive = 25

配置一个 VPN 服务器

WireGuard 自带一个快速创建和销毁 VPN 服务器的工具,wg-quick。注意这里使用的配置文件不是一个能被 wg setconf 有效的配置文件,并且你可能至少要把 eth0 改成你实际使用的。

服务器

/etc/wireguard/wg0server.conf
[Interface]
Address = 10.0.0.1/24  # This is the virtual IP address, with the subnet mask we will use for the VPN
PostUp   = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 5182
PrivateKey = [SERVER PRIVATE KEY]
MTU = 1420

[Peer]
PublicKey = [CLIENT PUBLIC KEY]
AllowedIPs = 10.0.0.2/32  # 这表示客户端只有一个 IP。

要使 iptables 规则生效,启用 IPv4 转发:

# sysctl net.ipv4.ip_forward=1

永久保留这项改变,向 /etc/sysctl.d/99-sysctl.conf 添加 net.ipv4.ip_forward = 1

使用 wg-quick up wg0server 启用 Interface,wg-quick down wg0server 用以关闭

客户端 (转发所有流量)

/etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.2/24  # The client IP from wg0server.conf with the same subnet mask
PrivateKey = [CLIENT PRIVATE KEY]
DNS = 10.0.0.1
MTU = 1420

[Peer]
PublicKey = [SERVER PUBLICKEY]
AllowedIPs = 0.0.0.0/0, ::0/0
Endpoint = [SERVER ENDPOINT]:5182
PersistentKeepalive = 25

使用 wg-quick up wg0 来启用 Interface, 使用 wg-quick down wg0 来关闭。

使用 systemctl enable wg-quick@wg0 来自动启动。

如果你使用 NetworkManager, 可能有必要启用 NetworkManager-wait-online.service systemctl enable NetworkManager-wait-online.service

或者你使用的是 systemd-networkd, 启用 systemd-networkd-wait-online.service systemctl enable systemd-networkd-wait-online.service

等待所有设备就绪再尝试 WireGuard 连接

疑难解答

DKMS module not available

如果你在安装了 wireguard-dkmsAUR 后执行下面的命令没有列出任何模块

$ modprobe wireguard && lsmod | grep wireguard

或者在使用下面的命令创建一个新的连接时提示 RTNETLINK answers: Operation not supported

# ip link add dev wg0 type wireguard

可能是因为缺失了 linux 头文件。

linux 头文件可以通过安装 linux-headers 获取。

使用技巧

以加密的形式存储私钥

以加密的形式存储私钥可能是可以实现的,例如通过使用 pass。只需将配置文件中[Interface]下的 PrivateKey 一行替换为。

 PostUp = wg set %i private-key <(su user -c "export PASSWORD_STORE_DIR=/path/to/your/store/; pass WireGuard/private-keys/%i")

where user is your username. See the `wg-quick(8)` man page for more details.

将其中的user替换成你的用户名。更多细节请参见 `wg-quick(8)` man 页面。