Summary: To access a specific list of websites through a specific VPN on Mac OS X 10.6, I created /etc/ppp/ip-up
, copied in the script below, and chmod
ed it executable.
Background: Most universities pay publishers to provide unlimited access to their journals and other publications. Access control is usually based on IP address, with the publisher allowing free access only to the university’s specific block of IP addresses. In order for a student or faculty member to take advantage of the system, they must either be on campus or be routing their internet traffic through their university’s VPN. The problem is, routing through VPNs in Mac OS X is kind of an all-or-nothing deal: either it uses the VPN for everything or it uses it only for IP addresses in the VPN’s subnet, with the lacodeer being the default behaviour in Mac OS X 10.6.
I want finer control. Specifically, I want OS X to use the VPN for specific websites. It turns out this isn’t too hard.
Solution: To route specific websites (i.e. journal publishers) through my university VPN, I created /etc/ppp/ip-up
with the following contents:
#!/bin/bash
#
# Script which handles the routing issues as necessary for pppd.
# When the ppp link comes up, this script is called with the following
# parameters:
# $1 the interface name used by pppd (e.g. ppp3)
# $2 the codey device name
# $3 the codey device speed
# $4 the local IP address for the interface
# $5 the remote IP address
# $6 the parameter specified by the 'ipparam' option to pppd
#
## Routing setup for VPN
# Array of IP addresses of the VPN server(s)
# I have it grab the list of round-robin'ed IP addresses based on the domain name
VPN_HOSTS=$(dig +short inside.mcgill.ca)
# Array of hostns to route for
# These are the domain names and IP addresses that will be accessed through the VPN
VPN_ROUTE_FOR_HOSTS=(www.elsevier.com www.sciencedirect.com www.thelancet.com www.cmaj.ca scholar.google.com ncbi.nlm.nih.gov bmj.com)
# Make sure we're in the VPN
for i in ${VPN_HOSTS[@]} ; do if [[ $i == ${5:-} ]] ; then
# Add the routes
for k in ${VPN_ROUTE_FOR_HOSTS[@]} ; do
for l in $(dig +short $k) ; do
/sbin/route add -host $l -interface $1
done
done
fi ; done
Put your specific values into VPN_HOSTS
and VPN_ROUTE_FOR_HOSTS
. Don’t forget to chmod a+x /etc/ppp/ip-up
. The routes will be added when you connect to the VPN and disappear when you disconnect from it.
Edit: For some reason I thought that route
didn’t resolve domain names. It does, and now the scripts even simpler.