如何在 Windows 版 WireGuard 中禁用路由表更改?

如何在 Windows 版 WireGuard 中禁用路由表更改?

我想要做的是为某些应用程序提供一个单独的接口,以便通过 WireGuard 使用 VPN,而所有其他应用程序则使用我的常规接口(按应用程序拆分隧道)。我已经解决了如何让特定应用程序使用我的 WireGuard 接口。

我现在的问题是,当我的 WireGuard 隧道打开时,我的所有机器的流量都会通过我的 VPN 进行传输。

我尝试allowedIPs = 0.0.0.0/0, ::/0从下方删除[Peer],但这导致我的隧道不允许我的应用程序向互联网传输流量。

我还尝试Table = off在下方添加[Interface]以禁止 WireGuard 将我的隧道添加到我的系统路由表中。发生这种情况的原因是 WireGuard 拒绝保存或导入配置并响应“[Interface] 部分的密钥无效:”table“。

我正在使用适用于 Windows 的 WireGuard v0.3.14。

还有其他方法可以实现这一点吗?

答案1

我的一位朋友在 WireGuard 的 zx2c4 (Jason Donenfeld) 的帮助下帮我解决了这个问题。我在这里分享我们的解决方案,以便下一个遇到同样问题的人使用。

Windows 版 WireGuard 在 v0.3.15 中增加了对的支持Table = off。这使得 WireGuard 在隧道打开时不会更新路由表。

此时,我们有了一条隧道,但即使它是应用程序的唯一适配器,Windows 也不会通过它路由流量。为了解决这个问题,我们需要向适配器添加一个优先级低于常规默认路由的默认路由。

为此,我们需要首先启用危险脚本执行在 WireGuard 中。为此,我们需要使用 regedit 设置注册表项HKEY_LOCAL_MACHINE\Software\WireGuard\DangerousScriptExecutionDWORD(1)该项默认不存在,需要使用 regedit 创建。然后需要重新启动 WireGuard。

完成此操作后,我们需要在启动和停止隧道时运行一些 PowerShell 命令来为隧道创建默认路由。此路由需要具有更高的指标/成本(优先级较低)比我们的正常默认路由。对于此解决方案,我们使用度量值 95(比最高自动度量高 10)。

WireGuard 能够自动执行隧道配置中的PreUpPostUpPreDownPostDown选项中指定的 Windows 命令。我们利用此功能自动设置路由。

WireGuard 在运行命令时将环境变量设置WIREGUARD_TUNNEL_NAME为此隧道的名称。我们可以通过调用将其转换为 PowerShell 对象$wgInterface = Get-NetAdapter -Name %WIREGUARD_TUNNEL_NAME%

一旦我们将隧道作为 PowerShell 对象,我们就可以在 Windows 中设置或关闭我们的路线。

为了创建我们的路线,我们调用route add 0.0.0.0 mask 0.0.0.0 0.0.0.0 IF $wgInterface.ifIndex metric 95

要删除我们的路线,我们调用route delete 0.0.0.0 mask 0.0.0.0 0.0.0.0 if $wgInterface.ifIndex metric 95

[Interface]当我们将所有这些结合在一起时,我们最终在隧道配置中得到以下内容。 PostUpPreDownTable = off就是此解决方案所提供的。

[Interface]
PrivateKey = <...>
Address = <...>
DNS = <...>
PostUp = powershell -command "$wgInterface = Get-NetAdapter -Name %WIREGUARD_TUNNEL_NAME%; route add 0.0.0.0 mask 0.0.0.0 0.0.0.0 IF $wgInterface.ifIndex metric 95"
PreDown = powershell -command "$wgInterface = Get-NetAdapter -Name %WIREGUARD_TUNNEL_NAME%; route delete 0.0.0.0 mask 0.0.0.0 0.0.0.0 if $wgInterface.ifIndex metric 95"
Table = off

[Peer]
PublicKey = <...>
AllowedIPs = 0.0.0.0/0,::0/0
Endpoint = <...>

IPv4 现已完成。如果您想使用IPv6以及(可选)继续下一部分。

IPv6 专用

如果主机系统上可用 IPv6 并且受 WireGuard 隧道支持,那么我们也可以将其应用于 IPv6。

警告:如果主机系统不在 IPv6 互联网上,则不应配置通过 WireGuard 的 IPv6 路由,除非可以通过隧道发送部分非隧道流量。忽略这一点将导致您混合非隧道流量和隧道流量(例如:一些个人流量通过工作网络路由)。如果主机在 IPv6 互联网上,这将不是问题,因为任何非隧道 IPv6 流量都将通过主机默认 IPv6 接口路由。

要对 IPv6 执行此操作,我们需要在启动和停止隧道时运行一些 PowerShell 命令来为隧道创建默认 IPv6 路由。此路由还需要具有更高的度量(优先级较低)比我们的正常默认路由。对于此解决方案,我们使用了度量值 205(比最高自动 IPv6 度量 50 高 155)。我们还需要确保此路由不是持久的,因此如果出于任何原因脚本未将其删除,它将在下次启动时自动删除。

为了创建我们的 IPv6 路由,我们调用netsh interface ipv6 add route prefix= ::0/0 interface= $wgInterface.name metric= 205 store= active

要删除我们的 IPv6 路由,我们调用netsh interface ipv6 delete route prefix= ::0/0 interface= $wgInterface.name

PostUp这些 PowerShell 命令需要添加到隧道配置的和的末尾。进行此更改后,隧道配置中PreDown应该会出现以下PostUp和行。PreDown

PostUp = powershell -command "$wgInterface = Get-NetAdapter -Name %WIREGUARD_TUNNEL_NAME%; route add 0.0.0.0 mask 0.0.0.0 0.0.0.0 IF $wgInterface.ifIndex metric 95; netsh interface ipv6 add route prefix= ::0/0 interface= $wgInterface.name metric= 205 store= active"
PreDown = powershell -command "$wgInterface = Get-NetAdapter -Name %WIREGUARD_TUNNEL_NAME%; route delete 0.0.0.0 mask 0.0.0.0 0.0.0.0 if $wgInterface.ifIndex metric 95; netsh interface ipv6 delete route prefix= ::0/0 interface= $wgInterface.name"

答案2

我本来很想直接回复 Ryan,但我不能 ¯\_(ツ)_/¯

根据他的回答,我写了一个小的 powershell 帮助脚本。

它可以设置注册表项,重新启动 WireGuard 管理器服务,当然还可以设置默认路由(还有一个!)

您可以在这里找到它(带有配置示例):https://gist.github.com/webtroter/36477c014e4cc5f169468891fa7652f2

相关内容