如何使Windows VPN路由选择性流量(通过目标网络)?


138

我想使用Windows VPN,但仅限于特定网络,因此它不会占用我的整个网络连接。

例如,不要将VPN变为默认路由,而是将其设置为192.168.123.0/24的路由

(我可以看到Ubuntu 在这个问题上有一个解决方案,但有时我也必须在Windows上这样做)

这可以自动化,这样每当我连接到VPN时它会这样做吗?


是否存在通过VPN过滤一堆网站的相关问题?看起来这里的答案仅适用于VPN背后有一个站点的情况。我在中国,我想要使用的网站大约有一半被阻止,所以应该通过VPN,但其他网站没有VPN更快/更顺畅。
hippietrail 2015年

我继续问了一个新问题:superuser.com/questions/925947
hippietrail 2015年

Answers:


138

您可以通过转到VPN,Networking选项卡,Internet Protocol (TCP/IP)属性Advanced和取消选项的属性来关闭接管整个连接Use default gateway on remote network192.168.123.0/24根据VPN服务器的设置,这可能会也可能不会留下路由。如果没有,您每次都必须手动添加路由,尽管您可以将其放在批处理文件中。

要手动添加路由,请运行(以管理员身份):

route -p add 192.168.0.12 mask 255.255.255.255 10.100.100.254

此示例将192.168.0.12通过VPN网关建立持久性(无需在重新启动后运行命令)到IP的路由10.100.100.254

有关此内容的更多信息,请访问http://technet.microsoft.com/en-us/library/bb878117.aspx


1
“你必须手动添加路线”......怎么样?有人强迫说,“192.168.10.123”通过vpn,但没有别的?
Timothy Khouri

16
就个人而言,我发现只需关闭复选框即可。我没有添加任何路线。我通过无数的痕迹证实了一切都在我预期的地方。
eidylon 2011年

1
同样,这个复选框就是所需要的。
Luk

1
请澄清。哪些流量通过VPN路由?它只是针对VPN服务器IP的流量吗?例如,如果VPN连接转到“my.domain.com”,那么这是否意味着客户端上“my.domain.com”的所有流量都通过VPN,其他一切都转到默认网关?
Triynko

1
我使用“route print”命令,并验证Windows 7生成的路由是错误的。它没有将发送到我的VPN IP的流量发送到VPN ...而是将其发送到我的本地网关。表格中还有一些圆形条目。我删除了Windows创建的路由,然后手动添加了正确的路由,以便我的VPN服务器的IP地址条目将使用VPN的网关和客户端的本地IP作为接口。然后,通过VPN隧道成功路由到我的VPN服务器的流量,并且所有其他流量未按预期受到影响。效果很好。
Triynko 2012年

20

我成功地使用了@ TRS-80的技术来实现这一目标。

我在家工作,必须通过VPN连接到公司网络上我的电子邮件(我讨厌webmail !!)。

与此同时,我需要经常浏览信息,还需要youtube才能获得我的背景音乐......现在你绝对不希望从VPN流出youtube,因为这听起来像是机器人歌唱!:)

我所做的就是关注@ TRS-80:

VPN的属性,网络选项卡,“Internet协议(TCP / IP)”属性,高级,取消选中“在远程网络上使用默认网关”

然后做了我自己的:

在DNS选项卡下,勾选“在DNS中注册此连接地址”

一切都无缝衔接!


9

虽然这个答案并不反映您的要求,但我专门为此目的使用了一个VM。这样,只有VM内的网络才受到路由的限制。

您可能会找到其他人更好的答案,但至少这可能会给您一些考虑因素,因为它是创建VM后的一个简单解决方案。


如果您的硬件可以很好地处理它,这是一个很好的解决方案
Enigma 2013年

使用这个解决方案多年,直到找到这个线程。:)
OV

7

我发现它需要在route命令中直接指向接口。没有它,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'。


这对我也有用。要找出您需要的接口,只需执行“route print”命令并检查显示可用接口列表的第一行(在那里找到您的VPN并检查其IF - 它将在第一列中)。
Funbit 2015年

有一篇精彩的文章:链接。使用0.0.0.0作为默认网关IP似乎也可以很好地工作,因此无需在更改时进行调整。在这个答案中加入它会很棒,因为它比最顶层的东西更有用。
lpd 2015年


4

如果您同时拥有IPV4和IPV6,则必须在两个位置取消选中“在远程网络上使用默认网关”,即使您只使用IPV4



2

我想在混合中添加我的解决方案。它运行在Windows 7或更高版本上的Cygwin驱动的UNIX shell上,但也应该在构建14986或Windows的Busybox之后与MSYS2,Bash-on-Windows [WSL]一起使用。需要使用管理员权限运行。

它有一些设置,并试图检测一些你没有明确设置的东西。它还明确设置接口编号(IF)以解决某些用户(像我一样)在这里遇到的其他解决方案的一些问题。

#!/bin/sh

# these three settings are required
adapter_name='VPN Connection'
username=
password=

# This setting here might be important because it's about the target network
# and in some cases it can't be properly determined automatically so this might
# be then worth setting.
# Format is in CIDR notation with the network address and a forward slash and
# the amount of network bits
target_network=192.168.0.0/24

# the IP you will get on the target network, also the VPN gateway on your
# local machine, you normally don't need to set this as the script tries to
# detect it
ip=

# optional setting for metric which normally shouldn't be necessary,
# except in te very rare cases where it should be set to a value lower than all
# other routes that might match the target network
metric=

# experimental setting to delete routes to the target network prior and after
# should normally not be needed unless this script fails and you get error
# messages like 'The route addition failed: The object already exists.'
route_cleanup=F

prog_name=${0##*/}

msg() {
  printf '%s: %s\n' "$prog_name" "$*"
}

die() {
  msg "$*" >&2
  exit 1
}

[ "$adapter_name" ] || die "Adapter name not set!"
[ "$username" ]     || die "Username not set!"
[ "$password" ]     || die "Password not set!"

if [ "$(uname -o)" != 'MS/Windows' ]; then
  id -G | grep -qE '\<0|544\>' || die 'Not running with admin rights.'
fi

msg "Disconnecting any existing connection that might exist."
rasdial.exe "$adapter_name" /d

msg "Connecting"
rasdial.exe "$adapter_name" "$username" "$password"

if [ ! "$ip" ]; then
  msg "Getting IP address on target network."
  ip=$(netsh.exe interface ip show config name="$adapter_name" |
    grep -a 'IP Address' | awk -F'[: ]+' '{print $4}')

  [ "$ip" ] || die 'Could not get IP! Exiting.'

  msg "Detected IP address as '$ip'."
fi

if [ ! "$target_network" ]; then
  msg "Getting target network."
  target_network=$(netsh.exe interface ip show config name="$adapter_name" |
    grep -a 'Subnet Prefix' | awk -F'[: ]+' '{print $4}')

  [ "$target_network" ] || die 'Could not get target network! Exiting.'

  msg "Detected target network as '$target_network'."
fi

msg "Getting VPN interface number."
if=$(ROUTE.EXE print -4 | grep -a "$adapter_name" |
  awk -F. '{gsub(" ", "");print $1}')

[ "$if" ] || die 'Could not get interface number! Exiting.'

msg "Detected VPN interface number as '$if'."

if [ "$route_cleanup" = T ]; then
  msg "Deleting any potentially already existing routes for the target network."
  ROUTE.EXE delete "$target_network"
fi

msg "Adding route for target network."
if [ "$metric" ]; then
  ROUTE.EXE add "$target_network" "$ip" IF "$if" Metric "$metric"
else
  ROUTE.EXE add "$target_network" "$ip" IF "$if"
fi

msg "VPN should be up now."
msg "Press enter to make it stop."
read -r _

if [ "$route_cleanup" = T ]; then
  msg "Deleting route."
  ROUTE.EXE delete "$target_network"
fi

msg "Disconnecting."
rasdial.exe "$adapter_name" /d

# msg "Press enter to exit."
# read -r _

exit 0

还值得注意的是,可能需要手动设置低度量标准,否则默认路由将在发往VPN的流量之前匹配。您可以通过转到适配器设置来执行此操作,在该设置中打开VPN适配器的“...属性”菜单项→ “网络”选项卡→ “Internet协议版本4(TCP / IP)”属性→ “高级” →然后取消选中在“自动度量”(除复选框“使用默认网关......”当然),并在其值设置“界面指标:”字段设置为大于默认路由(见低的值ROUTE.EXE -4 print输出)。


1

有点旧,但我找到了一种方法来使用另一台机器。我有一台笔记本电脑,我设置了VPN连接,在那里我有FreeProxy设置Socks5 ..

然后我在我的客户端机器上设置firefox以使用笔记本电脑的代理服务器..结果是如果我使用FireFox或任何设置使用该Socks5代理的东西,它将使用VPN,否则它使用标准路由..



1

来自俄罗斯论坛:http//forum.ixbt.com/topic.cgi?id = 1443549

保存为文件(例如: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

1

如果不使用其他程序,批处理文件或命令行,则无法在Windows中执行此操作。另一种方法是获得可以运行VPN的虚拟(或物理)机器。

似乎很奇怪,像这样容易解释的东西很难实现。将流量从一个程序路由到VPN接口以及将所有其他程序路由到默认NIC接口有多难?为什么我们需要为此设置一个完整的虚拟机?使用Linux它是可能的,但它的解决方案也不是很优雅。

它也非常受欢迎:我在同一主题上遇到过几十个主题。所以我只希望有人意识到这种荒谬,并为此做点什么。(在Windows 8中!)

此解决方案来自未归因的批处理文件。它略有改编。

Windows 7的说明

该脚本将通过您的VPN连接和路由流量,直到重新启动-你可以替换route add使用route -p add的变化持续下去,但如果你没有持久的IP与你的VPN,它最终会停止工作时,你的VPN的IP变化。

  1. 打开网络和共享中心
  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:

脚本

@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

0

像我这样的新手的“简短”指南,他们对网络知之甚少。这里没什么新内容,但是前面的答案和其他相关主题中描述的所有好选项的摘要。整个过程包括3个基本步骤:

1)使所有流量不通过VPN。为此,您必须取消Use default gateway on remote network选中VPN设置中的复选框。确保取消选中IPv4和IPv6的此复选框。通常我只是完全禁用VPN协议进行VPN连接。

(!)(有时)取消选中该复选框对于正常工作是足够的 - 根据我的经验,在建立VPN连接后,可以自动添加必要的路由(这将通过VPN引导必要的流量)。我不知道这些规则的确切位置和方式,但这种情况仍然存在 - 可能是VPN网络管理员所做的一些魔术。

2)只通过VPN进行必要的流量。为此,您需要定义路线。这里有3个选项:

2.1)通过VPN网关添加永久路由:

route -p add a.b.c.d/<CIDR> w.x.y.z 要么 route -p add a.b.c.d mask e.f.g.h w.x.y.z

其中'VPN网关'='您在VPN网络上的IP'= w.x.y.z和目标地址/网络= a.b.c.d。您可以w.x.y.z通过执行ipconfig和查找您的VPN连接名称来查找,或者,如果您使用PowerShell,您可以通过执行来获得紧凑的输出ipconfig | grep -A5 PPP(在找到每个PPP连接后将输出5行)。

缺点:如果您的VPN IP将发生变化,您将不得不重新创建路由。

2.2)通过VPN网络接口添加永久路由:

route -p add a.b.c.d/<CIDR> 0.0.0.0 IF <interface number>

a.b.c.d目标地址/网络在哪里,是interface numberVPN连接的标识符。可以通过执行来找到此ID netstat -rn,或者,对于更紧凑的输出,可以找到该ID netstat -rn | grep -A10 'Interface List'

优点:如果您的VPN地址(w.x.y.z)发生变化,则无需更改任何内容。

缺点:如果删除VPN连接,则需要使用新ID重新创建路由。

2.3)使用PowerShell cmdlet:

Add-VpnConnectionRoute -ConnectionName '<VPN connection name>' -DestinationPrefix a.b.c.d/<CIDR>

优点:每次建立VPN连接时都会添加必要的路由,并在每次断开连接时删除。

缺点:没有Get-VpnConnectionRoutescmdlet,因此很难管理这些规则。

3)检查并确保路由按预期工作!

如果添加了持久路由,则可以通过执行来检查它们netstat -rn | grep -A10 'Persistent Routes'

最后,tracert对两个应该通过VPN访问的IP地址和那些应该在没有VPN的情况下工作的IP地址运行一些命令。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.