Connecting to a safe@office vpn on a Mac...

Let me start off by saying that I started using a Mac several years ago because I finally reached a tipping point. I knew I wanted to get more into photography and have access to things like Lightroom and Photoshop. I was also getting tired of administering my box (although I’m happy that Ubuntu is largely making that practice disappear for the average user). I want to write code, do photography, and still participate in the business world without worrying about whether my OpenOffice document is going to render correctly.

So I made the switch (please don’t flame me, I still use Linux quite a bit, and that will never change). Since the change, I’ve not had to spend much time trying to configure my system. Everything largely Just Works.

That is, until you want to setup a VPN connection.

On the other end of the connection is a Safe@Office product. It claims to support a generic L2TP client, and until recently, I didn’t really believe that. I’ve tried to use Apple’s built-in client several times in the past, and no dice. It would connect, but I couldn’t do shit. I finally sat down to figure it out the other day because I’ve grown tired of IPSecuritas.

Turns out my problem boiled down to routing. I left the “Route all my data through the VPN” box unchecked (because that’s just ridiculous), and what I ended up with was an extra default route to the VPN gateway via the VPN tunnel and another route to the VPN gateway via my normal internet connection. The problem is that the assigned IP address (from the VPN) is not on the company’s subnet. What I needed was an extra route to say route those IP addresses over the VPN link. But I only need this when the VPN is active.

Easier said than done.

So, I confess, I’m not terribly knowledgeable about all the services that underly Mac OS X. I don’t really want to be that knowledgeable about them–that’s the appeal. To someone else out there, this may be common knowledge, but it took me a while to find the answer.

As I mentioned before, what I really needed was to set this route up when my VPN connection comes online. It turns out that this is entirely possible. When you establish your connection, there’s a service called pppd that is used to help tunnel traffic over your new IPSEC connection. If you check out the man page for it (man pppd from the command line), and scroll through 40 pages of options, you’ll find that it will invoke a script called /etc/ppp/ip-up when the connection comes up, and one called /etc/ppp/ip-down when the connection comes down. Further more, it will look in /etc/ppp/peers/ConnectionName for additional options.

Sweet!

So, reading a little more, /etc/ppp/ip-up is executed with several parameters:

interface-name tty-device speed local-IP-address remote-IP-address ipparam

interface-name is the name of the ppp interface that has been established. In my case, it’s ppp0. tty-device is the name of the device used to help establish the connection (think modem or serial port). That doesn’t apply here, so it’s just an empty string. speed is the speed the tty-device is running at, but we don’t have one. So, the speed is 0. The local-IP-address is the IP address it used for the local side of the connection. Unless you tell it otherwise, it’s the first primary ip address of your machine. The remote-IP-address is where it gets interesting. That’s the address of you on the other side of the tunnel. It’s also the one that doesn’t map into my company’s subnet, necessitating the additional route. Finally, there is ipparam. Turns out, there is an option called ipparam that can be used to control the value of this field. Awesome.

On the routing side, I need to add a route that goes to the company’s subnet, but forces it to do so over the tunnel. Mac’s route command is pretty similar to Linux’s, so after taking a look at the man page for route, I came up with the following command to add the route:

route -n add -net $NET -interface $IFNAME

$IFNAME is actually set by pppd when it calls /etc/ppp/ip-up and /etc/ppp/ip-down. It’s also the first parameter to the script, but I like using names. To delete it is just the opposite:

route -n delete -net $NET -interface $IFNAME

Were almost there.

Before I show you all the steps, let me say that the below steps only work for Snow Leopard. Turns out Apple broke this facility in Leopard, and it doesn’t appear to have ever been fixed (grrr).

Step 1: Create the VPN connection

I won’t walk through the details here. I created a new VPN connection called “Work” that uses L2TP. I also clicked the authentication button to and added my preshared key, and my password for the connection. On the Safe@Office side, you need to make sure you have enabled L2TP clients and set the preshared key. You also need to make sure you set up a user who is capable of using the VPN. This is fairly well documented online and in the manual, so I won’t repeat that here.

Step 2: Create an option file for the connection

My company, like most, uses the 10.0.0.0 class A subnet. I want to pass this as the ipparam to /etc/ppp/ip-up. Also, I called my connection “Work”. You might want to call yours something else, so translate accordingly. Here’s how to do it:

> sudo mkdir /etc/ppp/peers
> echo ipparam 10 | sudo tee /etc/ppp/peers/Work

This creates a file called /etc/ppp/peers/Work that contains a single line:

ipparam 10

Step 3: Create the ip-up and ip-down scripts

Next, I created the /etc/ppp/ip-up script with the following content:

#!/bin/bash

# This is the ipparam that we set in /etc/ppp/peers/Work
MYNET=$6

/sbin/route -n add -net $MYNET -interface $IFNAME >> /var/log/ppp.log 2>&1

And, the /etc/ppp/ip-down script:

#!/bin/bash

# This is the ipparam that we set in /etc/ppp/peers/Work
MYNET=$6

/sbin/route -n delete -net $MYNET -interface $IFNAME >> /var/log/ppp.log 2>&1

Remember to:

> sudo chmod a+x /etc/ppp/ip-up /etc/ppp/ip-down

That will make the files executable.

Step 4: Try it out!

Now when you connect to your VPN, it should add the necessary route and delete it when the connection goes down. If you’re having trouble, it’s likely because your network layout is different. Talk to the appropriate admin and get advice on what it should be from them.

Good luck!