196

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?

2
  • 1
    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. Jun 10, 2015 at 3:06
  • 1
    I went ahead and asked a new question: superuser.com/questions/925947 Jun 10, 2015 at 3:18

13 Answers 13

185

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

12
  • 3
    "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? Jun 11, 2011 at 2:16
  • 19
    Personally, 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
    Sep 28, 2011 at 20:05
  • 2
    Same, this checkbox was all that was needed.
    – Luk
    Sep 6, 2012 at 20:59
  • 3
    Please 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
    Sep 25, 2012 at 0:06
  • 2
    I 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
    Sep 25, 2012 at 7:13
33

Use Add-VpnConnectionRoute cmdlet in Windows 8+.

Add-VpnConnectionRoute -ConnectionName 'My VPN Connection' -DestinationPrefix 192.168.123.0/24
2
  • 1
    This worked perfectly for me on Windows 10.
    – x-ray
    Jun 26, 2018 at 23:26
  • 4
    To remove a route, you can use Remove-VpnConnectionRoute with the same syntax. There is no Get-VpnConnectionRoute sadly, but to view routes, you can do (Get-VPNConnection -ConnectionName '...').Routes.
    – mwfearnley
    Apr 5, 2022 at 10:51
22

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!

12

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.

2
  • A comment on "there is no Get-VpnConnectionRoutes cmdlet": you can get the routes by first gettings the vpn connection and then check the routes property: $vpnConnection = Get-VpnConnection "<name of vpn connection>"; $vpnConnection.Routes; Feb 3, 2021 at 6:21
  • You can get list of routes by executing this command: (get-vpnconnection -ConnectionName "<VPN connection name>").routes
    – Milad
    Jul 15, 2021 at 11:03
11

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.

3
  • This is a good solution provided your hardware can handle it well.
    – Enigma
    Feb 7, 2013 at 15:16
  • Used this solution for years, until found this thread. :)
    – o.v
    Aug 7, 2019 at 13:48
  • That's a really cool solution :) Jul 22, 2020 at 9:28
9

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'.

2
  • 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
    Apr 24, 2015 at 1:55
  • 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
    Jun 16, 2015 at 8:51
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

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

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).

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..

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.

1
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
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
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .