Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

A script to provide VPN split routing via PPPTP Network
Apple's PPTP Internet Connection app doesn't provide split routing. To avoid that all your traffic going through the VPN tunnel, you could start (as root using sudo), when the VPN connection is already established, the following script.

#! /bin/sh
dr=`netstat -nr | grep ' UHLW ' | awk '{print $1}'`
route delete default AAA.BBB.CCC.DDD
route add    default $dr
route add    AAA.BBB.0.0 AAA.BBB.CCC.DDD
Where AAA.BBB.CCC.DDD is provided by the logfile of the PPTP connection application: "remote IP address AAA.BBB.CCC.DDD" . Then only connections to the AAA.BBB.x.y range of addresses will use the VPN.

[robg adds: I haven't tested this one.]
    •    
  • Currently 3.40 / 5
  You rated: 5 / 5 (5 votes cast)
 
[31,480 views]  

A script to provide VPN split routing via PPPTP | 16 comments | Create New Account
Click here to return to the 'A script to provide VPN split routing via PPPTP' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
A script to provide VPN split routing via PPPTP
Authored by: silas on Mar 17, '03 11:35:17AM
I wanted to share a script I wrote that sort of extends this functionality and allows it to be run automatically. (RobG, this may be worth a hint in itself?). Anyway, this is a Perl script:


#!/usr/bin/perl
#
# fix_vpn_routing.pl
# To be run as root.
#
# Fixes OS X's VPN routing of all packets over the VPN
# to only route destination network packets over the VPN
#
# Parts based on getLocation.pl written by Christopher Copeland
#
# Last updated on 01/10/2003 by JCH
  
use strict;

my $vpn_server="123.45.67.8"; # VPN Server
my $real_gateway="192.168.1.1"; # Real Default Gateway
    
# The networks you want to route over the VPN
my @vpn_nets = ('123.45.67.0/24', '199.164.165.0/24');

# Get our current location from the system
my $vpn_ip = &get_location_from_scutil() || "";

if ($vpn_ip eq $vpn_server) {
  foreach my $vpn_net (@vpn_nets) {
    system ("route add -net $vpn_net $vpn_server");
  }
  system("route delete default $vpn_server");
  system("route add default $real_gateway");
}
 
exit;

sub get_location_from_scutil {

  my @scutil = `scutil <<- end_scutil 2> /dev/null
  open
  show State:/Network/Interface/ppp0/IPv4
  close
  end_scutil`;

  my @matches = map { m/0 : (.*)/ } @scutil;
  if(@matches == 2) {
    return $matches[1];
  }
  else {
    return undef;
  }
}

I then added a line at the end of /System/Library/SystemConfiguration/Kicker.bundle/Resources/set-hostname that calls this script every time you change location (which connecting to a VPN qualifies for):


logger fixing VPN routing if need be
/usr/local/bin/admin/fix_vpn_routing.pl
Now, when you connect to the VPN, the script will automatically update the routing for you. When you disconnect, or change location to a non-VPN connection, the routing will be handled as normal by the OS. If anyone has any enhancements, I'd love to see them!

[ Reply to This | # ]
A script to provide VPN split routing via PPPTP
Authored by: Numbski on Mar 17, '03 03:22:30PM

I've been doing this for a while now manually. Good to see someone scripted it. :)



[ Reply to This | # ]
A script to provide VPN split routing via PPPTP
Authored by: PigDawg on Mar 24, '03 08:51:43PM

Has anyone got this to work? It didn't work for me. I added teh fix_vpn_routing.pl file to /usr/local/bin not /usr/local/bin/admin. Is that important? Also, I added the two lines to set-hostname and finally I changed the permissions of fix_vpn_routing.pl to 755. What else is needed? I even rebooted my Mac.

How do I know its not working for me? When I am connected to the VPN Mail cannot connect to my AT&T Broadband account because it is now considered to be outside the AT&T network.



[ Reply to This | # ]
A script to provide VPN split routing via PPPTP
Authored by: tapella on Apr 29, '03 11:35:11AM

I had trouble with my connections "lagging out" at first. What you need to do is explicitly add DNS information to the PPTP section of your Network Preferences. These should be the ones that you pick up from AT&T when you're normally connected to that network.

Personally I am connecting through a wireless hub, and I used the DNS information that was in the WAN area of the status info on the hub.



[ Reply to This | # ]
A script to provide VPN split routing via PPPTP
Authored by: tapella on Apr 29, '03 11:31:33AM

This hint is awesome.



[ Reply to This | # ]
A script to provide VPN split routing via PPPTP
Authored by: Matthieu Brunet on Jun 16, '03 10:33:31AM

I don't understand what is the "real gateway" is ? Where can i found it ?
Plus, when I do a "netstat -nr" I don't have a UHLW tag. Only UGS, UH or UGHS



[ Reply to This | # ]
A script to provide VPN split routing via PPPTP
Authored by: tapella on Oct 27, '03 08:58:09PM

The "real gateway" is your normal gateway when not connected to the VPN. For example, if you use a little wireless hub or similar, it's probably 192.168.1.1. If you go to the Network Preference Pane details for the non-VPN connection you're using, the "real gateway" IP address is labelled as "Router" (at least in Panther).

Basically those two variables at the top of the code (vpn_server and real_gateway) are the system variables that get swapped. Normally real_gateway is your default Router/Gateway. When you connect to the VPN, vpn_server gets set as the default. The script unsets vpn_server as the default and then sets your normal real_gateway as the default, so that all the traffic that's not specifically designated in the vpn_nets list goes outside your VPN.

The line:
route add -net $vpn_net $vpn_server
is saying route all the IP addresses in the $vpn_net list through the $vpn_server IP (your VPN Router/Gateway). As I mentioned in the last paragraph, things not in that list will go through the "default gateway", which was reset back to your normal Router/Gateway by the script.

I'm not sure if that's clear or not, or if it helps.



[ Reply to This | # ]
A fix for Panther and possibly 10.2.8
Authored by: PigDawg on Oct 31, '03 11:08:53AM
If you had implemented this hint before 10.2.8 and found that it suddenly stopped working here is why... The hint says to modify the file
/System/Library/SystemConfiguration/Kicker.bundle/Resources/set-hostname
But it has been moved to (and probably overwritten)
/System/Library/SystemConfiguration/Kicker.bundle/Contents/Resources/set-hostname
Modify the set-hostname file in its new location as the hint spells out and everything should start working again.

[ Reply to This | # ]
Wait, my bad
Authored by: PigDawg on Oct 31, '03 11:17:00AM

This script trick just won't work in Panther. It looks like you'll have to use one of the other tricks listed in this hint and its replies.



[ Reply to This | # ]
A script to provide VPN split routing via PPPTP
Authored by: millz on Nov 17, '03 08:35:53PM

That script basically worked for me in panther, except that the get_location_from_scutil was returning my vpn-assigned client IP address as opposed to the vpn server address.
To fix that, I changed $matches[1] to $matches[0].

Also, I needed to change my vpn config in "internet connect" to use the IP address instead of the hostname of my vpn server. And I used ip addrs in the variables in the script.

Also, I used the other tip provided by another commenter in this thread and added the call to this script to the /System/Library/SystemConfiguration/Kicker.bundle/Contents/Resources/set-hostname script (which has to be edited as root with sudo).

Thanks! I have wanted this for a while now!



[ Reply to This | # ]
A script to provide VPN split routing via PPPTP
Authored by: waffffffle on Sep 10, '04 04:45:10PM
I don't understand this line: my @vpn_nets = ('123.45.67.0/24', '199.164.165.0/24'); I have 2 subnets that I want to connect to over VPN: 128.112.x.x and 140.180.x.x . How do I write them using the notation you use? I don't understand what the 0/24 part means. Thanks.

[ Reply to This | # ]
A script to provide VPN split routing via PPPTP
Authored by: dani++ on Aug 21, '03 12:26:18PM
'silas' perl script does not work for me... but I have improved the original scrip to work even more automagically (does still need to be called after the VPN connection is started, automatically or manually).

Must be run as root, of course.

#!/bin/bash
################################################################################
# FIX VPN ROUTING . SH
# Author: Daniel Giribet
# Improvement over shell script published by 'Anonymous' on macosxhints.com
# 'silas' perl script did not work for me, so I use this one.
# Though the scipt is trivial, use at your own risk.

PPP_LOG=/tmp/ppp.log

default_=$(/usr/sbin/netstat -nr | grep ' UHLW ' | awk '{print $1}')
remote_vpn_str=$(/usr/bin/tail -5 $PPP_LOG|/usr/bin/grep 'remote IP address')
n=$(echo $remote_vpn_str |/usr/bin/wc -w|/usr/bin/tr -d '\n' |/usr/bin/tr -d ' ')
remote_vpn=$(echo $remote_vpn_str | awk '{print $'$n'}')
mask=$(echo $remote_vpn|/usr/bin/sed -e 's/\./ /g'|awk '{print $1"."$2".0.0"}')

/usr/bin/logger 'fix_vpn_routing.sh: modifying routes...'

/sbin/route delete default $remote_vpn
/sbin/route add default $default_
/sbin/route add $mask $remote_vpn

/usr/bin/logger "fix_vpn_routing.sh: default: $default_ mask: $mask"



[ Reply to This | # ]

A script to provide VPN split routing via PPPTP
Authored by: carbon14 on Dec 08, '03 02:52:18AM

This script worked for me, but I had to change a few things to make it work. Here is the new script:

#!/bin/bash
################################################################################
# FIX VPN ROUTING . SH
# Author: Daniel Giribet
# Improvement over shell script published by 'Anonymous' on macosxhints.com
# 'silas' perl script did not work for me, so I use this one.
# Though the scipt is trivial, use at your own risk.
#
# 12/7/03 - modified by carbon14
# fixed mask to be derived from local ip
# fixed mask sed script. You can alter the mask size by changing "$3" to 0

PPP_LOG=/tmp/ppp.log

default_=$(/usr/sbin/netstat -nr | grep ' UHLW ' | awk '{print $1}')
remote_vpn_str=$(/usr/bin/tail -5 $PPP_LOG|/usr/bin/grep 'remote IP address')
local_vpn_str=$(/usr/bin/tail -5 $PPP_LOG|/usr/bin/grep 'local IP address')
n=$(echo $remote_vpn_str |/usr/bin/wc -w|/usr/bin/tr -d 'n' |/usr/bin/tr -d ' ')
remote_vpn=$(echo $remote_vpn_str | awk '{print $'$n'}')
local_vpn=$(echo $local_vpn_str | awk '{print $'$n'}')
mask=$(echo $local_vpn|/usr/bin/sed -e 's/\./ /g' | awk '{print $1"."$2"."$3".0"}')

/usr/bin/logger 'fix_vpn_routing.sh: modifying routes...'

/sbin/route delete default $remote_vpn
/sbin/route add default $default_
/sbin/route add $mask $remote_vpn

/usr/bin/logger "fix_vpn_routing.sh: default: $default_ mask: $mask"


There was a problem with the sed script not having the proper escape for "."

You can also modify the size of the mask by removing the "$3" and setting it to 0

-Carbon14



[ Reply to This | # ]
A script to provide VPN split routing via PPPTP
Authored by: aleck on Dec 16, '03 11:30:21AM

I'm new to Unix stuff, so I'm having trouble how to start this after I connect to VPN.

I've set chmod 777 for this file, and tried to add it as the last line in the set-homepage file, as discussed for the perl script, but no luck.

What is the command line for starting this file? Simply typing the file name has no effect.



[ Reply to This | # ]
A script to provide VPN split routing via PPPTP
Authored by: scstraus on Aug 20, '04 10:48:31AM

There's a "correct" way of doing this which is listed at the end of this thread:

http://www.macosxhints.com/article.php?story=20030906232648318&query=pptp+default+route

Be sure and try the one at the end of the thread rather than the beginning because it uses the OS X standard methods for doing everything and is very flexible.

And no, I didn't write the hint, I just thought it was so elegant that I'd tell everyone about it.

---
I came into this game for the action, the excitement. Go anywhere, travel light, get in, get out, wherever there's trouble, a man alone.



[ Reply to This | # ]
A script to provide VPN split routing via PPPTP
Authored by: uve on Mar 28, '10 04:54:21AM

try this instrusction http://www.cometip.com/2010/03/mac-os-vpn-routing.html
it works for me.



[ Reply to This | # ]