Wednesday, May 11, 2011

Fun with Multiple VPN Connections on Mac OS X

Disclaimer: Frankly, I'm neither a Unix nerd nor a network freak. Maybe this is why I prefer using Mac OS X: In most cases things are simply working, or at least some nice graphical interfaces guides me through the network configuration jungle. So, use my tips on your own risk and feel free to write me a comment, if you can explain things better :-)

Virtual private network (VPN) are one of these things making me nervous without a nice GUI. Fortunately, OS X directly supports all the protocols I need (and thank you, Apple, for supporting the Cisco protocol as of OS X version 10.6). Setting up a VPN is as simple as installing a printer. Maybe even simplier ;-)

However, there are always new problems challenges waiting, and one of these challenges is the use of multiple VPNs simultaneously. I have the following situation: I can only connect to some local network, which does not allow any internet connections. For that purpose, I have to use a VPN "T" -- the VPN server "TServer" (names are only for simplify reading) is more or less the only thing accessible from that internal network. So, every connection to the internet runs through this VPN.

Now, I have to connect to a server "S", which only accepts connections from a local network, I call it "FNet". And my VPN server "TServer" is not part of this network "FNet". In order to access this server, I usually start another VPN "F" (with another VPN-server "FServ", virtually placing me (and my machine's IP address) inside the local network "FNet". Unfortunately, I can only connect to "FServ" via the first VPN. So, the question is, how to set up the second VPN?

Fortunately, it is possible to simply connect to two VPNs simultaneously. All you need to do is simply to configure both VPNs in your network settings.
Fig. 1:Simultaneously connect to multiple VPNs
I can then firstly connect to the VPN "T", and when this connection is establish I can use it to connect to the second VPN "F". Figure 1 shows the VPN menu in the system menu bar (OS 10.6, with elder versions, things look a bit different, as explained here).

Well, this is the easy part. The harder part is to tell the applications which VPN to use. This problem is (almost) the same problem as using different network interfaces (e.g., use the Ethernet connection for some tasks, and a WLan connection for others), as the VPNs create virtual network interfaces. So, it's time to start the console... ifconfig prints out the available network interfaces. E.g., my first VPN "T" has created a new interface called ppp0:

ppp0: flags=8051 mtu 1444
 inet 111.123.123.144 --> 111.123.123.166 netmask 0xffff0000

It is not that important to know exactly what you see here. The only important thing is the number 111.123.123.144 which is the IP-address assigned to my machine for VPN "T".

After connecting to the second VPN "F", another interface is available, representing the second VPN:

utun0: flags=8051 mtu 1280
 inet 222.123.123.155 --> 222.123.123.177 netmask 0xffffff00

Within this second VPN, I've got the IP 222.123.123.155.

So, I have two interfaces and two IP addresses, one for each VPN. This information can be used to tell applications to connect via one specific VPN.

In my case, I want to make an SSH connection to the server "S", which is only possible from within "FNet", that is, using the second VPN "F". Fortunately, I can tell ssh to use a certain IP address on my local machine. Let's assume 222.123.144.144 to be the IP address of the server S. This is how to connect to "S" via the second VPN "F":

>ssh -b 222.123.123.155 -l theUser 222.123.144.144

in which "theUser" the user login for "S". 222.123.123.155 is the IP of my machine within FNet (as F virtually places my machine in FNet). Note that you have to use the IP address rather then the name of the server (maybe some geek can tell me how to "update" the DNS stuff accordingly).

Other applications cannot be configured that easily, in these cases you have to add routing entries to your route table. E.g., instead of using the "-b" option of ssh, I could have added a new route (I found that tip here). To add a route, I need to be a super user, so we have to use sudo:

>sudo add route 222.123.144.144 222.123.123.155

Now, I can directly connect to S without the "-b" option:

>ssh -l theUser 222.123.144.144

Don't forget to delete the route when no longer needed:

>sudo delete route 222.123.144.144 222.123.123.155