How can I make the Windows VPN route selective traffic (by destination network)?

143

88

I want to use a Windows VPN but only for a particular network, so that it doesn't take over my entire network connection.

e.g., Instead of the VPN becoming the default route, make it only the route for 192.168.123.0/24

(I can see that there is a solution for this for Ubuntu in this question, but sometimes I have to do this on Windows too)

Can this be automated so that whenever I connect to the VPN it does this?

Legooolas

Posted 2009-07-24T09:33:51.157

Reputation: 4 530

Is there a related question for filtering a bunch of sites through VPN? It looks like the answers here will work only for the case where there's a single site behind VPN. I'm in China and about half the sites I'd like to use are blocked so should go through VPN but other sites are faster/smoother without VPN. – hippietrail – 2015-06-10T03:06:36.497

I went ahead and asked a new question: http://superuser.com/questions/925947

– hippietrail – 2015-06-10T03:18:20.687

Answers

143

You can turn off taking over your entire connection by going to the properties of the VPN, Networking tab, Internet Protocol (TCP/IP) properties, Advanced, untick Use default gateway on remote network. This may or may not leave a route to 192.168.123.0/24 depending on the VPN server's setup. If it doesn't, you'll have to manually add the route each time, although you could put it in a batch file.

In order to manually add the route, run (as administrator):

route -p add 192.168.0.12 mask 255.255.255.255 10.100.100.254

This example will make a persistent (it's not necessary to run the command after a reboot) route to the IP 192.168.0.12 through the VPN gateway 10.100.100.254.

More about this at http://technet.microsoft.com/en-us/library/bb878117.aspx

TRS-80

Posted 2009-07-24T09:33:51.157

Reputation: 2 923

This answer is incomplete because you don't mention the necessity of specifying the interface. Please see my answer here for a more complete explanation: http://superuser.com/a/862409/16153

– Jez – 2015-01-08T21:33:05.063

I've been looking for a way to do this over 2 years! Didn't expect it to be as simple as unchecking a checkbox. Do you know how to achieve the same effect on Ubuntu and Android as well? Thanks! – Bruno Finger – 2017-01-25T11:01:58.603

Wow, here I am again, almost 8 years later. This info is no longer useful, since Windows 7 is out of service, and this is still far, far to complex to set up. I want one app to avoid my VPN so it can connect to local computers, and want all other traffic to route normally over the VPN. – Triynko – 2020-02-22T17:50:43.763

1"You'll have to manually add the route" ... how? How does someone force, let's say, "192.168.10.123" to go through the vpn, but nothing else? – Timothy Khouri – 2011-06-11T02:16:10.313

17Personally, I found just turning off the checkbox was enough. I did not have to add any routes. I verified everything is going where I would expect it to via numerous tracerts. – eidylon – 2011-09-28T20:05:39.263

1Same, this checkbox was all that was needed. – Luk – 2012-09-06T20:59:00.670

1Please clarify. Which traffic is routed over the VPN? Is it just traffic targetted to the IP of the VPN server? For example, if the VPN connection goes to "my.domain.com", then does that mean all traffic on the client to "my.domain.com" goes over the VPN, and everything else goes to the default gateway? – Triynko – 2012-09-25T00:06:20.463

1I used "route print" command, and verified that the routes Windows 7 generated were dead wrong. It was not sending traffic addressed to my VPN's IP to the VPN... instead it was sending it to my local gateway. There were also a few circular entries in the table. I deleted the route Windows created, then manually added the correct route so that my VPN server's IP address entry would use the VPN's gateway and local IP of the client for the interface. Traffic to my VPN server was then successfully routed through the VPN tunnel, and all other traffic was unaffected as expected. Works well. – Triynko – 2012-09-25T07:13:14.977

I had to uncheck the "Use default gateway on remote network" and then check "Disable class based route addition" to use my local network in the same IP range. (Local and VPN both use 192.168.1.x internally) – wersimmon – 2013-04-15T23:11:35.637

@eidylon thanks for sharing tracert as verification method hint. I was goint to ask for a verification method. The answer could still be improved with a working example of how to verify that both kind of traffic goes to their corresponding "right place", possibly with tracert. – n611x007 – 2013-08-05T17:24:14.790

The route -p add was especially useful for me, because our public webservers have areas protected both with password and with ip-restrictons so they can only be accessed from our own network. – Lenne – 2013-11-06T00:09:53.480

20

I successfully used @TRS-80's technique to achieve this.

I work from home and have to VPN onto the corporate network for my email (I hate webmail!!).

At the same time, I need to be constantly surfing for info and also need youtube for my background music... Now you definitely don't want to stream youtube off a VPN since that makes it sound like a Robot Singing!!! :)

All I did was follow @TRS-80:

properties of the VPN, Networking tab, "Internet Protocol (TCP/IP)" properties, Advanced, untick "Use default gateway on remote network"

and then did my own:

under DNS tab, tick "register this connections addresses in DNS"

All works seamlessly!

bPratik

Posted 2009-07-24T09:33:51.157

Reputation: 201

9

Granted this answer does not reflect your request but i use a VM specifically for this purpose. That way only the network inside the VM is restricted by the routes.

You may find some better answers by other people but at least this may give you something to consider as it an easy solution after the VM has been created.

Wayne

Posted 2009-07-24T09:33:51.157

Reputation: 1 115

Used this solution for years, until found this thread. :) – o.v – 2019-08-07T13:48:53.597

This is a good solution provided your hardware can handle it well. – Enigma – 2013-02-07T15:16:57.050

7

I found that it needed to directly point interface in route command. Without it, Windows going to use main network card interface, instead of VPN. In my case, it looks like

route -p add 192.168.10.187 mask 255.255.255.255 0.0.0.0 IF 26
::           ^destination        ^mask           ^gateway   ^interface

note the 'IF 26'.

Dmitry Petrov

Posted 2009-07-24T09:33:51.157

Reputation: 71

This worked for me as well. To find out which interface you need just execute "route print" command and check the first lines displaying list of available interfaces (find your VPN there and check its IF - it will be in the first column). – Funbit – 2015-04-24T01:55:55.623

There's a brilliant article on this: link. Using 0.0.0.0 as the default gateway IP seems to work nicely too, so it need not be adjusted upon change. It would be great to incorporate in this answer, since imo it's far more useful than the top one.

– lpd – 2015-06-16T08:51:55.227

6

Use Add-VpnConnectionRoute cmdlet in Windows 8+.

Add-VpnConnectionRoute -ConnectionName 'My VPN Connection' -DestinationPrefix 192.168.123.0/24

Der_Meister

Posted 2009-07-24T09:33:51.157

Reputation: 295

This worked perfectly for me on Windows 10. – x-ray – 2018-06-26T23:26:25.597

4

if you have both IPV4 and IPV6 you have to uncheck the "Use default gateway on remote network" in both places, even if you only use IPV4

Dave

Posted 2009-07-24T09:33:51.157

Reputation: 41

3

If you use the CMAK and setup a routing file that the client can download... windows will download the routing file & adjust routes as appropriate. There are options to remove the default route... and add various static routes & such. This is known as a split-tunnel btw.

There is a good how-to here: http://blogs.technet.com/b/rrasblog/archive/2007/06/11/split-tunnelling-using-cmak.aspx

TheCompWiz

Posted 2009-07-24T09:33:51.157

Reputation: 9 161

2

I want to add my solution to the mix. It runs on a Cygwin-powered UNIX shell on Windows 7 or newer but should also work with MSYS2, Bash-on-Windows [WSL] after build 14986, or Busybox for Windows). Needs to be run with admin privileges.

It has some settings and tries to detect some of the things you didn't explicitly set. It also sets the interface number (IF) explicitly to counter some problems some users (like me) had with the other solutions here.

#!/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

It's also worth noting that it might be necessary to manually set a low metric or otherwise the default route will match before the traffic destined for the VPN. You do this by going to the adapter setting where you open the "… Properties" menu item for the VPN adapter → "Networking" tab → "Internet Protocol Version 4 (TCP/IP)" Properties → "Advanced" → and there you uncheck the "Automatic metric" checkbox (in addition to the "Use default gateway …" of course) and set the value in the "Interface metric:" field to a value lower than the default route (see ROUTE.EXE -4 print output).

phk

Posted 2009-07-24T09:33:51.157

Reputation: 255

1

A little old but I found a way to do this using another machine. I have a laptop where I set up the VPN connection and on there I have FreeProxy set up with Socks5..

Then I set up firefox on my client machine to use the laptop's proxy server.. the result is that if I use FireFox or anything that's set up to use that Socks5 proxy, it will use the VPN, otherwise it uses standard routing..

Lonnie

Posted 2009-07-24T09:33:51.157

Reputation: 11

1

A 'short' guide for noobs like me, who don't know much about networks. Not much new here, but a summary of all good options described in previous answers and in other related threads. Whole procedure consists of 3 basic steps:

1) Make all traffic NOT going via VPN. For this you must uncheck Use default gateway on remote network checkbox in VPN settings. Make sure to uncheck this checkbox for both IPv4 and IPv6. Usually I simply disable IPv6 protocol completely for VPN connection.

(!) It is (sometimes) possible that unchecking that checkbox will be enough for normal work - in my experience, necessary routes (which will direct necessary traffic via VPN) can be added automatically after VPN connection is established. I don't know exactly where and how these rules are configured, but such scenario exists - probably it is some magic done by VPN network administrators.

2) Make only necessary traffic going via VPN. For this you need to define routes. Here you have 3 options:

2.1) Add permanent route via VPN gateway:

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

where 'VPN gateway' = 'your IP on VPN network' = w.x.y.z and target address/network = a.b.c.d. You can find w.x.y.z by executing ipconfig and looking for your VPN connection name or, if you use PowerShell, you can get compact output by executing ipconfig | grep -A5 PPP (which will output 5 lines after finding each PPP connection).

Cons: you will have to re-create routes if your VPN IP will change.

2.2) Add permanent route via VPN network interface:

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

where a.b.c.d is the target address/network and interface number is identifier of your VPN connection. This ID can be found by executing netstat -rn, or, for more compact output, netstat -rn | grep -A10 'Interface List'.

Pros: no need to change anything if your VPN address (w.x.y.z) will change.

Cons: need to re-create routes with new ID if you delete your VPN connection.

2.3) Use PowerShell cmdlet:

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

Pros: necessary routes are added each time VPN connection is established and deleted each time it is disconnected.

Cons: there is no Get-VpnConnectionRoutes cmdlet so it can be hard to manage these rules.

3) Check and ensure routing works as expected!

If you added persistent routes, you can check them by executing netstat -rn | grep -A10 'Persistent Routes'.

And, finally, run a few tracert commands against both IP addresses which are supposed to be accessed via VPN and against those which should work without VPN.

o.v

Posted 2009-07-24T09:33:51.157

Reputation: 121

1

This can't be done in Windows without using additional programs, batch files, or the command line. An alternative is to get a virtual (or physical) machine which you can run the VPN on.

It seems strange that something as easily explainable as this is so difficult to achieve. How difficult could it be to just route traffic from one program to the VPN interface and all the other programs to the default NIC interface? Why would we need to set up a whole virtual machine for that? And with Linux it's possible but its solution is not very elegant either.

It's very much sought after too: I came across dozens of threads on the same subject. So I only hope someone realises the ludicrousness of this and do something about it. (In Windows 8!)

This solution is from an unattributed batch file. It has been slightly adapted.

Instructions for Windows 7

The script will connect to and route traffic through your VPN until a reboot - you can replace route add with route -p add for the change to persist, but if you don't have a persistent IP with your VPN, it will eventually stop working when your VPN IP changes.

  1. Open the Network and Sharing Center
  2. Open the properties for your VPN connection
  3. Click the Networking tab
  4. For both IPv4 and 6:
    1. Click Properties
    2. Click Advanced
    3. Uncheck Use default gateway[...]
  5. Close everything opened from the previous steps
  6. Edit and save the batch script found below
  7. Run it as an administrator

You need to replace the following in the script:

  • <VPN> with the Name of the VPN connection you created
  • <USER> with the VPN username
  • <PASS> with the VPN password
  • <TARGET> with the IP address you want routed through the VPN (if you want to route more addresses, simply duplicate the three lines where the target is used)

Note: If you don't want to save the password in the file, replace <PASS> with %password% and add the following after the first line of the script: set password= Input password:.

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

Xantippe

Posted 2009-07-24T09:33:51.157

Reputation: 19

1

You can use something like netcatcher - just add all the routes you need one time and forget it. It will automatically add and delete routes when you connect or disconnect your VPN session. If your VPN IP address is dynamically obtained (DHCP) netcatcher will catch it and update the routes right way.

Andy

Posted 2009-07-24T09:33:51.157

Reputation: 11

2

if this is something you wrote you need to disclose that http://www.anseko.com/about.html see [faq#promotion]

– Jeff Atwood – 2011-08-30T09:32:36.670

1

from russian forum: http://forum.ixbt.com/topic.cgi?id=14:43549

save as file (ex: vpn_route.vbs) and after vpn connected execute command

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

shibormot

Posted 2009-07-24T09:33:51.157

Reputation: 231