WireGuard
来自 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 客户端。
- wireguard-gui — 使用 nextauri 构建的 Linux Wireguard 客户端 GUI。
命令行工具
- wg_tool — 用于管理服务器和用户的 WireGuard 配置的工具。
- wg-client — 具有命令行和 GUI 的 Linux 客户端。
- wg2nd — 一个将 WireGuard 配置从 wg-quick(8) 格式转换为与 systemd-networkd 兼容的配置的工具。
用法
以下命令演示了如何在两个或多个对等点之间设置具有以下设置的基本隧道
| 外部(公共)地址 | 内部 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: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 | |
外部地址应已存在。例如,如果 ICMP 回显请求未被阻止,对等点 A 应该可以通过其公共 IP 地址(或多个地址)ping 对等点 B,反之亦然。
内部地址将是新创建的地址,可以通过使用 ip(8) 工具手动创建,或通过网络管理软件创建,这些地址将在新的 WireGuard 网络内部使用。以下示例将使用 10.0.0.0/24 和 fdc9:281f:04d7:9ee9::/64 作为内部网络。IP 地址中的 /24 和 /64 是 CIDR。
密钥生成
为每个对等点生成一个私钥和一个公钥。如果连接数十个对等点,可选地考虑使用自定义密钥对以个性化 Base64 编码的公钥字符串。请参阅 #自定义密钥。
要生成私钥,请运行
$ (umask 0077; wg genkey > peer_A.key)
要生成公钥
$ 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
自定义密钥
目前,wg show 不支持为密钥附加人类可读的名称。这使得将密钥与更易于识别的实体关联变得困难,尤其是在使用多个密钥时。除了安装一个完全支持这种关联的 工具外,一种可能的解决方案是生成一个包含一些熟悉字符的公钥(可能是所有者姓名或主机名的前几个字母等)。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=
手动配置
对等点设置
对等点 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
附加路由
要建立比点对点更复杂的连接,需要进行额外的设置。
点对点连接
要访问对等点的网络,请在应能连接到它的对等点的配置中的 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
站点对点连接
如果目的是将设备连接到具有 WireGuard 对等点的网络,请在每个设备上设置路由,以便它们知道对等点可以通过该设备访问。
之后,在其他设备将连接到 WireGuard 对等点的对等点上 启用 IP 转发。
站点对站点连接
要连接两个(或更多)网络,请在所有 *站点* 上同时应用 #点对点连接 和 #站点对点连接。
通过 WireGuard 路由所有流量
要将所有流量通过 WireGuard 隧道路由,请使用
# ip route add default dev wg0 table 2468 # wg set wg0 fwmark 1234 # ip rule add not fwmark 1234 table 2468 pref 10
在第一行,默认路由被添加到备用路由表(表 2468)。此备用路由表的唯一目的是将数据包传递给 wg0 接口。
在第二行,由 wg0 接口处理的所有传出数据包都用防火墙标记标记。
第三行,缺乏此防火墙标记的数据包被定向到备用路由表 2468,该表将其路由到 wg0 接口。pref 10 表示此规则的优先级为 10。要列出所有规则及其相应的优先级,请使用 ip rule show。这些规则决定了将为特定数据包使用哪个路由表。
此实现的优点在于避免使用任何端点。这很方便,因为 WireGuard 端点可以漫游。可以定义没有端点的 WireGuard 对等点。
在此实现中,本地访问网络将无法访问。要白名单 LAN 使用
# ip rule add suppress_prefixlength 0 table main pref 5
使用 ip-rule(8) 添加白名单条目非常简单。例如,要允许特定用户发送隧道外的查询,请使用
# ip rule add uidrange 955-955 table main pref 5
955 是用户的用户 ID。所有用户的用户 ID 可以在 /etc/passwd 中找到。
DNS
要将对等点用作 DNS 服务器,请将其 WireGuard 隧道 IP 地址(或多个地址)添加到 /etc/resolv.conf。例如,使用对等点 B 作为 DNS 服务器
/etc/resolv.conf
nameserver fdc9:281f:04d7:9ee9::2 nameserver 10.0.0.2
基本检查
调用不带参数的 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-networkd、netctl[1]、NetworkManager 和 ConnMan[2]。
- netctl 依赖于 wireguard-tools 中的 wg(8) 和
/etc/wireguard/interfacename.conf配置文件来建立 WireGuard 连接。 - ConnMan 对 WireGuard 的支持非常有限。它只能连接到一个对等点。[3]
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[4] 的设置,以确保网络仍然正常工作。 - 要使用对等点作为 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) § 示例 手册页中提供了示例。
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 RouteTable=main [WireGuardPeer] 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 [WireGuardPeer] PublicKey=PEER_C_PUBLIC_KEY PresharedKey=PEER_A-PEER_C-PRESHARED_KEY AllowedIPs=10.0.0.3/32,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 服务器,请在 *.network* 文件中使用
DNS=选项指定其 WireGuard 隧道的 IP 地址(或多个地址)。对于 搜索域,请使用Domains=选项。有关详细信息,请参阅 systemd.network(5) § [NETWORK] 段选项。 - 要将对等点用作 *唯一* DNS 服务器,请在 *.network* 文件的
[Network]部分设置DNSDefaultRoute=true和Domains=~.。 - 要自动为
AllowedIPs中的所有内容创建路由,请将RouteTable=main添加到 *.netdev* 文件中的[WireGuard]或[WireGuardPeer]部分。或者,可以使用 *.network* 文件中的[Route]部分手动指定其他路由。
# chown root:systemd-network /etc/systemd/network/99-wg*.netdev # chmod 0640 /etc/systemd/network/99-wg*.netdev
或者,可以将密钥存储在单独的文件中,并使用 PrivateKeyFile=、PresharedKeyFile= 和 PublicKeyFile= 进行引用,或者使用 systemd-creds 将它们加密存储。请参阅 #使用 systemd 凭据存储私钥 (systemd-networkd)。
[Address] 部分而不是 [Network] 部分指定地址。例如:/etc/systemd/network/99-wg0.network
... [Address] Address=10.0.0.1/24 NFTSet=address:inet:my_table:wg_ipv4_address NFTSet=prefix:inet:my_table:wg_ipv4_prefix NFTSet=ifindex:inet:my_table:wg_ifindex [Address] Address=fdc9:281f:04d7:9ee9::1/64 NFTSet=address:inet:my_table:wg_ipv6_address NFTSet=prefix:inet:my_table:wg_ipv6_prefix NFTSet=ifindex:inet:my_table:wg_ifindex
对等点 B 设置
/etc/systemd/network/99-wg0.netdev
[NetDev] Name=wg0 Kind=wireguard Description=WireGuard tunnel wg0 [WireGuard] ListenPort=51902 PrivateKey=PEER_B_PRIVATE_KEY RouteTable=main [WireGuardPeer] 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 [WireGuardPeer] PublicKey=PEER_C_PUBLIC_KEY PresharedKey=PEER_B-PEER_C-PRESHARED_KEY AllowedIPs=10.0.0.3/32,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 RouteTable=main [WireGuardPeer] 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 [WireGuardPeer] 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
/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 RouteTable=main [WireGuardPeer] PublicKey=PEER_B_PUBLIC_KEY PresharedKey=PEER_A-PEER_B-PRESHARED_KEY AllowedIPs=10.0.0.2/32 AllowedIPs=fd31::2/128
/etc/systemd/network/99-wg0.network
[Match] Name=wg0 [Network] Address=10.0.0.1/32 Address=fd31::1/128 IPMasquerade=both
IPMasquerade=both 选项会为 IPv4 和 v6 启用 WireGuard 接口上的 IP 转发,为其设置 IP 伪装的防火墙规则,以便对等点 A 可以为对等点 B 提供有效的互联网连接。此外:- 为用于连接到互联网的接口 启用 IP 转发(即,在其 *.network* 文件中添加
IPv4Forwarding=yes)。 - 确保 防火墙不会阻止转发。
- 配置本地 DNS 服务器以接受对 WireGuard 接口 IP 地址的连接。对于 systemd-resolved,请参阅 systemd-resolved#附加监听接口。
- 要自动为
AllowedIPs中的所有内容创建路由,请将RouteTable=main添加到 *.netdev* 文件中的[WireGuard]或[WireGuardPeer]部分。
对等点 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 AllowedIPs=::/0 # Endpoint=[2a01::1]:51871 Endpoint=198.51.100.101:51871 RouteTable=1000
在 netdev 配置中,最值得关注的行是 RouteTable=1000 和 FirewallMark=0x8888。RouteTable 行指定为 wireguard 接口创建一个 id 为 1000 的新路由表,并且主路由表上没有设置任何规则。
FirewallMark 只是用数字 0x8888 标记此 wireguard 接口发送和接收的所有数据包,该数字可用于在这些数据包上定义策略规则。
/etc/systemd/network/50-wg0.network
[Match] Name=wg0 [Network] Address=10.0.0.2/32 Address=fd31::2/128 DNS=10.0.0.1 DNS=fd31::1 DNSDefaultRoute=true Domains=~. [RoutingPolicyRule] Family=both FirewallMark=0x8888 InvertRule=true Table=1000 Priority=10 # Exempt the endpoint IP address so that wireguard can still connect to it. [RoutingPolicyRule] #To = "2a01::1/128"; To=198.51.100.101/32 Priority=5
我们在这里定义两个路由策略。对于所有未标记为 0x8888 的数据包(即所有非 wireguard/普通流量),我们指定必须使用路由表 1000(即 wireguard 路由表)。此规则将所有流量路由通过 wireguard。
我们通过使用主表(默认为 Table=main)路由我们的端点来豁免它,该表具有更高的优先级。
豁免特定地址
为了豁免特定地址(例如私有 LAN 地址)不通过 WireGuard 隧道路由,请将它们添加到另一个具有更高优先级的 RoutingPolicyRule 中。
/etc/systemd/network/50-wg0.network
... [RoutingPolicyRule] To=192.168.0.0/24 Priority=9 ...
特定用户的路由
可能希望仅为特定用户(例如,用于 torrent 流量的 transmission 用户)通过隧道路由 WAN 流量。
/etc/systemd/network/99-wg0.network
... [RoutingPolicyRule] Table=1000 User=transmission Priority=30001 Family=both [RoutingPolicyRule] Table=main User=transmission SuppressPrefixLength=0 Priority=30000 Family=both ...
优先级更高的规则(30000)匹配 transmission 用户生成的所有流量,并将其路由通过主表(无 wireguard),但仅使用前缀长度大于 0 的规则。这排除了默认的 catch-all 规则。因此,只有匹配主表特定规则(如定义本地家庭网络子网的规则)的流量才通过主表路由。
优先级较低的规则(30001)匹配 transmission 用户生成的所有流量,并将其路由通过表 1000,即 wireguard 表。
注意:这些规则应该 *代替* 本节开头定义的两个规则来路由所有流量通过 wireguard。
测试
使用以下命令测试代理:
# ipv4 $ curl -4 zx2c4.com/ip # ipv6 $ curl -6 zx2c4.com/ip
检查 systemd-networkd 日志以获取任何错误和警告消息。
$ journalctl -u systemd-networkd.service
调用 wireguard-tools 中的 wg 命令。
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 实现持久化的站点对点、点对站点或站点对站点连接,只需在 netctl 配置文件中添加适当的 Routes= 行,并将此网络添加到 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 接口。有关 WireGuard 在 NetworkManager 中使用的所有详细信息,请阅读 Thomas Haller 的博客文章 — WireGuard in NetworkManager。
# nmcli connection import type wireguard file /etc/wireguard/wg0.conf
以下示例通过 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.dns和ipv6.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“服务器”和通用的“客户端”,以便通过加密和安全的隧道(如 OpenVPN 等)访问服务器/网络资源。“服务器”运行在 Linux 上,“客户端”可以在任何数量的平台上运行(WireGuard 项目除了 Linux、Windows 和 MacOS 外,还提供 iOS 和 Android 平台的应用程序)。有关更多信息,请参阅官方项目 安装链接。
服务器
在充当“服务器”的对等点上,首先 启用 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 的 netmask 为 /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-wait-online.service 服务,而 systemd-networkd 的用户可能需要 启用 systemd-networkd-wait-online.service 服务,以在尝试 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 是不够的,因此定期运行 reresolve-dns 脚本可能对任何基于 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 端点一次[5]。
/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 nss-lookup.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 内核模块时,可以通过运行以下命令将调试信息写入内核环形缓冲区(可通过 dmesg 和 journalctl 查看):
# 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 的用户可以简单地 重新加载 服务。
解决部分公共 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 的网络软件。
NetworkManager 的用户应该知道它默认不使用 resolvconf。建议使用 systemd-resolved。如果不想这样做,请 安装 openresolv 并配置 NetworkManager 使用它:NetworkManager#Use 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 发现 (PMTU) 不可靠,较大的 MTU 值可能导致连接不稳定或间歇性连接。这可能导致 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
例如,对于上面对等方 B 在标准 LAN 设置中:
# 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 在从挂起状态恢复时重新配置网络接口的方式上引入了一项更改[6]。在此过程中,由 systemd-networkd 管理的网络连接将与 wireguard 接口断开。除非配置了终止开关(kill switch),否则恢复挂起状态后可能会暴露公共 IP 地址。要解决此问题,请在 /etc/systemd/networkd.conf 中注释掉 ManageForeignRoutingPolicyRules 并将其值更改为 no。[7]
请完整查看 systemd-networkd 页面,以了解此更改可能带来的任何其他潜在副作用。