MacDevCenter    
 Published on MacDevCenter (http://www.macdevcenter.com/)
 See this if you're having trouble printing code examples


VPN on Mac OS X

by Jason Deraleau
12/20/2002

Virtual Private Networking is a valuable tool for system and network administrators. It's an excellent way to reduce the costs of multiple site and remote access networks, while simultaneously increasing the overall security of your network.

In a moment, I'll introduce some of the VPN tools that come with Mac OS X, but first, I'd like to help you become familiar with a few basic concepts and some terminology.

The Virtual Private Network

VPN technologies are alternatives to a few more expensive WAN technologies. The most often replaced is remote access. Many corporations have configured Remote Access Servers, procured a bunch of phone lines, and given their remote users dialup accounts to connect to the corporate network. While this is a very feasible solution, it can also be cost-prohibitive. Telephone lines, modem racks, and new server equipment all cost money and time to prepare and maintain. You can put VPN technology to use here by configuring a PPTP server and getting dialup accounts from an Internet Service Provider (ISP). You no longer have to maintain your own dial-in servers and phone lines; instead, the users connect to the ISP and then use a PPTP dialer to connect to your corporate server. Connections are secure, and you're using the Internet to branch out your network.

Another common WAN technology that is replaced by VPN is the point-to-point circuit. As a corporation grows, it will often branch out into multiple offices and purchase point-to-point T circuits to link them together. This can become expensive as you maintain multiple lines to branch offices, their routing equipment, and personnel to keep everything running smoothly. Instead, you can have each office configure a server or router to use PPTP to connect together across the Internet. Your network is expanded across the Internet securely.

Two of the most commonly-used VPN protocols are Point to Point Tunneling Protocol (PPTP) and the Layer 2 Tunneling Protocol (L2TP). PPTP is very popular on the Microsoft platforms and pretty much every platform has a client to access a PPTP server. L2TP is popular with routing equipment, especially Cisco's. While not as common on the Internet overall, L2TP is still the most common solution for point-to-point VPN setups. Apple is using PPTP in the VPN client for Mac OS X and the VPN server for Mac OS X Server.

Mac OS X's VPN Client

Beginning with Mac OS X 10.2 ("Jaguar"), Apple has included a PPTP client. It is built into the Internet Connect tool and includes the ability to store passwords in the keychain. To create a PPTP connection, open Internet Connect in the /Applications folder. In Internet Connect, select New VPN Connection Window from the File menu.

Screen shot.
Mac OS X's PPTP client.

Enter the server address for your PPTP server and the appropriate credentials; you should be able to get these from your server's administrator. Once you have everything filled out, click the Connect button. Watch the Status field to be sure you are establishing a connection. After the connection is up, you can check in the Network pane of System Preferences for a PPTP device. This device will show you your VPN connection's network address information, much like any other network adapter.

Tunneling PPP over SSH

While PPTP is a very common solution for creating a VPN on the Internet, server solutions for Mac OS X are limited at this point. There is a PPTP VPN daemon available, shipping with Mac OS X Server, but unfortunately it is not listed as an open source component on Apple's site. This greatly hampers the ability to get two Mac OS X clients together in a VPN. However, there is another solution: using PPP and SSH together to form a VPN link.

This method works by creating a PPP link between two systems over an SSH connection. The master machine initiates an SSH connection to the slave. Once it has authenticated the connection, the slave machine launches pppd, with output going to the inbound SSH session. On the master machine, pppd is launched to respond to the slave's pppd. The two daemons sync up and begin passing packets, which are in turn encrypted by SSH. While it isn't terribly optimized (read "fast"), it does work, and is a great placeholder while we're waiting for more PPTP daemons to be ported to Mac OS X.

The slave machine is the machine that is connected to the main network. This is the same box that would run the actual VPN server, but in this situation it is the slave of the PPP link. This is the easiest method, because it allows the remote machine to build and tear down the VPN connection. The slave machine in my examples will be "utopia.lifehertz.com."

The first thing we'll need to do is create an account on the slave machine for our master machine to log into. This should be a brand-new account and will not be used beyond the VPN. We're going to modify some settings on the account that may break a normal user.

To create the user account, open the Accounts tab of the System Preferences pane. Click New User, and enter "VPN User" for the Name and "vpn" for the Short Name. Set an easy-to-remember password for now; we're going to disable it later. Once you've filled out these fields, click the OK button.

Screen shot.
Creating the VPN user.

The next step is to setup the vpn account with the ability to launch the PPP daemon. To do this, we're going to edit the sudoers file. Open up the Terminal and issue the command sudo pico /etc/sudoers to open the file in pico. You'll want to add the VPN Cmnd_Alias and VPN user privileges to make your sudoers file look similar to the one below:

# Cmnd alias specification
Cmnd_Alias VPN=/usr/sbin/pppd, /sbin/route

# Defaults specification

# User privilege specification
root    ALL=(ALL) ALL
%admin  ALL=(ALL) ALL
vpn     ALL=NOPASSWD: VPN

The master machine is the machine you are using remotely. This machine will initialize the SSH connection and then respond to the PPP daemon launching on the slave. In my example, the master machine is "nomad.lifehertz.com." In order to easily log in to the slave machine to launch pppd, we'll be using SSH key authentication. To do this, we first need to generate the key, then copy the public portion of the key to the vpn account's home directory on the slave machine. You don't need to use a password on the key. The commands below should help you do this:

$ sudo ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /var/root/.ssh/id_rsa.
Your public key has been saved in /var/root/.ssh/id_rsa.pub.
The key fingerprint is:
a3:46:24:8b:b7:a9:d6:91:d7:25:9a:e2:82:ce:16:82 musouka@nomad
$ sudo scp /var/root/.ssh/id_rsa.pub vpn@utopia.lifehertz.com:~
The authenticity of host 'utopia (24.218.227.101)' can't be established.
RSA key fingerprint is 00:41:24:66:bf:d4:38:d4:cb:2a:e2:75:93:74:d2:9e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'utopia,24.218.227.101' (RSA) to the list of known hosts.
vpn@utopia's password:
id_rsa.pub 100% |**********************************************************************| 123

Once you've copied the public key to the slave system, you'll want to connect to it and finish setting up the vpn account. First ssh into the slave machine and then attempt to connect back to the master machine from the slave to exchange host keys. You'll want to confirm adding the master to your slave's known hosts and then just Ctrl-C to cancel the actual connection. Verify that there is a file in the vpn account's ~/.ssh folder called known_hosts. Next, move the generated public key to the a file called authorized_keys in the ~/.ssh folder. Finally, configure the PPP daemon to launch passively upon login. The commands below should get you there:

$ ssh vpn@utopia.lifehertz.com
vpn@utopia's password:
$ ssh nomad
The authenticity of host 'nomad (209.94.128.164)' can't be established.
RSA key fingerprint is 71:7d:6d:03:87:86:28:94:ee:16:2f:e2:01:dd:e9:38.
Are you sure you want to continue connecting (yes/no)? yes
vpn@nomad's password: ^C
$ mv ~/utopia.pub ~/.ssh/authorized_keys
$ echo "sudo /usr/sbin/pppd passive; logout" > ~/.login
$ logout

To verify that your slave machine is set up properly, from the master machine, attempt the command sudo ssh vpn@utopia.lifehertz.com. Your master machine should connect to the slave machine, be authenticated via the SSH key, and then begin to see the garbled output of the PPP daemon. If this is all working properly, then your slave machine is ready to go.

To finish up configuring the master machine, you'll need to make use of a little tool called pty-redir. This program will execute a passed command on a separate TTY. As you saw above, when you SSH to the slave machine, the PPP daemon will launch and start filling your screen with garbage. In order to get the two machines to connect, you need to have the PPP daemon on the master machine launch to respond to the slave's PPP daemon. The problem is that you can't launch pppd very well if you're busy looking at the slave machine's output. pty-redir helps you get around this quite easily. To download and install pty-redir, follow the code below:

$ curl -O http://www.macdevcenter.com/mac/2002/12/20/examples/pty-redir-0.1.tar.gz
$ tar zxvf pty-redir-0.1.tar.gz
$ cd pty-redir-0.1
$ make
$ sudo mkdir /usr/local/bin
$ sudo cp pty-redir /usr/local/bin

These commands will put the pty-redir binary in your /usr/local/bin directory. To test it out, execute the command sudo /usr/local/bin/pty-redir /usr/bin/ssh vpn@utopia.lifehertz.com. You should just see a result along the lines of /dev/ttyp4. This output tells you which TTY was allocated for your command and to where its output is going. In this case, the slave machine's PPP daemon is sending its connection information to the redirected TTY. All you need to do to finish the link is launch pppd on the master machine and have it use the redirected port. You do this with the command sudo /usr/sbin/pppd /dev/ttyp4 local noauth proxyarp persist 192.168.10.1:192.168.10.2. This will tell the master machine's PPP daemon to use the redirected TTY and use the IP address of 192.168.10.1 for its end of the PPP link. The slave machine's IP would be 192.168.10.2. If everything is working up to this point, you should be able to ping 192.168.10.2 and get a response from the slave machine. This means your connection is up and running!

Learning Unix for Mac OS X

Related Reading

Learning Unix for Mac OS X
By Dave Taylor, Brian Jepson

Now that you have the tunnel up, you can use a static route to point to the slave machine's network. You will then be able to pass traffic to other hosts on the slave's network through the encrypted PPP tunnel securely. If the network you are trying to access is 192.168.3.0/24, you would use the command sudo /sbin/route add -net 192.168.3.0/24 192.168.10.2. Make sure that the gateway for the route is the slave machine's end of the PPP link. Depending on the slave machine's routing setup, you might be able to have the master machine pass all Internet traffic through the slave machine. This is a good way to help secure traffic if you're using a wireless access point in a public place. You can bring up the VPN connection and then change your default route with the command sudo /sbin/route add -net 0.0.0.0 192.168.10.2. This will route all of your Internet traffic through the VPN link, securing your wireless traffic. The main thing to consider with changing the gateway is that you are going to take a hit in performance. You must take into account that your traffic will be encrypted, passed through the tunnel, decrypted, passed out of the slave machine, and then out onto the Internet. This can definitely slow things down.

So you've been connected into your slave machine for a while, and have decided that it's time to disconnect. The process is pretty simple. Use ps ax | grep pppd to search for the PPP daemon's process ID. Then use the sudo kill command to kill the daemon. The master machine's PPP daemon will bring down the link. This allows the slave machine's PPP daemon to quit. Upon quitting, the slave machine will log out the vpn user. At this point, the PPP connection will have stopped, both daemons will have quit, and your SSH connection should be down as well.

For finishing touches, I've included a script here that can help build and tear down the VPN connection with just a few keystrokes. It's also a good idea to disable the vpn user's password, making it less susceptible to break-in attempts. To do this, just issue the command sudo niutil -createprop . /users/vpn passwd *.

Jason Deraleau works as a systems administrator by day, IT consultant and technical writer by night, and is the coauthor of the upcoming Running Mac OS X Tiger.


Return to the Mac DevCenter.


Copyright © 2009 O'Reilly Media, Inc.