Custom VPN routing and DNS under OSX

      Comments Off on Custom VPN routing and DNS under OSX

It’s very easy to set up a VPN using OSX.   Apple has one of their typical help pages which makes it appear so simple even a child could do it.   But, often you have special cases which are not easily covered by the default setup, and that’s where things get tricky.

In my situation, I don’t check the “Send all traffic through VPN” because I like to access the Internet normally even when connected via the client’s VPN.  That’s where the problems arise, since I often can’t reach internal subnets or use the client’s internal DNS servers automatically.

It turns out that because of OSX’s Unix heritage, making even advanced customizations is quite easy (so long as you’re comfortable creating scripts at the command line).   I’ll give you a quick tour of how I set up a VPN connection which:

  1. Added additional routes for foreign subnets.
  2. Changed my DNS to use a DNS server on the remote host.

The important thing to know is that there are two scripts that you can create which are triggered after successful VPN setup and at shutdown:

  • /etc/ppp/ip-up – runs after any VPN connection is established
  • /etc/ppp/ip-down – runs after any VPN connection is terminated

You can find complete documentation for these scripts on Apple’s Developer site or just by typing “man pppd” at the OSX command line.

For example, my /etc/ppp/ip-up VPN start-up script looks like this:

#!/bin/bash
ALTDNS=192.168.200.52   # DNS I want to use instead
if [ "$DNS1" == '192.168.0.8' ]; then
    # Add a route to another internal subnet
    /sbin/route -n add 192.168.200.0/24 $IPLOCAL
    # Temporarily use their DNS
    networksetup -setdnsservers 'My VPN Name' $ALTDNS
fi

In my case, the $DNS1 variable makes it easy to recognize the particular VPN because the client publishes their internal DNS as 192.168.0.8.   Since the script runs for all VPN’s, you’ll need to qualify commands to be sure they are triggered according to some criteria that matches your requirements.

Note the following:

  1. I use /sbin/route to configure an extra route for the 192.168.200.0 subnet.  This doesn’t have to be undone, since it will disappear automatically when the VPN is shut down.
  2. I use the OSX networksetup tool to specify a DNS server for the VPN (which will be the same name as the one listed in your Network Settings control panel).

All of the above need no shutdown script, so I didn’t need to create an /etc/ppp/ip-down.

Creating Your Own Scripts

Creating these scripts requires that you have root access, so be very very careful.  I suggest you use the pico or vi editors to create and edit these files, since both are built into OSX.

For example:

mymac% sudo bash
Password: .....
bash-3.2# cd /etc/ppp
bash-3.2# pico ip-up
... create or edit your script in pico ...
bash-3.2# chmod 755 ip-up

The above switches to root, and allows you to edit your own script, then changes permissions to be sure it’s executable (otherwise it won’t run).  Once your script is created, you can start your VPN normally, and things should work.

If you’re not sure about what parameters are passed to the script, you can cheat by creating a harmless dummy script instead.  For example, you can put the following in /etc/ppp/ip-up:

!/bin/bash                                                                     
echo DNS1: $DNS1 DNS2: $DNS2 IPREMOTE: $IPREMOTE >/tmp/grabinfo.txt
echo script arguments: $* >>/tmp/grabinfo.txt

Then, you can inspect the VPN details by looking at /tmp/grabinfo.txt:

bash-3.2# cat /tmp/grabinfo.txt 
DNS1: 192.168.0.8 DNS2: IPREMOTE: 192.168.0.150
command args: ppp0 0 192.168.0.151 192.168.0.150 192.168.22.1

The above information may be useful in your script itself, and it’s easier than trying to guess.

From there, you’re on your own.  But, hopefully this is enough to solve a wide variety of custom configuration needs.

Comments

comments