为了连接到我客户的公司网络,我一直在使用 Cisco AnyConnect 安全移动客户端,它工作正常,但似乎不允许我使用拆分隧道(尽管根据应用程序的“统计信息”选项卡,VPN 本身具有“隧道模式(IPv4):拆分包含”,据我所知,这意味着我可以)。(是的,我理解为什么拆分隧道可能很危险,但 VPN 的锁定干扰了我的工作,而我客户的 IT 部门不愿意为承包商破例——而且就像我说的,配置好像允许它。)
为了找到一种方法让分离隧道发挥作用,我安装了 OpenConnect,连接得很好——它接受了我的凭证,我在日志中看到了公司的“横幅”消息,它工作正常。但我只能通过 VPN 访问的所有目的地都不起作用。
我怀疑问题出在路由上。AnyConnect 和 OpenConnect 都向特定网络目标(相同的目标)添加了许多路由,但网关和接口的值不同。例如,
AnyConnect
===========================================================================
Interface List
14...00 05 9a 3c 7a 00 ......Cisco AnyConnect Secure Mobility Client Virtual Miniport Adapter for Windows x64
[...]
===========================================================================
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.151 35
[...]
a.b.c.x 255.255.255.255 On-link a.b.c.d 2
a.b.c.y 255.255.255.255 On-link a.b.c.d 2
a.b.c.z 255.255.255.255 On-link a.b.c.d 2
[...]
192.168.1.1 255.255.255.255 On-link 192.168.1.151 36
[...]
224.0.0.0 240.0.0.0 On-link a.b.c.d 10000
[...]
255.255.255.255 255.255.255.255 On-link a.b.c.d 10000
OpenConnect
Interface List
[...]
63...00 ff 8d 2a 8a 57 ......TAP-Windows Adapter V9
[...]
===========================================================================
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.151 36
[...]
a.b.c.x 255.255.255.255 a.b.c.(d+1) 192.168.1.151 36
a.b.c.y 255.255.255.255 a.b.c.(d+1) 192.168.1.151 36
a.b.c.z 255.255.255.255 a.b.c.(d+1) 192.168.1.151 36
[...]
224.0.0.0 240.0.0.0 On-link a.b.c.d 291
[...]
255.255.255.255 255.255.255.255 On-link a.b.c.d 291
除了0.0.0.0
路由之外,所有这些路由都是通过连接到 VPN 来添加的。对于0.0.0.0
,OpenConnect 将路由的度量更改0.0.0.0
为 36(AnyConnect 表中显示的值也与我完全断开连接时的值相同)。(顺便说一句,AnyConnect 还删除了几条 IPv6 路由,而 OpenConnect 则不予理会——我认为这不重要?)
为了明确对比这些添加项,AnyConnect 对网关使用“On-link”,而 OpenConnect 使用的 IP 地址几乎与 AnyConnect 对接口使用的 IP 地址相同。对于接口,OpenConnect 使用私有 IP 地址。用于 AnyConnect 接口和 OpenConnect 网关的 IP 地址在客户端拥有的范围内。
指标也不同 - AnyConnect 使用 2,其优先级高于我的0.0.0.0
路由(通过 AnyConnect 断开或连接时设置为 35),而 OpenConnect 使用 36 - 并且还将我的0.0.0.0
路由更改为使用 36,因此优先级是相同的(记录显示,我系统上的所有其他路由都使用高于 36 的指标)。
192.168.1.1
AnyConnect 还为 添加了一条到的路由192.168.1.151
,这是 OpenConnect 用于接口的路由。这是其中一个有而另一个没有的唯一路由。
两者都为224.0.0.0
和添加了路由255.255.255.255
,但 AnyConnect 使用的度量为 10000(高于任何其他路由),而 OpenConnect 使用的度量为 291(高于任何其他添加的度量,但低于我连接之前已有的一些其他现有路由)。有趣的是,尽管对所有其他路由使用不同的值,但 OpenConnect 对这两条路由使用与 AnyConnect 相同的网关和接口。
这是在 Windows 10 Pro x64 计算机上。Cisco AnyConnect 是版本 4.5.03040;OpenConnect GUI 是“版本1.5.3(32 位)[...]基于 OpenConnect v7.08。”
我对路由或 VPN 了解不多;即使得到这么多信息也需要大量的搜索和阅读。在开始之前,我甚至不知道“拆分隧道”这个术语。很多信息也已经过时了——Windows 10 没有提供“在远程网络上使用默认网关”选项来取消选中,因为这里和其他地方的很多答案都建议在 AnyConnect 下使用拆分隧道。我不知道是否还有其他相关细节可以提供,但如果有其他需要,我当然很乐意提供。显然,我一直在尝试屏蔽客户端的 IP 地址,但我认为具体的地址在这里并不重要(我也不知道有什么理由屏蔽它们,但这不是我要分享的信息,所以我不会分享)。
答案1
根据 KRyan 的回答,我修改了我的 openconnect 脚本(openconnect gui 文件夹中的 vpnc-script.js!)像这样,它在类似情况下帮助了我:
for (var i = 0 ; i < parseInt(env("CISCO_SPLIT_INC")); i++) {
var network = env("CISCO_SPLIT_INC_" + i + "_ADDR");
var netmask = env("CISCO_SPLIT_INC_" + i + "_MASK");
var netmasklen = env("CISCO_SPLIT_INC_" + i + "_MASKLEN");
exec("route add " + network + " mask " + netmask);
}
=>
for (var i = 0 ; i < parseInt(env("CISCO_SPLIT_INC")); i++) {
var network = env("CISCO_SPLIT_INC_" + i + "_ADDR");
var netmask = env("CISCO_SPLIT_INC_" + i + "_MASK");
var netmasklen = env("CISCO_SPLIT_INC_" + i + "_MASKLEN");
exec("route add " + network + " mask " + netmask + " " + internal_gw+" metric 2 if "+env("TUNIDX"));
}
(第 175 行)
我认为错误在这里:
// Calculate the first usable address in subnet
var internal_gw_array = new Array(
address_array[0] & netmask_array[0],
address_array[1] & netmask_array[1],
address_array[2] & netmask_array[2],
(address_array[3] & netmask_array[3]) + 1
);
var internal_gw = internal_gw_array.join(".");
当我通过 传入内部 IP 的网络掩码为 255.255.255.255 时var netmask_array = env("INTERNAL_IP4_NETMASK").split(".");
,此网关技巧(最终路由会转到一个接口,网关 IP 在这里毫无意义)似乎失败了
答案2
我猜对了,问题出在路线上。经过多次尝试和错误才找到正确答案,但最终在连接后手动更新路线成功了。
奇怪的是,route CHANGE
不起作用;我不得不使用route ADD
,尽管据我所知,这些路由在我连接后已经存在。我使用了相同的目的地、掩码和网关,然后METRIC 2 IF 17
(由于“TAP-Windows 适配器 V9”接口使用 17 — 我怀疑它会在每次重启时发生变化?断开连接和重新连接似乎目前一致使用 17,但正如您在问题中看到的那样,它当时使用的是 63)。完成此操作后,route PRINT
该目的地列出了两个条目(一个由 OpenConnect 添加,另一个是我添加的),它允许我连接。
不过,我觉得非常奇怪的是,我新添加的路线的度量为 37 — 不是我在命令中输入的 2 route ADD
,而且大于现有条目的 36。但无论如何,它都能正常工作。
幸运的是,我们的项目维护了一个hosts
文件(开发人员在开始处理时将其复制到自己的hosts
文件中,我们的构建工具会根据该文件进行检查),因此我能够编写一个批处理脚本来调整路线。为了方便其他想要这样做的人,我的批处理脚本如下所示
FOR /F "tokens=1" %%i IN (\path\to\our\development\hosts) DO (
route ADD %%i MASK 255.255.255.255 a.b.c.d METRIC 2 IF 17
)
文件hosts
格式与系统文件相同:a.b.c.d URL
。此脚本不支持注释(尽管我想象注释route ADD
将会失败),我不知道空行是否会成为问题(但同样,可能只是注释失败route ADD
)。
我可能必须针对 17 进行调整,因为我怀疑它不会是常数;当它出现时,我会研究如何确定它是什么,并使用变量来代替它。(我也会更新这个答案。)
答案3
并不是说您还没有找到可行的方法,而是您似乎误解了路由指标的使用方式。它们实际上只是在非常特殊的情况下起到决定性作用。引用链接的答案:
Windows 上的路由选择,涉及:
- 寻找到达目的地的最具体路线
- 选择具有最低度量的最具体路由。
如果你想让你的脚本不那么脆弱,你可以以编程方式确定接口号。