Recently, a co-worker was asking about my configuration for connecting to the corporate VPN, and I thought the information might be useful for others as well — I use a combination of Tunnelblick; an OpenVPN client for Mac OS X, Sidekick; an application that changes Mac OS X settings based on your physical location (and/or network SSID, etc.), and a little shell script I wrote to start the VPN, define additional routes, and update my dynamic DNS hostname.
Tunnelblick
Tunnelblick is a free, open source graphic user interface for OpenVPN on Mac OS X. It installs itself in the menu bar, and provides a quick & easy way to connect and disconnect from one or more configured VPNs. Tunnelblick comes as a ready-to-use application, with all necessary binaries and drivers. To use Tunnelblick, you’ll need access to a VPN server — either a corporate VPN account, for example, or one of the many public VPN servers now available on the internet. The public VPN solutions are practical when you need to use a public WiFi service (airport, coffee shop, etc.) and would like to encrypt your traffic, get around transparent proxies, firewall rules, etc. — or maybe you’d just like to make sure your ISP isn’t tracking your activity.
Sidekick
Sidekick is not free and open source — it’s a $30 application, but well worth the expense if, for example, you travel back & forth from work with your laptop. You define a set of rules — a physical location, a network SSID, etc. — and actions Sidekick will perform when those rules are met. You might have “Home”, “Work”, “Corp VPN”, and “Public VPN” locations. The Home location could change your default printer and start a backup. The Corp VPN could start the appropriate Tunnelblick VPN, run a shell script to change some routes, and open a terminal window to a remote server.
As an example, in the Mac OS X System Preferences you could create a “Public” location, and in Sidekick, you could add a “Public VPN” place, setting it as the default. As it’s actions, you might set your default printer to CUPS-PDF, disable Time Machine, run vpn-public-connect.sh, and vpn-disconnect-all.sh “when leaving location“.
Custom Scripts
The vpn-public-connect.sh script is executed by Sidekick to start the VPN. It uses AppleScript to tell Tunnelblick to connect the VPN, then waits for a gateway host to be defined for the VPN device (either tun
or tap
), adds or removes custom routes, and updates a dynamic DNS hostname. The nsupdate-ddns.sh script used to update the dynamic DNS has been discussed in an earlier post.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#!/bin/sh vpn="PublicVPN" # Tunnelblick VPN configuration name dev="tap" # "tun" or "tap" as defined in VPN config tries="30" # wait up to $tries * 5 seconds for gateway host IP route_add="" # additional hosts or subnets to route through the VPN route_del="" # hosts or subnets to remove from VPN routing table echo "Starting VPN $vpn..." osascript -e " tell application \"Tunnelblick\" connect \"$vpn\" end tell" try=1 while [ -z "$gw_host" -a $try -le $tries ] do sleep 5 echo "Waiting for gateway host ($try/$tries)..." gw_host="`netstat -f inet -n -r | grep -v 'ff:ff:ff:ff:ff:ff' | \ sed -n \"s/^\([0-9][0-9\.]*\)[[:space:]].*[[:space:]]UH.*$dev[0-9][[:space:]0-9]*\$/\1/p\"`" (( try++ )) done [ -z "$gw_host" ] && exit 1 echo "Found gateway host $gw_host" echo "Adding custom routes..." for net in $route_add; do sudo route add $net $gw_host; done for net in $route_del; do sudo route delete $net $gw_host; done echo "Updating dynamic DNS entry..." nsupdate-ddns.sh |
Download the vpn-public-connect.sh script here.
The vpn-disconnect-all.sh script should be executed by Sidekick when leaving location (an optional checkbox when adding the script to Sidekick’s actions). The script simply tells Tunnelblick to close all VPNs, and then updates the dynamic DNS hostname.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/bin/sh echo "Closing all VPNs..." osascript -e " tell application \"Tunnelblick\" disconnect all end tell" sleep 5 echo "Updating dynamic DNS entry..." nsupdate-ddns.sh |