Creating a Mac to Mac VPN using SSH and the tun device driver

Problem

There are many VPN solutions out there, but this one is mine.

I wanted a VPN solution that I could use to enable my MacBook laptop when out and about to connect back to my MacMini at home. In addition to the usual email and file access, I wanted access to UDP, which doesn’t work well with conventional SSH port forwarding.

There are other solutions to this Mac to Mac VPN problem: IPSEC, PPTP and hamachi some work well(-ish) on Mac OS X 10.4. If you’re reading this page I’m guessing you, like me, have reasons for not wanting to use these solutions.

Solution

I already had SSH port forwarding working, so I wanted to work on developing that as a solution rather than trying to reconfigure firewalls all over the place.

Preparation

Now is a good time to make sure your backups are really backing up and your restores really work.

If you don’t know how to do SSH port forwarding, may I suggest you read up elsewhere and get that working first. It might solve your issues and mean you don’t need a VPN at all and, if you can’t get ssh port forwarding to work, you won’t get this to work either.

tools required

To follow this tutorial you need two Macs, home and laptop, running Mac OS X 10.4.10 or later; SSH installed and the daemon listening on the home machine; the tun/tap drivers installed; Terminal.

tun/tap drivers

Don’t be fooled by the presence of a tun man page! Mac OS X doesn’t actually have a tun interface you can use.

The easiest way to install tun/tap drivers is to download tunnelblick

You need to do this on the laptop and the home Mac.

Assuming you have tunnelblick application on your Desktop, try the following in the terminal:

sudo cp -rp Desktop/Tunnelblick.app/Contents/Resources/*kext /System/Library/Extensions/
cd /System/Library/Extensions
sudo chown -R root:wheel tun.kext
sudo chmod -R go-w tun.kext
sudo chown -R root:wheel tap.kext
sudo chmod -R go-w tap.kext 
sudo kextload /System/Library/Extensions/tun.kext

The SSH connection

You need to make sure your sshd_config on the home machine (not the laptop) permits tunnelling. The sshd_config lives in /private/etc and should say

PermitRootLogin yes
PermitTunnel yes

Then, from the laptop

sudo ssh -w 0:0 root@home. while true \; do echo -n . \&\& sleep 60 \; done

Your terminal window on the laptop should slowly start to fill with meaningless dots. Now open up another terminal window on you laptop. You should see a tun network interface where you didn’t have one before:

 ifconfig tun0
tun0: flags=8851<UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        open (pid 28659)

You can also fire up another ssh connection to your home and check there is a tun interface there too.

If you can get that working, you can try and use these shiny new tun interfaces for IP VPN magic.

The VPN connection

sudo ifconfig tun0 172.16.0.1 172.16.0.2
ssh root@home. ifconfig tun0 172.16.0.2 172.16.0.1 \&\& sysctl -w net.inet.ip.forwarding=1

This creates an IP address 172.16.0.1 on your laptop, connected to 172.16.0.2 on your home machine.

Adding a route on your laptop to use that interface is easy:

sudo route add -net 172.16.0 -interface tun0

Also, you probably want to add the whole network that you have at home onto the laptop tunnel

sudo route add -net 172.16.0 -interface tun0

NAT

The above steps work fine for a host-to-host connection. If you want to use the connection to ‘break out’ of the network you are on, and use the home network instead, you’ll need to get some NAT working from the tun interface on the home Mac. To do this, I use waterroof to manage NAT. INCOMPLETE SECTION

 sudo launchctl start net.waterroof.rules; natd -interface en0 -l -s -m
 ipfw add 00002 allow ip from any to any via tun0 
 ipfw add 00003 divert 8668 ip from any to 192.168.1.0/24 via en0
 ipfw add 00004 allow ip from any to 172.16.0.1

Rules do the following:

  1. Configure forwarding, and NAT
  2. Allow all traffic if it comes through the tunnel, which may be a little over kind.
  3. Put everything t or from the “internal home network (assuming that’s 192.168.1.0/24)” through NAT
  4. Make sure everything can get back to your laptop after NAT translation at rule 3 (again this might be over kind, but it shouldn’t get NAT’d if you didn’t start the conversation .. so maybe not)
 
technical/unix/mac_os_x/vpn_with_ssh.txt · Last modified: 2007/09/06 19:46 by daleroberts