WireGuard

来自 ArchWiki

来自 WireGuard 项目主页

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

本文中使用的主要概念的粗略介绍可以在 WireGuard 项目主页上找到。自 2019 年末以来,WireGuard 已包含在 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 动态 动态 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-address,或者也可以使用 wicuvanityAUR 来做到这一点。

例如

$ 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 地址(即 endpoint),对等点 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 路由所有流量

本文或章节需要扩充。

原因: 添加关于如何通过 VPN 路由所有内容的说明。[1] 已经有 #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 隧道。

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

# 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
  • 通过隧道所有流量路由到特定对等点,请将默认路由 (0.0.0.0/0 用于 IPv4,::/0 用于 IPv6) 添加到 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) § 示例 手册页中提供了一个示例。

注意: 通过 WireGuard 路由所有 DNS (即 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] 部分选项
  • 要使用对等点作为唯一 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

以下示例通过密钥文件格式 .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
  • 通过隧道所有流量路由到特定对等点,请将默认路由 (0.0.0.0/0 用于 IPv4,::/0 用于 IPv6) 添加到 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)。例如,使用密钥文件格式
...
[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 项目在 iOS 和 Android 平台上以及 Linux、Windows 和 MacOS 上提供应用程序)。有关更多信息,请参阅官方项目安装链接

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

服务器

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

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

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

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

  • 允许在 WireGuard 将运行的指定端口(例如,允许 51820/UDP 上的流量)上的 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 将通过 VPN 转发所有 IPv4 (0.0.0.0/0) 和 IPv6 (::/0) 流量。

注意: NetworkManager 的用户可能需要启用 NetworkManager-wait-online.servicesystemd-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 服务器由于 DHCP、Dyndns、IPv6 等原因频繁更改其 IP 地址,则任何 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 的端点恢复。

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

/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 接口。这可以通过在客户端 WireGuard 配置文件的 Interface 部分中设置 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

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

MTU 为 `1420` 及以上可能会导致部分链接断开,这可能被解释为防火墙或路由问题,而不是实际的 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]` 部分。但是,在某些设置(例如,结合 NetworkManager 使用 `wg-quick@.service`)中,这可能会在恢复时失败。此外,这仅适用于静态网络设置,如果网关或设备发生更改(例如,在笔记本电脑上使用以太网或 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 页面,以了解此更改的任何其他潜在副作用(如果有)。

参见