如何使Windows VPN路由有选择性的流量(按目标网络)?
我想使用Windows VPN,但只针对特定的网络,这样它就不会占用我的整个网络连接。与其让VPN成为默认路由,不如让它只作为192.168.123.0/24的路由
(我可以看到Ubuntu有这样的解决方案在这个问题中,但有时我在Windows上也必须这样做)
能否自动完成,这样我每次连接到VPN时,它都会这样做?
我想使用Windows VPN,但只针对特定的网络,这样它就不会占用我的整个网络连接。与其让VPN成为默认路由,不如让它只作为192.168.123.0/24的路由
(我可以看到Ubuntu有这样的解决方案在这个问题中,但有时我在Windows上也必须这样做)
能否自动完成,这样我每次连接到VPN时,它都会这样做?
你可以通过进入VPN的属性,Networking
选项卡,Internet Protocol (TCP/IP)
属性,Advanced
,取消勾选Use default gateway on remote network
,关闭接管整个连接。这可能会或不可能留下一个路由到192.168.123.0/24
,这取决于VPN服务器的设置。如果没有,你就必须每次手动添加路由,尽管你可以把它放在一个批处理文件中。
为了手动添加路由,请运行(作为管理员):
route -p add 192.168.0.12 mask 255.255.255.255 10.100.100.254
这个例子将通过VPN网关192.168.0.12
建立一个持久的路由(不需要在重启后运行该命令)到IP 10.100.100.254
。
我发现它需要在路由命令中直接点接口。如果没有它,Windows要用主网卡接口,而不是VPN。在我的情况下,看起来像
route -p add 192.168.10.187 mask 255.255.255.255 0.0.0.0 IF 26
:: ^destination ^mask ^gateway ^interface
注意'IF 26'。
在Windows 8+中使用Add-VPNConnectionRoute cmdlet。
如果你使用CMAK并设置一个路由文件,客户端可以下载….windows会下载路由文件并适当调整路由。有选项可以删除默认路由…..并添加各种静态路由等。这就是所谓的split-tunnel btw.
这里有一个很好的方法。 http://blogs.technet.com/b/rrasblog/archive/2007/06/11/split-tunnelling-using-cmak.aspx
我想把我的解决方案加入其中。它在Windows 7或更高版本的Cygwin驱动的UNIX shell上运行,但应该也可以使用MSYS2,Bash-on-Windows [WSL]后的bash-on-Windows [WSL],或Busybox for Windows)。需要使用管理员权限运行。
它有一些设置,并尝试检测一些你没有明确设置的东西。它还明确地设置了接口号(IF),以对抗一些用户(比如我)在这里的其他解决方案中遇到的一些问题。你可以通过打开VPN适配器设置,在这里打开VPN适配器的“…属性”菜单项→“网络”选项卡→“Internet协议版本4(TCP/IP)”属性→“高级”→在那里你可以取消勾选“自动公制”复选框(当然还有“使用默认网关…”),并将“接口公制:”字段中的值设置为低于默认路由的值(见ROUTE.EXE -4 print
输出)。
你可以使用类似于netcatcher这样的东西–只需一次性添加所有需要的路由,然后忘记它。当你连接或断开VPN会话时,它将自动添加和删除路由。如果你的VPN IP地址是动态获取的(DHCP),netcatcher会捕捉到它并更新路由。
来自俄罗斯论坛。http://forum.ixbt.com/topic.cgi?id=14:43549
保存为文件 (ex: vpn_route.vbs),并在vpn连接后执行命令
cscript vpn_route.vbs
vpn_route.vbs:
strComputer = "."
strMACAddress = "MAC of VPN interface here (example 00:45:55:00:00:00)"
strTarget = "route target here (example 192.168.123.0)"
strMask = "mask here (example 255.255.255.0)"
Set objWMIService = GetObject("winmgmts:\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * From Win32_NetworkAdapterConfiguration Where MACAddress = '" & strMACAddress & "'")
For Each objItem in colItems
strIP = objItem.IPAddress(0)
Next
Set objShell = CreateObject("WScript.Shell")
objShell.Run "route add " & strTarget & " mask " & strMask & " " & strIP
为像我这样对网络不甚了解的新手提供一个 “简短的 "指南。这里没有太多新的东西,只是总结了之前的答案和其他相关线程中描述的所有好的选项。整个过程包括3个基本步骤:
***1) 使所有的流量不通过VPN进行传输。确保在IPv4和IPv6中都要取消选中这个复选框。通常情况下,我只是在VPN连接时完全禁用IPv6协议。
(!!)有可能(有时)取消这个复选框就可以正常工作了–根据我的经验,在VPN连接建立后,必要的路由(通过VPN引导必要的流量)可以自动添加。我不知道这些规则是在哪里和如何配置的,但这种情况是存在的–可能是VPN网络管理员的一些魔法。) 只让_必要的流量通过VPN进行传输。这里你有三个选项:
2.1) 通过VPN网关添加永久路由:
Use default gateway on remote network
或route -p add a.b.c.d/<CIDR> w.x.y.z
,其中'VPN网关’=‘你的VPN网络上的IP’=route -p add a.b.c.d mask e.f.g.h w.x.y.z
,目标地址/网络=w.x.y.z
。你可以通过执行a.b.c.d
并查找你的VPN连接名来找到w.x.y.z
,或者,如果你使用PowerShell,你可以通过执行ipconfig
来获得紧凑的输出(在找到每个PPP连接后会输出5行)。
优点:如果你的VPN地址(ipconfig | grep -A5 PPP
)会改变,就不需要改变任何东西。 3) 使用PowerShell cmdlet:
route -p add a.b.c.d/<CIDR> 0.0.0.0 IF <interface number>
优点:每次建立VPN连接时都会添加必要的路由,每次断开连接时都会删除。
缺点:没有a.b.c.d
cmdlet,所以管理这些规则会比较麻烦。) 检查并确保路由正常工作!**
如果你添加了持久路由,可以通过执行interface number
来检查。
如果不使用额外的程序、批处理文件或命令行,这在Windows中是无法实现的。另一种方法是得到一个虚拟机(或物理机),你可以在它上运行VPN。
这似乎很奇怪,这么容易解释的事情竟然很难实现。仅仅将流量从一个程序路由到VPN接口,而将所有其他程序路由到默认的NIC接口,这有多难?为什么我们需要为此设置一整台虚拟机呢?而且用Linux是可以的,但它的解决方案也不是很优雅。
也很受追捧。我碰到过几十个关于这个问题的线程。所以我只希望有人能意识到这一点的可笑之处,并对此做些什么。(在Windows 8中!)
这个解决方案来自一个未归属的批处理文件。它已经稍作调整。
**Windows 7*的说明
该脚本将连接到你的VPN并通过你的VPN进行流量路由,直到重启–你可以用route add
替换为route -p add
,以使变化持续存在,但如果你的VPN没有持久的IP,当你的VPN IP发生变化时,它最终会停止工作。打开网络和共享中心
2. 打开你的VPN连接的属性
3. 点击 Networking
标签
4. 对于IPv4和6:
1. 点击 Properties
2. 点击 Advanced
3. 取消勾选Use default gateway[...]
5.关闭前几步打开的所有内容
6.编辑并保存下面找到的批处理脚本
7.以管理员身份运行
。以管理员身份运行
你需要在脚本中替换以下内容:
<VPN>
用你创建的VPN连接的名称 <USER>
用VPN用户名 <PASS>
用VPN密码 <TARGET>
用你想通过VPN路由的IP地址 <PASS>
(如果你想路由更多的地址,只需在目标地址的三行中重复使用) _注: 如果你不想将密码保存在文件中,请将%password%
替换为set password= Input password:
,并在脚本的第一行后添加以下内容:&007.
Script*
@echo off
@echo make sure to be disconnected!
rasdial <VPN> /d
@echo start to connect to vpn
rasdial <VPN> <USER> <PASS>
netsh interface ip show config name="<VPN>" | findstr "IP" > ip.dat
set /p ip= < ip.dat
del ip.dat
set ip=%ip:~-12%
@echo VPN IP is %ip%
set target=<TARGET>
@echo Add route for %target%
route add %target% mask 255.255.255.255 %ip%
timeout /T 3 > nul