Windows – Can’t change routes with VPN Client

vpnwindows

My VPN connection forces all internet traffic through the tunnel, and that's very slow. I want to be able to tunnel only certain IP addresses, and to do that at my side (client-side).

I'm connecting to a VPN with FortiSSL Client, the route table looks like this before a connection is established:

Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0      192.168.0.1    192.168.0.101     40
        127.0.0.0        255.0.0.0         On-link         127.0.0.1    306
        127.0.0.1  255.255.255.255         On-link         127.0.0.1    306
  127.255.255.255  255.255.255.255         On-link         127.0.0.1    306
      192.168.0.0    255.255.255.0         On-link     192.168.0.101    276
    192.168.0.101  255.255.255.255         On-link     192.168.0.101    276
    192.168.0.255  255.255.255.255         On-link     192.168.0.101    276
    192.168.119.0    255.255.255.0         On-link     192.168.119.1    276
    192.168.119.1  255.255.255.255         On-link     192.168.119.1    276
  192.168.119.255  255.255.255.255         On-link     192.168.119.1    276
    192.168.221.0    255.255.255.0         On-link     192.168.221.1    276
    192.168.221.1  255.255.255.255         On-link     192.168.221.1    276
  192.168.221.255  255.255.255.255         On-link     192.168.221.1    276
        224.0.0.0        240.0.0.0         On-link         127.0.0.1    306
        224.0.0.0        240.0.0.0         On-link     192.168.119.1    276
        224.0.0.0        240.0.0.0         On-link     192.168.221.1    276
        224.0.0.0        240.0.0.0         On-link     192.168.0.101    276
  255.255.255.255  255.255.255.255         On-link         127.0.0.1    306
  255.255.255.255  255.255.255.255         On-link     192.168.119.1    276
  255.255.255.255  255.255.255.255         On-link     192.168.221.1    276
  255.255.255.255  255.255.255.255         On-link     192.168.0.101    276

After connecting it looks like this:

Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0      192.168.0.1    192.168.0.101   4265
          0.0.0.0          0.0.0.0         On-link        172.16.0.1     21
        127.0.0.0        255.0.0.0         On-link         127.0.0.1   4531
        127.0.0.1  255.255.255.255         On-link         127.0.0.1   4531
  127.255.255.255  255.255.255.255         On-link         127.0.0.1   4531
       172.16.0.1  255.255.255.255         On-link        172.16.0.1    276
      192.168.0.0    255.255.255.0         On-link     192.168.0.101   4501
    192.168.0.101  255.255.255.255         On-link     192.168.0.101   4501
    192.168.0.255  255.255.255.255         On-link     192.168.0.101   4501
    192.168.119.0    255.255.255.0         On-link     192.168.119.1   4501
    192.168.119.1  255.255.255.255         On-link     192.168.119.1   4501
  192.168.119.255  255.255.255.255         On-link     192.168.119.1   4501
    192.168.221.0    255.255.255.0         On-link     192.168.221.1   4501
    192.168.221.1  255.255.255.255         On-link     192.168.221.1   4501
  192.168.221.255  255.255.255.255         On-link     192.168.221.1   4501
   200.250.246.74  255.255.255.255      192.168.0.1    192.168.0.101   4245
        224.0.0.0        240.0.0.0         On-link         127.0.0.1   4531
        224.0.0.0        240.0.0.0         On-link     192.168.119.1   4502
        224.0.0.0        240.0.0.0         On-link     192.168.221.1   4502
        224.0.0.0        240.0.0.0         On-link     192.168.0.101   4502
        224.0.0.0        240.0.0.0         On-link        172.16.0.1     21
  255.255.255.255  255.255.255.255         On-link         127.0.0.1   4531
  255.255.255.255  255.255.255.255         On-link     192.168.119.1   4501
  255.255.255.255  255.255.255.255         On-link     192.168.221.1   4501
  255.255.255.255  255.255.255.255         On-link     192.168.0.101   4501
  255.255.255.255  255.255.255.255         On-link        172.16.0.1    276

The VPN client puts a catch-all route with a lower metric than all of my other routes and this routes all internet traffic through the tunnel.
I tried changing my default internet route's metric to a lower value:

C:\Windows\system32>route change 0.0.0.0 mask 0.0.0.0 192.168.0.1 metric 10 if 13
OK!

But nothing changed.

Then I tried deleting the VPN's "catch-all" route, the one with metric 21 above:

C:\Windows\system32>route delete 0.0.0.0 mask 0.0.0.0 if 50
OK!

And it broke everything:

C:\Windows\system32>ping 8.8.8.8

Pinging 8.8.8.8 with 32 bytes of data:
PING: transmit failed. General failure.

I tried changing the metric on the adapters as well, but the FortiSSL Client overrides all settings when it connects, so it didn't help.

The fix must come from my side, as the folk on the other side take days to respond.

I'm running Windows 7 x64 if that helps.

— UPDATE (2013-12-24) —

Thanks to mbrownnyc's tip, I examined the issue with Rohitab and found out FortiSSL Client watches the routes table with the NotifyRouteChange IP Helper API call.

I set a breakpoint before NotifyRouteChange calls and used the option "Skip Call" to sucessfully prevent FortiSSL from resetting route metrics, and I now have:

Routes with metrics favoring my Wifi adapter

Yet when I run tracert my route still goes out through the VPN:

C:\Windows\system32>tracert www.google.com

Tracing route to www.google.com [173.194.118.83]
over a maximum of 30 hops:

  1    45 ms    47 ms    45 ms  Jurema [172.16.0.1]

Is there any aspect of windows networking I'm not aware of that can favor a certain route even if route print's metrics say otherwise?

Best Answer

Note that I am not using regular networking notation for addressing here (such as CIDR or even host/mask notation, as not to confuse the asker).

Instead of deleting your "default gateway" route (0.0.0.0 mask 0.0.0.0) so that your network stack has no idea where to send most packets, try to raise the metric of the VPN route below that of your default route (in this case 4265).

After connecting with the Fortigate client:

route change 0.0.0.0 mask 0.0.0.0 172.16.0.1 metric 4266 if N

Where N is the interface number for the fortissl interface returned at the beginning of route print.

The networking stack should treat this properly:

  • The route that "includes the destination addresses" will handle the packets (the route tells the network stack to send packets destined for this IP to this gateway for further routing).
  • All packets with a destination IP 172.16.*.* will be sent to the VPN; because the Windows network stack knows that if there's an address attached to an interface, then that interface is how you access other IPs on in that address range. I can get more explicit with the range if you post the "Subnet Mask" for the 172.16.0.1.

You must determine the IP addresses of resources you need access to over the VPN. You can do this easily by using nslookup [hostname of resource] when connected without having adjusted the routes.

[rant]

I have no problem with allowing split-tunneling over VPN, particularly because of the usage issue you cite. If your IT department considers split-tunneling a security mechanism, they need to rethink what they are doing:

  • VPN clients' access to resources should be isolated and heavily restricted as if they are being accessed via the Internet (because assets where you don't assert complete control present higher risk than assets where you can assert some).
  • They should integrate a network access control mechanism for VPN clients. This could allow them to enforce some policies on the client machines (such as "are anti-virus definitions up to date?", etc etc).
  • Consider using a rigid solution like the Fortigate SSL VPN Virtual Desktop (which is fairly easy to configure and free [me thinks] with the SSL VPN license).

[/rant]

Related Question