WireGuard

出自 ArchWiki
(重定向自 Wg)

出自 WireGuard 项目主页

WireGuard 是一款极其简单、快速且现代的 VPN,它采用了最先进的加密技术。它的目标是比 IPsec 更快、更简单、更精简和更有用,同时避免了巨大的麻烦。它旨在比 OpenVPN 具有更高的性能。WireGuard 被设计为一个通用的 VPN,可以在嵌入式接口和超级计算机上运行,适用于许多不同的环境。最初为 Linux 内核发布,现在它是跨平台的(Windows、macOS、BSD、iOS、Android),并且可以广泛部署。

本文中使用的主要概念的粗略介绍可以在 WireGuard 的项目主页上找到。WireGuard 自 2019 年末以来已包含在 Linux 内核 中。

安装

安装 wireguard-tools 软件包以获得用户空间实用程序。

或者,各种网络管理器都提供对 WireGuard 的支持,前提是提供了对等密钥。有关详细信息,请参阅 #持久配置

图形客户端

  • wireguird — 一个用于 WireGuard 的 Linux GTK GUI 客户端。
https://github.com/UnnoTed/wireguird || wireguirdAUR

命令行工具

  • wg_tool — 用于管理服务器和用户的 WireGuard 配置的工具。
https://github.com/gene-git/wg_tool || wg_toolAUR
  • wg-client — 具有命令行和 GUI 的 Linux 客户端。
https://github.com/gene-git/wg-client || wg-clientAUR
https://git.flu0r1ne.net/wg2nd/about || wg2ndAUR

用法

本文或本节需要语言、wiki 语法或风格方面的改进。请参阅 Help:Style 作为参考。

原因: 无用的章节名称——本页所有内容都关于 WireGuard 用法。将 4 个子节移动到顶层可能更有意义。(在 Talk:WireGuard 中讨论)

以下命令演示了如何使用以下设置在两个或多个对等节点之间建立基本隧道

外部(公网)地址 内部 IP 地址 端口
域名 IPv4 地址 IPv6 地址 IPv4 地址 IPv6 地址
对等节点 A 198.51.100.101 2001:db8:a85b:70a:ffd4:ec1b:4650:a001 10.0.0.1/24 fdc9:281f:04d7:9ee9::1/64 UDP/51871
对等节点 B peer-b.example 203.0.113.102 2001:db8:40f0:147a:80ad:3e88:f8e9:b002 10.0.0.2/24 fdc9:281f:04d7:9ee9::2/64 UDP/51902
对等节点 C dynamic dynamic 10.0.0.3/24 fdc9:281f:04d7:9ee9::3/64 UDP/51993
提示: 所有对等节点可以使用相同的 UDP 端口。

外部地址应该已经存在。例如,如果 ICMP 回显请求未被阻止,则对等节点 A 应该能够通过其公共 IP 地址 ping 对等节点 B,反之亦然。

内部地址将是新地址,可以通过 ip(8) 实用程序手动创建,也可以通过网络管理软件创建,这些地址将在新的 WireGuard 网络内部使用。以下示例将使用 10.0.0.0/24 和 fdc9:281f:04d7:9ee9::/64 作为内部网络。IP 地址中的 /24/64CIDR

密钥生成

为每个对等节点创建私钥和公钥。如果连接数十个对等节点,可以选择考虑个性化密钥对来个性化 Base64 编码的公钥字符串。请参阅 #个性化密钥

要创建私钥,请运行

$ (umask 0077; wg genkey > peer_A.key)
注意: 建议仅允许所有者进行读取和写入访问。上述操作会在子 shell 中临时更改 umask,以确保访问(读/写权限)仅限于所有者。

要创建公钥

$ wg pubkey < peer_A.key > peer_A.pub

或者,一次完成所有操作

$ wg genkey | (umask 0077 && tee peer_A.key) | wg pubkey > peer_A.pub

还可以生成预共享密钥,以添加额外的对称密钥加密层,混合到已有的公钥加密中,以实现后量子抗性。应为每个对等节点对生成一个预共享密钥,并且不应重复使用。例如,三个互连的对等节点 A、B 和 C 将需要三个单独的预共享密钥,每个对等节点对一个。

使用以下命令为每个对等节点对生成预共享密钥(确保也为此使用 umask 0077

$ wg genpsk > peer_A-peer_B.psk
$ wg genpsk > peer_A-peer_C.psk
$ wg genpsk > peer_B-peer_C.psk

个性化密钥

目前,WireGuard 不支持注释或将人类可记忆的名称附加到密钥。这使得识别密钥的所有者变得困难,尤其是在使用多个密钥时。一种解决方案是生成一个包含一些熟悉字符的公钥(可能是所有者姓名或主机名的前几个字母等),可以使用 wireguard-vanity-addresswicuvanityAUR 来实现。

例如

$ wireguard-vanity-address --in 8 leslie
searching for 'leslie' in pubkey[0..10], one of every 214748364 keys should match
one core runs at 2.69e6 keys/s, CPU cores available: 16
est yield: 5.0 seconds per key, 200.10e-3 keys/s
hit Ctrl-C to stop
private wEoVMj92P+E3fQXVf9IixWJqpCqcnP/4OfvrB1g3zmY=  public LEsliEny+aMcWcRbh8Qf414XsQHSBOAFk3TaEk/aSD0=
private EAOwlGGqpHVbZ9ehaCspdBJt+lkMcCfkwiA5T5a4JFs=  public VlesLiEB5BFd//OD2ILKXviolfz+hodG6uZ+XjoalC8=
private UDWG4VWI+RzAGzNSnlC+0X4d3nk9goWPs/NRC5tX524=  public 9lESlieIFOlJFV6dG7Omao2WS+amWgshDdBYn8ahRjo=

手动配置

对等节点设置

手动设置通过使用 ip(8)wg(8) 完成。

注意: 这些示例使用在 #密钥生成 中作为可选引入的预共享密钥。如果不使用它们,只需忽略命令中的相应部分。

对等节点 A 设置

在本示例中,对等节点 A 将监听 UDP 端口 51871,并将接受来自对等节点 B 和 C 的连接。

# ip link add dev wg0 type wireguard
# ip addr add 10.0.0.1/24 dev wg0
# ip addr add fdc9:281f:04d7:9ee9::1/64 dev wg0
# wg set wg0 listen-port 51871 private-key /path/to/peer_A.key
# wg set wg0 peer PEER_B_PUBLIC_KEY preshared-key /path/to/peer_A-peer_B.psk endpoint peer-b.example:51902 allowed-ips 10.0.0.2/32,fdc9:281f:04d7:9ee9::2/128
# wg set wg0 peer PEER_C_PUBLIC_KEY preshared-key /path/to/peer_A-peer_C.psk allowed-ips 10.0.0.3/32,fdc9:281f:04d7:9ee9::3/128
# ip link set wg0 up

PEER_X_PUBLIC_KEY 应该是 peer_X.pub 的内容。

关键字 allowed-ips 是将路由到对等节点的地址列表。确保至少指定一个包含 WireGuard 连接的内部 IP 地址的地址范围。

对等节点 B 设置

# ip link add dev wg0 type wireguard
# ip addr add 10.0.0.2/24 dev wg0
# ip addr add fdc9:281f:04d7:9ee9::2/64 dev wg0
# wg set wg0 listen-port 51902 private-key /path/to/peer_B.key
# wg set wg0 peer PEER_A_PUBLIC_KEY preshared-key /path/to/peer_A-peer_B.psk endpoint 198.51.100.101:51871 allowed-ips 10.0.0.1/32,fdc9:281f:04d7:9ee9::1/128
# wg set wg0 peer PEER_C_PUBLIC_KEY preshared-key /path/to/peer_B-peer_C.psk allowed-ips 10.0.0.3/32,fdc9:281f:04d7:9ee9::3/128
# ip link set wg0 up

对等节点 C 设置

# ip link add dev wg0 type wireguard
# ip addr add 10.0.0.3/24 dev wg0
# ip addr add fdc9:281f:04d7:9ee9::3/64 dev wg0
# wg set wg0 listen-port 51993 private-key /path/to/peer_C.key
# wg set wg0 peer PEER_A_PUBLIC_KEY preshared-key /path/to/peer_A-peer_C.psk endpoint 198.51.100.101:51871 allowed-ips 10.0.0.1/32,fdc9:281f:04d7:9ee9::1/128
# wg set wg0 peer PEER_B_PUBLIC_KEY preshared-key /path/to/peer_B-peer_C.psk endpoint peer-b.example:51902 allowed-ips 10.0.0.2/32,fdc9:281f:04d7:9ee9::2/128
# ip link set wg0 up

额外路由

要建立比点对点更复杂的连接,需要额外的设置。

本文或本节需要扩充。

原因: 添加一个场景:只有对等节点 A 具有公共 IP 地址(即端点),对等节点 B 和 C(通常在 NAT 之后)使用 PersistentKeepalive 连接到对等节点 A,从对等节点 B 到对等节点 C 以及反之亦然的连接通过对等节点 A 路由。配置:对等节点 B 和 C 在对等节点 A 的 AllowedIPs 中具有 10.0.0.0/24,对等节点 A 必须通过防火墙规则启用数据包转发和伪装,例如 iptables -A FORWARD -i wg+ -j ACCEPTiptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o wg0 -j MASQUERADE。(在 Talk:WireGuard 中讨论)
点对站

要访问对等节点的网络,请在应该能够连接到它的对等节点的配置中的 allowed-ips 中指定网络子网。例如 allowed-ips 10.0.0.2/32,fdc9:281f:04d7:9ee9::2/128,192.168.35.0/24,fd7b:d0bd:7a6e::/64

确保也使用 路由表ip-route(8) 设置路由表。例如

# ip route add 192.168.35.0/24 dev wg0
# ip route add fd7b:d0bd:7a6e::/64 dev wg0
站对点

本文或本节需要扩充。

原因: 添加 ip route 示例;添加使用 NAT 的替代方案;提及站点对等节点是网络网关的情况。(在 Talk:WireGuard 中讨论)

如果目的是将设备连接到具有 WireGuard 对等节点的网络,请在每个设备上设置路由,以便它们知道可以通过该设备访问对等节点。

提示: 通过在路由器中配置路由,在全网络范围内部署路由。

之后,在网络中其他设备将通过其连接到 WireGuard 对等节点的对等节点上启用 IP 转发

站对站

要连接两个(或多个)网络,请在所有站点上应用 #点对站#站对点

通过 WireGuard 路由所有流量

本文或本节需要扩充。

原因: 添加关于如何[1]通过 VPN 路由所有内容的说明。已经有 #systemd-networkd:通过 WireGuard 路由所有流量。(在 Talk:WireGuard 中讨论)

要通过对等节点路由所有流量,请将 AllowedIPs 设置为所有已知的 IP 地址,即“AllowedIPs = 0.0.0.0/0, ::0”

在一个简单的 wg-quick 配置中,它会是这样的

对等节点 B 设置

/etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.2/24, fdc9:281f:04d7:9ee9::2/64
PrivateKey = DEADBEEF
DNS = 10.0.0.12

[Peer]
PublicKey = PEER_C_PUBLIC_KEY
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = 10.1.2.3:52180

更多解释和一些 python 代码来计算如何排除范围可以在这里找到。[2]

DNS

要将对等节点用作 DNS 服务器,请将其 WireGuard 隧道 IP 地址添加到 /etc/resolv.conf。例如,要使用对等节点 B 作为 DNS 服务器

/etc/resolv.conf
nameserver fdc9:281f:04d7:9ee9::2
nameserver 10.0.0.2
注意: 如果对等节点将充当 DNS 服务器,请务必使用其 WireGuard 隧道地址作为 DNS 服务器地址,而不是允许 IP 中的其他地址。否则,DNS 查询可能会失败。

基本检查

不带参数调用 wg(8) 命令将快速概述当前配置。

例如,当对等节点 A 已配置时,我们能够看到其身份及其关联的对等节点

# wg
interface: wg0
  public key: UguPyBThx/+xMXeTbRYkKlP0Wh/QZT3vTLPOVaaXTD8=
  private key: (hidden)
  listening port: 51871

peer: 9jalV3EEBnVXahro0pRMQ+cHlmjE33Slo9tddzCVtCw=
  endpoint: 203.0.113.102:51902
  allowed ips: 10.0.0.2/32, fdc9:281f:04d7:9ee9::2

peer: 2RzKFbGMx5g7fG0BrWCI7JIpGvcwGkqUaCoENYueJw4=
  endpoint: 192.0.2.103:51993
  allowed ips: 10.0.0.3/32, fdc9:281f:04d7:9ee9::3

此时,可以到达隧道的末端。如果对等节点不阻止 ICMP 回显请求,请尝试 ping 对等节点以测试它们之间的连接。

使用 ICMPv4

$ ping 10.0.0.2

使用 ICMPv6

$ ping fdc9:281f:04d7:9ee9::2

在对等节点之间传输一些数据后,wg 实用程序将显示其他信息

# wg
interface: wg0
  public key: UguPyBThx/+xMXeTbRYkKlP0Wh/QZT3vTLPOVaaXTD8=
  private key: (hidden)
  listening port: 51871

peer: 9jalV3EEBnVXahro0pRMQ+cHlmjE33Slo9tddzCVtCw=
  endpoint: 203.0.113.102:51902
  allowed ips: 10.0.0.2/32, fdc9:281f:04d7:9ee9::2
  latest handshake: 5 seconds ago
  transfer: 1.24 KiB received, 1.38 KiB sent

peer: 2RzKFbGMx5g7fG0BrWCI7JIpGvcwGkqUaCoENYueJw4=
  allowed ips: 10.0.0.3/32, fdc9:281f:04d7:9ee9::3

持久配置

可以使用 wg-quick@.service 实现持久配置,该服务随 wireguard-tools 一起提供,或使用网络管理器。支持 WireGuard 的网络管理器有 systemd-networkdnetctl[3]NetworkManagerConnMan[4]

注意
  • netctl 依赖于 wg(8) (来自 wireguard-tools) 和 /etc/wireguard/interfacename.conf 配置文件来建立 WireGuard 连接。
  • ConnMan 对 WireGuard 的支持非常有限。它只能连接到一个对等节点。[5]

wg-quick

wg-quick(8) 使用来自 /etc/wireguard/interfacename.conf 的配置文件配置 WireGuard 隧道。

当前的 WireGuard 配置可以通过使用 wg(8) 实用程序的 showconf 命令来保存。例如

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

要使用配置文件启动隧道,请使用

# wg-quick up interfacename

或使用 systemd 服务—wg-quick@interfacename.service。要在启动时启动隧道,启用 该单元。

注意
  • 使用 wg-quick 配置 WireGuard 接口的用户应确保没有其他 网络管理 软件尝试管理它。要使用 NetworkManager 且不使用它配置 WireGuard 接口,请参阅 #路由定期重置
  • wg-quick 向配置文件格式添加了其他配置选项,从而使其与 wg(8) § 配置文件格式 不兼容。有关相关配置值,请参阅 wg-quick(8) § 配置 手册页。可以通过使用 wg-quick strip 生成 wg 兼容的配置文件。
  • wg-quick 没有提供指示 resolvconf 将 WireGuard 接口设置为私有的方法。即使指定了搜索域,来自系统的所有 DNS 查询(而不仅仅是与搜索域匹配的查询)都将发送到 WireGuard 配置中设置的 DNS 服务器。

对等节点 A 设置

/etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.1/24, fdc9:281f:04d7:9ee9::1/64
ListenPort = 51871
PrivateKey = PEER_A_PRIVATE_KEY

[Peer]
PublicKey = PEER_B_PUBLIC_KEY
PresharedKey = PEER_A-PEER_B-PRESHARED_KEY
AllowedIPs = 10.0.0.2/32, fdc9:281f:04d7:9ee9::2/128
Endpoint = peer-b.example:51902

[Peer]
PublicKey = PEER_C_PUBLIC_KEY
PresharedKey = PEER_A-PEER_C-PRESHARED_KEY
AllowedIPs = 10.0.0.3/32, fdc9:281f:04d7:9ee9::3/128
  • 将所有流量路由通过隧道到特定对等节点,请将 默认路由 (IPv4 为 0.0.0.0/0,IPv6 为 ::/0) 添加到 AllowedIPs。例如,AllowedIPs = 0.0.0.0/0, ::/0。wg-quick 将自动处理设置正确的路由和 fwmark[6],以便网络仍然正常运行。
  • 要将对等节点用作 DNS 服务器,请在 [Interface] 部分中设置 DNS = wireguard_internal_ip_address_of_peer搜索域 也使用 DNS = 选项设置。用逗号分隔列表中的所有值。

对等节点 B 设置

/etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.2/24, fdc9:281f:04d7:9ee9::2/64
ListenPort = 51902
PrivateKey = PEER_B_PRIVATE_KEY

[Peer]
PublicKey = PEER_A_PUBLIC_KEY
PresharedKey = PEER_A-PEER_B-PRESHARED_KEY
AllowedIPs = 10.0.0.1/32, fdc9:281f:04d7:9ee9::1/128
Endpoint = 198.51.100.101:51871

[Peer]
PublicKey = PEER_C_PUBLIC_KEY
PresharedKey = PEER_B-PEER_C-PRESHARED_KEY
AllowedIPs = 10.0.0.3/32, fdc9:281f:04d7:9ee9::3/128

对等节点 C 设置

/etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.3/24, fdc9:281f:04d7:9ee9::3/64
ListenPort = 51993
PrivateKey = PEER_C_PRIVATE_KEY

[Peer]
PublicKey = PEER_A_PUBLIC_KEY
PresharedKey = PEER_A-PEER_C-PRESHARED_KEY
AllowedIPs = 10.0.0.1/32, fdc9:281f:04d7:9ee9::1/128
Endpoint = 198.51.100.101:51871

[Peer]
PublicKey = PEER_B_PUBLIC_KEY
PresharedKey = PEER_B-PEER_C-PRESHARED_KEY
AllowedIPs = 10.0.0.2/32, fdc9:281f:04d7:9ee9::2/128
Endpoint = peer-b.example:51902

systemd-networkd

systemd-networkd 原生支持设置 WireGuard 接口。systemd.netdev(5) § 示例 手册页中提供了一个示例。

注意: 将所有 DNS 都路由到 WireGuard (即 Domains=~.) 将阻止端点的 DNS 解析。除非对等节点域配置为在特定网络链接上解析。

对等节点 A 设置

/etc/systemd/network/99-wg0.netdev
[NetDev]
Name=wg0
Kind=wireguard
Description=WireGuard tunnel wg0

[WireGuard]
ListenPort=51871
PrivateKey=PEER_A_PRIVATE_KEY

[WireGuardPeer]
PublicKey=PEER_B_PUBLIC_KEY
PresharedKey=PEER_A-PEER_B-PRESHARED_KEY
AllowedIPs=10.0.0.2/32
AllowedIPs=fdc9:281f:04d7:9ee9::2/128
Endpoint=peer-b.example:51902

[WireGuardPeer]
PublicKey=PEER_C_PUBLIC_KEY
PresharedKey=PEER_A-PEER_C-PRESHARED_KEY
AllowedIPs=10.0.0.3/32
AllowedIPs=fdc9:281f:04d7:9ee9::3/128
/etc/systemd/network/99-wg0.network
[Match]
Name=wg0

[Network]
Address=10.0.0.1/24
Address=fdc9:281f:04d7:9ee9::1/64
  • 要将对等节点用作 DNS 服务器,请使用 DNS= 选项在 .network 文件中指定其 WireGuard 隧道 IP 地址。对于 搜索域,请使用 Domains= 选项。有关详细信息,请参阅 systemd.network(5) § [NETWORK] SECTION OPTIONS
  • 要将对等节点用作唯一 DNS 服务器,请在 .network 文件的 [Network] 部分中设置 DNSDefaultRoute=trueDomains=~
  • 要路由其他子网,请将它们作为 [Route] 部分添加到 .network 文件中。例如
/etc/systemd/network/99-wg0.network
...
[Route]
Destination=192.168.35.0/24
Scope=link

[Route]
Destination=fd7b:d0bd:7a6e::/64
Scope=link
警告: 为了防止泄露私钥,建议设置 .netdev 文件的权限
# chown root:systemd-network /etc/systemd/network/99-wg*.netdev
# chmod 0640 /etc/systemd/network/99-wg*.netdev

对等节点 B 设置

/etc/systemd/network/99-wg0.netdev
[NetDev]
Name=wg0
Kind=wireguard
Description=WireGuard tunnel wg0

[WireGuard]
ListenPort=51902
PrivateKey=PEER_B_PRIVATE_KEY

[WireGuardPeer]
PublicKey=PEER_A_PUBLIC_KEY
PresharedKey=PEER_A-PEER_B-PRESHARED_KEY
AllowedIPs=10.0.0.1/32
AllowedIPs=fdc9:281f:04d7:9ee9::1/128
Endpoint=198.51.100.101:51871

[WireGuardPeer]
PublicKey=PEER_C_PUBLIC_KEY
PresharedKey=PEER_B-PEER_C-PRESHARED_KEY
AllowedIPs=10.0.0.3/32
AllowedIPs=fdc9:281f:04d7:9ee9::3/128
/etc/systemd/network/99-wg0.network
[Match]
Name=wg0

[Network]
Address=10.0.0.2/24
Address=fdc9:281f:04d7:9ee9::2/64

对等节点 C 设置

/etc/systemd/network/99-wg0.netdev
[NetDev]
Name=wg0
Kind=wireguard
Description=WireGuard tunnel wg0

[WireGuard]
ListenPort=51993
PrivateKey=PEER_C_PRIVATE_KEY

[WireGuardPeer]
PublicKey=PEER_A_PUBLIC_KEY
PresharedKey=PEER_A-PEER_C-PRESHARED_KEY
AllowedIPs=10.0.0.1/32
AllowedIPs=fdc9:281f:04d7:9ee9::1/128
Endpoint=198.51.100.101:51871

[WireGuardPeer]
PublicKey=PEER_B_PUBLIC_KEY
PresharedKey=PEER_B-PEER_C-PRESHARED_KEY
AllowedIPs=10.0.0.2/32
AllowedIPs=fdc9:281f:04d7:9ee9::2/128
Endpoint=peer-b.example:51902
/etc/systemd/network/99-wg0.network
[Match]
Name=wg0

[Network]
Address=10.0.0.3/24
Address=fdc9:281f:04d7:9ee9::3/64

systemd-networkd:将所有流量路由到 WireGuard

在此示例中,对等节点 B 连接到具有公共 IP 地址的对等节点 A。对等节点 B 将其所有流量路由到 WireGuard 隧道,并使用对等节点 A 处理 DNS 请求。

对等节点 A 设置

/etc/systemd/network/99-wg0.netdev
[NetDev]
Name=wg0
Kind=wireguard
Description=WireGuard tunnel wg0

[WireGuard]
ListenPort=51871
PrivateKey=PEER_A_PRIVATE_KEY

[WireGuardPeer]
PublicKey=PEER_B_PUBLIC_KEY
PresharedKey=PEER_A-PEER_B-PRESHARED_KEY
AllowedIPs=10.0.0.2/32
/etc/systemd/network/99-wg0.network
[Match]
Name=wg0

[Network]
Address=10.0.0.1/24
注意: 在对等节点 A 上启用 IP 转发 和 IP 伪装规则,以便为对等节点 B 提供可用的互联网。

假设使用 ufw,但 iptables 可以通过使用 服务器配置 部分中概述的规则来做到相同的事情

$ ufw route allow in on wg0 out on enp5s0
/etc/ufw/before.rules
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.0.0.0/24 -o enp5s0 -j MASQUERADE
COMMIT

对等节点 B 设置

/etc/systemd/network/99-wg0.netdev
[NetDev]
Name=wg0
Kind=wireguard
Description=WireGuard tunnel wg0

[WireGuard]
ListenPort=51902
PrivateKey=PEER_B_PRIVATE_KEY
FirewallMark=0x8888

[WireGuardPeer]
PublicKey=PEER_A_PUBLIC_KEY
PresharedKey=PEER_A-PEER_B-PRESHARED_KEY
AllowedIPs=0.0.0.0/0
Endpoint=198.51.100.101:51871
/etc/systemd/network/50-wg0.network
[Match]
Name=wg0

[Network]
Address=10.0.0.2/24
DNS=10.0.0.1
DNSDefaultRoute=true
Domains=~.

[RoutingPolicyRule]
FirewallMark=0x8888
InvertRule=true
Table=1000
Priority=10

# Exempt the endpoint IP address so that wireguard can still connect to it.
[RoutingPolicyRule]
To=198.51.100.101/32
Priority=5

[Route]
Destination=0.0.0.0/0
Table=1000

豁免特定地址

为了豁免特定地址(例如私有 LAN 地址)不通过 WireGuard 隧道路由,请将它们添加到另一个具有更高优先级的 RoutingPolicyRule。

/etc/systemd/network/50-wg0.network
...

[RoutingPolicyRule]
To=192.168.0.0/24
Priority=9

...

特定用户的路由

可能需要仅为特定用户(例如 transmission 用户)通过隧道路由 WAN 流量,以便将隧道用于 torrent 流量。

/etc/systemd/network/99-wg0.network
...

[RoutingPolicyRule]
Table=8677
User=transmission
Priority=30001
Family=both

[RoutingPolicyRule]
Table=main
User=transmission
SuppressPrefixLength=0
Priority=30000
Family=both

...
/etc/systemd/network/99-wg0.netdev
...

[WireGuard]
PrivateKey='PEER_PRIVATE_KEY'
RouteTable=8677

...

Netctl

Netctl 原生支持设置 WireGuard 接口。典型的 WireGuard netctl 配置文件集如下所示

对等节点 A 设置

/etc/netctl/wg0
Description="WireGuard tunnel on peer A"
Interface=wg0
Connection=wireguard
WGConfigFile=/etc/wireguard/wg0.conf

IP=static
Address=('10.0.0.1/24')
/etc/wireguard/wg0.conf
[Interface]
ListenPort = 51871
PrivateKey = PEER_A_PRIVATE_KEY

[Peer]
PublicKey = PEER_B_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
Endpoint = peer-b.example:51902

[Peer]
PublicKey = PEER_C_PUBLIC_KEY
AllowedIPs = 10.0.0.3/32

对等节点 B 设置

/etc/netctl/wg0
Description="WireGuard tunnel on peer B"
Interface=wg0
Connection=wireguard
WGConfigFile=/etc/wireguard/wg0.conf

IP=static
Address=('10.0.0.2/24')
/etc/wireguard/wg0.conf
[Interface]
ListenPort = 51902
PrivateKey = PEER_B_PRIVATE_KEY

[Peer]
PublicKey = PEER_A_PUBLIC_KEY
AllowedIPs = 10.0.0.1/32
Endpoint = peer-a.example:51871

[Peer]
PublicKey = PEER_C_PUBLIC_KEY
AllowedIPs = 10.0.0.3/32

对等节点 C 设置

/etc/netctl/wg0
Description="WireGuard tunnel on peer C"
Interface=wg0
Connection=wireguard
WGConfigFile=/etc/wireguard/wg0.conf

IP=static
Address=('10.0.0.3/24')
/etc/wireguard/wg0.conf
[Interface]
ListenPort = 51993
PrivateKey = PEER_C_PRIVATE_KEY

[Peer]
PublicKey = PEER_A_PUBLIC_KEY
AllowedIPs = 10.0.0.1/32
Endpoint = peer-a.example:51871

[Peer]
PublicKey = PEER_B_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
Endpoint = peer-b.example:51902

然后根据需要在每个参与的对等节点上启动和/或启用 wg0 接口,即

# netctl start wg0

要使用 WireGuard 和 Netctl 实现持久的站点到对等、对等到站点或站点到站点类型的连接,只需将适当的 Routes= 行添加到 netctl 配置文件中,并将此网络添加到 WireGuard 配置文件中的 AllowedIPs 中,例如 /etc/netctl/wg0 中的 Routes=('192.168.10.0/24 dev wg0')/etc/wireguard/wg0.conf 中的 AllowedIPs=10.0.0.1/32, 192.168.10.0/24,然后不要忘记启用 IP 转发

NetworkManager

NetworkManager 原生支持设置 WireGuard 接口。有关 NetworkManager 中 WireGuard 用法的所有详细信息,请阅读 Thomas Haller 的博客文章—NetworkManager 中的 WireGuard

提示: NetworkManager 可以导入 wg-quick 配置文件。例如
# nmcli connection import type wireguard file /etc/wireguard/wg0.conf
注意: nmcli 可以创建 WireGuard 连接配置文件,但它不支持配置对等节点。请参阅 NetworkManager 问题 358

以下示例通过 keyfile 格式 .nmconnection 文件配置 WireGuard。有关语法和可用选项的说明,请参阅 nm-settings-keyfile(5)nm-settings(5)

对等节点 A 设置

/etc/NetworkManager/system-connections/wg0.nmconnection
[connection]
id=wg0
type=wireguard
interface-name=wg0

[wireguard]
listen-port=51871
private-key=PEER_A_PRIVATE_KEY
private-key-flags=0

[wireguard-peer.PEER_B_PUBLIC_KEY]
endpoint=peer-b.example:51902
preshared-key=PEER_A-PEER_B-PRESHARED_KEY
preshared-key-flags=0
allowed-ips=10.0.0.2/32;fdc9:281f:04d7:9ee9::2/128;

[wireguard-peer.PEER_C_PUBLIC_KEY]
preshared-key=PEER_A-PEER_C-PRESHARED_KEY
preshared-key-flags=0
allowed-ips=10.0.0.3/32;fdc9:281f:04d7:9ee9::3/128;

[ipv4]
address1=10.0.0.1/24
method=manual

[ipv6]
address1=fdc9:281f:04d7:9ee9::1/64
method=manual
  • 将所有流量路由通过隧道到特定对等节点,请将 默认路由 (IPv4 为 0.0.0.0/0,IPv6 为 ::/0) 添加到 wireguard-peer.PEER_X_PUBLIC_KEY.allowed-ips。例如 wireguard-peer.PEER_B_PUBLIC_KEY.allowed-ips=0.0.0.0/0;::/0;。NetworkManager 1.20.0 及更高版本支持 WireGuard 连接中默认路由的特殊处理。
  • 要将对等节点用作 DNS 服务器,请使用 ipv4.dnsipv6.dns 设置指定其 WireGuard 隧道 IP 地址。搜索域 可以使用 ipv4.dns-search=ipv6.dns-search= 选项指定。有关更多详细信息,请参阅 nm-settings(5)。例如,使用 keyfile 格式
...
[ipv4]
...
dns=10.0.0.2;
dns-search=corp;
...
[ipv6]
...
dns=fdc9:281f:04d7:9ee9::2;
dns-search=corp;
...

要将对等节点用作唯一 DNS 服务器,请设置负 DNS 优先级(例如 dns-priority=-1)并将 ~. 添加到 dns-search= 设置。

对等节点 B 设置

/etc/NetworkManager/system-connections/wg0.nmconnection
[connection]
id=wg0
type=wireguard
interface-name=wg0

[wireguard]
listen-port=51902
private-key=PEER_B_PRIVATE_KEY
private-key-flags=0

[wireguard-peer.PEER_A_PUBLIC_KEY]
endpoint=198.51.100.101:51871
preshared-key=PEER_A-PEER_B-PRESHARED_KEY
preshared-key-flags=0
allowed-ips=10.0.0.1/32;fdc9:281f:04d7:9ee9::1/128;

[wireguard-peer.PEER_C_PUBLIC_KEY]
preshared-key=PEER_B-PEER_C-PRESHARED_KEY
preshared-key-flags=0
allowed-ips=10.0.0.3/32;fdc9:281f:04d7:9ee9::3/128;

[ipv4]
address1=10.0.0.2/24
method=manual

[ipv6]
address1=fdc9:281f:04d7:9ee9::2/64
method=manual

对等节点 C 设置

/etc/NetworkManager/system-connections/wg0.nmconnection
[connection]
id=wg0
type=wireguard
interface-name=wg0

[wireguard]
listen-port=51993
private-key=PEER_C_PRIVATE_KEY
private-key-flags=0

[wireguard-peer.PEER_A_PUBLIC_KEY]
endpoint=198.51.100.101:51871
preshared-key=PEER_A-PEER_C-PRESHARED_KEY
preshared-key-flags=0
allowed-ips=10.0.0.1/32;fdc9:281f:04d7:9ee9::1/128;

[wireguard-peer.PEER_B_PUBLIC_KEY]
endpoint=peer-b.example:51902
preshared-key=PEER_B-PEER_C-PRESHARED_KEY
preshared-key-flags=0
allowed-ips=10.0.0.2/32;fdc9:281f:04d7:9ee9::2/128;

[ipv4]
address1=10.0.0.3/24
method=manual

[ipv6]
address1=fdc9:281f:04d7:9ee9::3/64
method=manual

特定用例:VPN 服务器

本文或本节是与 #将所有流量路由到 WireGuard 合并的候选对象。

注意: 相同的用例。(在 Talk:WireGuard 中讨论)
注意: 本节中有意选择使用术语“服务器”和“客户端”,专门用于帮助新用户/现有 OpenVPN 用户熟悉 WireGuard 配置文件的构造。WireGuard 文档仅将这两个概念都称为“对等节点”。

本节的目的是设置 WireGuard“服务器”和通用“客户端”,以通过加密和安全的隧道(如 OpenVPN 等)启用对服务器/网络资源的访问。“服务器”在 Linux 上运行,“客户端”可以在任意数量的平台上运行(WireGuard 项目除了 Linux、Windows 和 MacOS 之外,还提供 iOS 和 Android 平台上的应用程序)。有关更多信息,请参阅官方项目 安装链接

提示: 除了使用 wireguard-tools 进行服务器/客户端配置外,还可以使用 systemd-networkd 原生 WireGuard 支持。

服务器

本文或本节是与 #站点到点 合并的候选对象。

注意: 相同的用例。(在 Talk:WireGuard 中讨论)

在将充当“服务器”的对等节点上,首先 启用 IPv4 转发

如果服务器配置了公共 IP,请务必

  • 在 WireGuard 将运行的指定端口上允许 UDP 流量(例如,允许 51820/UDP 上的流量)。
  • 如果防火墙的转发策略未包含在接口本身的 WireGuard 配置 /etc/wireguard/wg0.conf 中,请设置防火墙的转发策略。以下示例应具有 iptables 规则并按原样工作。

如果服务器位于 NAT 之后,请务必将 WireGuard 将运行的指定端口(例如,51820/UDP)从路由器转发到 WireGuard 服务器。

密钥生成

按照 #密钥生成 中的说明为服务器和每个客户端生成密钥对。

服务器配置

创建“服务器”配置文件

/etc/wireguard/wg0.conf
[Interface]
Address = 10.200.200.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY

# substitute eth0 in the following lines to match the Internet-facing interface
# the FORWARD rules will always be needed since traffic needs to be forwarded between the WireGuard
# interface and the other interfaces on the server.
# if the server is behind a router and receives traffic via NAT, specify static routing back to the
# 10.200.200.0/24 subnet, the NAT iptables rules are not needed but the FORWARD rules are needed.
# if the server is behind a router and receives traffic via NAT but one cannot specify static routing back to
# 10.200.200.0/24 subnet, both the NAT and FORWARD iptables rules are needed. 
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

[Peer]
# foo
PublicKey = PEER_FOO_PUBLIC_KEY
PresharedKey = PRE-SHARED_KEY
AllowedIPs = 10.200.200.2/32

[Peer]
# bar
PublicKey = PEER_BAR_PUBLIC_KEY
PresharedKey = PRE-SHARED_KEY
AllowedIPs = 10.200.200.3/32

其他对等节点(“客户端”)可以根据需要以相同的格式列出。每个对等节点都需要设置 PublicKey。但是,指定 PresharedKey 是可选的。

请注意,Address 的网络掩码为 /24,而 AllowedIPs 上的客户端为 /32。客户端仅使用其 IP,服务器仅发回其各自的地址。

可以使用 wg-quick(8) 手动管理接口,或使用通过 systemctl(1) 管理的 systemd 服务来管理。

可以使用 wg-quick up wg0 分别通过 启动 并可能 启用 通过 wg-quick@interface.service 的接口来启动接口,例如 wg-quick@wg0.service。要关闭接口,请使用 wg-quick down wg0 分别 停止 wg-quick@interface.service

客户端配置

创建相应的 “客户端” 配置文件

foo.conf
[Interface]
Address = 10.200.200.2/32
PrivateKey = PEER_FOO_PRIVATE_KEY
DNS = 10.200.200.1

[Peer]
PublicKey = SERVER_PUBLICKEY
PresharedKey = PRE-SHARED_KEY
Endpoint = my.ddns.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
bar.conf
[Interface]
Address = 10.200.200.3/32
PrivateKey = PEER_BAR_PRIVATE_KEY
DNS = 10.200.200.1

[Peer]
PublicKey = SERVER_PUBLICKEY
PresharedKey = PRE-SHARED KEY
Endpoint = my.ddns.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0

使用通配符 AllowedIPs = 0.0.0.0/0, ::/0 将转发所有 IPv4 (0.0.0.0/0) 和 IPv6 (::/0) 流量通过 VPN。

注意: NetworkManager 的用户可能需要启用 NetworkManager-wait-online.service,而 systemd-networkd 的用户可能需要启用 systemd-networkd-wait-online.service,以等待设备准备好网络后再尝试 WireGuard 连接。

测试隧道

这篇文章或章节可能需要与 #基本检查 合并。

注意: 相同主题。(在 Talk:WireGuard 中讨论)

一旦隧道建立,可以使用 netcat 发送流量以测试吞吐量、CPU 使用率等。在隧道的一侧,在监听模式下运行 nc,在另一侧,将来自 /dev/zero 的一些数据通过管道传输到发送模式下的 nc

在下面的示例中,端口 2222 用于流量(如果使用防火墙,请务必允许端口 2222 上的流量)。

在隧道的一侧监听流量

$ nc -vvlnp 2222

在隧道的另一侧,发送一些流量

$ dd if=/dev/zero bs=1024K count=1024 | nc -v 10.0.0.203 2222

可以使用 wg 直接监控状态。

# wg
interface: wg0
  public key: UguPyBThx/+xMXeTbRYkKlP0Wh/QZT3vTLPOVaaXTD8=
  private key: (hidden)
  listening port: 51820

peer: 9jalV3EEBnVXahro0pRMQ+cHlmjE33Slo9tddzCVtCw=
  preshared key: (hidden)
  endpoint: 192.168.1.216:53207
  allowed ips: 10.0.0.0/0
  latest handshake: 1 minutes, 17 seconds ago
  transfer: 56.43 GiB received, 1.06 TiB sent

技巧和窍门

以加密形式存储私钥 (wg-quick)

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

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

其中 user 是感兴趣的 Linux 用户名。有关更多详细信息,请参阅 wg-quick(8) 手册页。

或者,可以使用 systemd-creds。这有助于创建绑定到系统 TPM 的加密私钥。有关更多详细信息,请参阅 systemd-creds(1)

首先,创建一个加密凭据

# echo -n your_wg_private_key | systemd-creds --tpm2-device=auto encrypt - /etc/credstore.encrypted/wg-private-key.cred

最后,将 WireGuard 配置文件中 [Interface] 下的 PrivateKey 行替换为

PostUp = wg set %i private-key <(systemd-creds decrypt /etc/credstore.encrypted/wg-private-key.cred)

使用 systemd 凭据作为私钥 (systemd-networkd)

您可以使用 systemd-creds 加密存储您的私钥。

# echo -n your_wg_private_key | systemd-creds encrypt - /etc/credstore.encrypted/network.wireguard.private.wg0
# echo -n your_pre_shared_key | systemd-creds encrypt - /etc/credstore.encrypted/network.wireguard.psk.wg0
注意: 存储名称必须匹配 network.wireguard.*。请参阅 systemd.netdev(5) § [WIREGUARD]_SECTION_OPTIONS

修改您的 .netdev 文件以使用

PrivateKey = @network.wireguard.private.wg0
PresharedKey = @network.wireguard.psk.wg0

具有更改 IP 的端点

在解析服务器域名后,WireGuard 将不再检查 DNS 中的更改

如果 WireGuard 服务器的 IP 地址经常因 DHCP、Dyndns、IPv6 等而更改,则任何 WireGuard 客户端都将丢失其连接,直到通过类似 wg set "$INTERFACE" peer "$PUBLIC_KEY" endpoint "$ENDPOINT" 的命令更新其端点。

另请注意,如果端点将要更改其地址(例如,当移动到新的提供商/数据中心时),仅更新 DNS 是不够的,因此在任何基于 DNS 的设置上定期运行 reresolve-dns 可能是有意义的。

幸运的是,wireguard-tools 提供了一个示例脚本 /usr/share/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh,该脚本解析 WG 配置文件并自动重置端点地址。

需要定期运行 /usr/share/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh /etc/wireguard/wg.conf,以从已更改 IP 的端点恢复。

一种方法是每三十秒更新所有 WireGuard 端点一次[7],通过 systemd 计时器

/etc/systemd/system/wireguard_reresolve-dns.timer
[Unit]
Description=Periodically reresolve DNS of all WireGuard endpoints

[Timer]
OnCalendar=*:*:0/30

[Install]
WantedBy=timers.target
/etc/systemd/system/wireguard_reresolve-dns.service
[Unit]
Description=Reresolve DNS of all WireGuard endpoints
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'for i in /etc/wireguard/*.conf; do /usr/share/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh "$i"; done'

之后,启用启动 wireguard_reresolve-dns.timer

生成二维码

如果客户端是手机等移动设备,可以使用 qrencode 生成客户端配置二维码并在终端中显示

$ qrencode -t ansiutf8 -r client.conf

启用调试日志

当在支持动态调试的内核上使用 Linux 内核模块时,可以通过运行以下命令将调试信息写入内核环缓冲区(可以使用 dmesgjournalctl 查看)

# modprobe wireguard
# echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control

重新加载对等端(服务器)配置

如果 WireGuard 对等端(主要是服务器)在其配置中添加或删除另一个对等端,并希望在不停止任何活动会话的情况下重新加载配置,则可以执行以下命令来执行此操作

# wg syncconf ${WGNET} <(wg-quick strip ${WGNET})

其中 $WGNET 是 WireGuard 接口名称或配置基本名称,例如 wg0(对于服务器)或 client(不带 .conf 扩展名,对于客户端)。

wg-quick@.service 的用户可以简单地重新加载该服务。

本文或本节需要扩充。

原因: 展示如何使用来自 #持久配置 的其他网络管理器执行此操作。(在 Talk:WireGuard 中讨论)

针对某些公共 Wi-Fi 网络似乎阻止 WireGuard 连接的解决方法

注意: 仅当设备上提供蜂窝网络连接时,此解决方法才是一种选择。

某些 Wi-Fi 网络可以配置为主动识别并阻止 WireGuard 的握手,从而阻止初始连接并阻止建立安全隧道。

此策略适用于阻止新的 WireGuard 连接,但对于现有的连接则毫无用处。因此,为了在此类网络上使用 WireGuard,只需在加入 Wi-Fi 网络之前通过蜂窝网络连接到 WireGuard 对等端,从而允许在主动阻止发生之前进行握手。当设备从蜂窝网络过渡到 Wi-Fi 时,WireGuard 将保持此隧道打开。

故障排除

路由被定期重置

NetworkManager 的用户应确保它未管理 WireGuard 接口。例如,创建以下配置文件

/etc/NetworkManager/conf.d/unmanaged.conf
[keyfile]
unmanaged-devices=type:wireguard

DNS 解析中断

当通过 WireGuard 接口隧道传输所有流量时,连接可能会在一段时间后或在新连接时看似丢失。这可能是由 网络管理器DHCP 客户端覆盖 /etc/resolv.conf 引起的。

默认情况下,wg-quick 使用 resolvconf 注册新的 DNS 条目(来自配置文件中的 DNS 关键字)。这将导致与不使用 resolvconf网络管理器DHCP 客户端出现问题,因为它们将覆盖 /etc/resolv.conf,从而删除 wg-quick 添加的 DNS 服务器。

解决方案是使用支持 resolvconf 的网络软件。

注意: systemd-resolved 的用户应确保 systemd-resolvconf安装

NetworkManager 的用户应该知道它默认不使用 resolvconf。建议使用 systemd-resolved。如果这是不可取的,安装 openresolv 并配置 NetworkManager 以使用它:NetworkManager#使用 openresolv

调整 MTU 值

默认的 Wireguard 最大传输单元 (MTU) 值为 1420

由于 MTU 过低(低于 1280),wg-quick 可能无法创建 WireGuard 接口。可以通过在客户端的 Interface 部分的 WireGuard 配置中设置 MTU 值来解决此问题。

foo.config
[Interface]
Address = 10.200.200.2/24
MTU = 1420
PrivateKey = PEER_FOO_PRIVATE_KEY
DNS = 10.200.200.1

根据您的网络,较低的 MTU 值也可能使您的 WireGuard 连接工作。

在某些情况下,较大的 MTU 值可能会导致连接不稳定或间歇性连接,因为沿着路由的 路径 MTU 发现 (PMTU) 不可靠。这可能会导致 ICMP ping 因其数据包大小较小而工作,但大多数 TCP 连接因完全利用 MTU 大小而失败的情况。例如,IPv6 连接比 IPv4 具有更高的数据包开销,因此在相同的 MTU 值下,可能会更早发生分片。

值得检查对等端和涉及的其他路由器上的链路 MTU 大小,以确定最小值。

# ip link show
5: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1400 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/none

另一种选择是回退到 MTU 为 1280,并通过试错方法找到给定路径的合适值。

1420 及以上的 MTU 可能会导致部分链路断开,这可能被解释为防火墙或路由问题,而不是实际的 MTU 大小。

密钥的长度或格式不正确

为避免以下错误,请将密钥值放在配置文件中,而不是密钥文件的路径。

# wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
Key is not the correct length or format: `/path/example.key'
Configuration parsing error
[#] ip link delete dev wg0

无法在 NAT / 防火墙后建立持久连接

默认情况下,WireGuard 对等端在不需要通信时保持沉默,因此位于 NAT 和/或 防火墙 后的对等端可能无法从其他对等端访问,直到它们自己联系其他对等端(或连接可能超时)。在位于 NAT 和/或防火墙后的对等端的 [Peer] 设置中添加 PersistentKeepalive = 25 可以确保连接保持打开状态。

要通过命令行临时设置持久保持活动设置,请运行以下命令

# wg set wg0 peer public_key persistent-keepalive 25

环路路由

将端点 IP 添加到允许的 IP 列表,内核将尝试向所述设备绑定发送握手,而不是使用原始路由。这会导致握手尝试失败。

作为一种解决方法,需要使用以下命令手动添加到端点的正确路由

# ip route add endpoint_ip via gateway dev network_interface

例如,对于标准 LAN 设置中上述的对等端 B

# ip route add 203.0.113.102 via 192.168.0.1 dev eth0

为了使此路由持久化,可以将该命令作为 PostUp = ip route ... 添加到 wg0.conf[Interface] 部分。但是,在某些设置(例如,将 wg-quick@.service 与 NetworkManager 结合使用)中,这可能会在恢复时失败。此外,这仅适用于静态网络设置,如果网关或设备发生更改(例如,在笔记本电脑上使用以太网或 Wi-Fi),则会失败。

使用 NetworkManager,更灵活的解决方案是使用调度器脚本启动 WireGuard。以 root 身份创建

/etc/NetworkManager/dispatcher.d/50-wg0.sh
#!/bin/sh
case $2 in
  up)
    wg-quick up wg0
    ip route add <endpoint ip> via $IP4_GATEWAY dev $DEVICE_IP_IFACE
    ;;
  pre-down)
    wg-quick down wg0
    ;;
esac

如果尚未运行,请启动并启用 NetworkManager-dispatcher.service。还要确保 NetworkManager 未管理 wg0 的路由,请参阅 #路由被定期重置

使用 systemd-networkd 在睡眠后连接丢失

systemd 版本 253 引入了关于如何重新配置从挂起状态恢复时网络接口的更改[8]。这样做时,由 systemd-networkd 管理的网络连接将丢失与 wireguard 接口的连接。除非配置了终止开关,否则这会带来在从挂起状态恢复后暴露公共 IP 地址的风险。要解决此问题,请在 /etc/systemd/networkd.conf 中取消注释并将 ManageForeignRoutingPolicyRules 的值更改为 no[9]

完整查看 systemd-networkd 页面,以了解此更改的任何其他潜在副作用(如果有)。

另请参阅