Friday, September 28, 2007

Connecting OS X Leopard to a Cisco VPN

That nastiest part of being an early adopter is that we’re forced either to to without creature comforts, or to hack up substitutes. Now that Leopard is fairly stable (as of pre-release 9a559), some of us have started using it full-time--but the first bump in the road is that our Cisco VPN client doesn’t work, and we can’t connect to our offices to work from home.

Luckily, there is a solution: vpnc. Vpnc is a command-line client for Cisco’s VPN concentrators, and it works on Linux, every flavor of UNIX, and most importantly, OS X including Leopard. It’s simple to get up and running:

1. Install XCode Tools from the OS X install DVD

You’re going to be compiling some software by hand, so you need the compiler and other utilities included in XCode Tools. Pop in your DVD and look under “Optional Installs” for the XCode Tools package. Double-click it and follow your nose.

2. Install the TUN/TAP kernel extensions

Download the tun/tap drivers for OS X. The version for Tiger (OS X 10.4) works fine with Leopard (OS X 10.5) as well. Download the source package: inside it are the folders tun.kext and tap.kext, containing the pre-compiled kernel extensions. In a terminal window, locate those folders and install them as follows:

        # sudo mv ./PATH/tun.kext /Library/Extensions
        # sudo mv ./PATH/tap.kext /Library/Extensions
        # sudo chown -R root:wheel /Library/Extensions/{tun,tap}.kext

Then test them with the following commands:

        # sudo kextload /Library/Extensions/{tun,tap}.kext
        kextload: /Library/Extensions/tun.kext loaded successfully
        kextload: /Library/Extensions/tap.kext loaded successfully

        # sudo kextunload /Library/Extensions/{tun,tap}.kext
        kextunload: unload kext /Library/Extensions/tun.kext succeeded
        kextunload: unload kext /Library/Extensions/tap.kext succeeded

3. Install libgpg-error and libgcrypt

The latest version of each should be fine; that’s what I’m using. You have to install them in the order listed: libgcrypt uses libgpg-error and won’t build without it. Download and unpack the tarball for each, then in a terminal window do the following:

        # cd libgpg-error-version
        # ./configure
        # make
        # sudo make install

        # cd libgcrypt-version
        # ./configure
        # make
        # sudo make install

When configuring libgcrypt for an Intel Mac, you’ll need to say “./configure --disable-asm” or else the library will build and install fine, but programs using it will not work. You can leave that option off for PPC Macs.

4. Install vpnc

Download the vpnc source code and unpack it in a convenient location. In a terminal window, build and install it:

        # cd vpnc-version
        # make
        # sudo make install

If you installed the above libraries correctly, vpnc should build and install without errors. That’s it! You’re ready to be productive again! That is, as soon as you...

5. Configure vpnc

The vpnc distribution comes with a template configuration file, vpnc.conf, which looks like this:

        IPSec gateway <gateway>
        IPSec ID <group-id>
        IPSec secret <group-psk>
        IKE Authmode hybrid
        Xauth username <username>
        Xauth password <password>

If your VPN uses group authentication and XAuth, you can fill in the blanks in this file and you’re set to go. You may need to change the IKE Authmode option from “hybrid” to “psk.” Put your username and password in the XAuth lines, and get the gateway IP address and group ID from your Cisco VPN configuration.

The IPSec secret is your group password. If you don’t know it, you can look in:


There you’ll find the encrypted group password. Copy and paste that into this web page to recover the original password, and put that in your vpnc.conf.

Save the resulting file in /etc/vpnc/vpnc.conf

5. Run vpnc

Running vpnc conveniently involves several steps, so it’s best to put it in a shell script like the following. I named mine, imaginatively enough, “startvpn.”


# Remember the default gateway
GATEWAY=$( route get default | egrep gateway | awk '{print $2}' )

# Reload the kernel modules
kextunload /Library/Extensions/tun.kext
kextunload /Library/Extensions/tap.kext
kextload /Library/Extensions/tun.kext
kextload /Library/Extensions/tap.kext

/usr/local/sbin/vpnc /etc/vpnc/vpnc.conf

# Switch the default gateway back
/sbin/route delete default
/sbin/route add default $GATEWAY

This script first reloads the kernel modules, then starts the VPN, and finally resets your default gateway so that normal traffic will not go through the gateway. If you want everything to go through the VPN, you can change the script accordingly. Note that this script is Darwin-specific; you’ll need to change it slightly to make it work on Linux or some other *NIX flavor.

You should probably also create a “stopvpn” script like this:


# Stop the vpn

# Unload the kernel modules
kextunload /Library/Extensions/tun.kext
kextunload /Library/Extensions/tap.kext

The unloading and reloading of kernel modules is just for good hygiene; well-written kernel modules shouldn’t need reloading, but it can help clear leftover state from your last connection and avoid potential problems. TIP: this is very useful for Cisco’s vpn client.

Put the two scripts somewhere in your path. Then, whenever you need to connect to your VPN, just open a terminal and say “sudo startvpn,” followed by “sudo stopvpn” when you’re done.

Happy telecommuting!