我想要做的是为某些应用程序提供一个单独的接口,以便通过 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\DangerousScriptExecution
。DWORD(1)
该项默认不存在,需要使用 regedit 创建。然后需要重新启动 WireGuard。
完成此操作后,我们需要在启动和停止隧道时运行一些 PowerShell 命令来为隧道创建默认路由。此路由需要具有更高的指标/成本(优先级较低)比我们的正常默认路由。对于此解决方案,我们使用度量值 95(比最高自动度量高 10)。
WireGuard 能够自动执行隧道配置中的PreUp
、PostUp
、PreDown
和PostDown
选项中指定的 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]
当我们将所有这些结合在一起时,我们最终在隧道配置中得到以下内容。 PostUp
、PreDown
和Table = 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