I’ve been experimenting with using SSH as a VPN. That is to say not just tunnelling a single port but forwarding all traffic through the remote host like a router.

I’ve pulled together instructions from here and here and have this:

  1. Enable root SSH with keys and allow tunnelling on the remote machine in /etc/ssh/sshd_config:
PermitTunnel yes
PermitRootLogin without-password
  1. Generate root SSH keys on the local machine and copy the public one to the remote machine:
ssh-keygen -t rsa
scp id_rsa.pub remote-ip:/root/.ssh/authorized_keys
  1. SSH as root (or using sudo) from local to remote to setup the VPN, this will actually give you a login as I found that if you don’t make that a login session (i.e. ssh -NTFw 0:0 remote-ip) then you can’t take down the tun0 device when you’re finished, which makes for all sorts of problems when you try to bring it up again later:
sudo ssh -w0:0 remote-ip
  1. Whilst in the root SSH session on the remote machine, you can configure the tun0 device (on a /30 as its point-to-point, using a private IP range), enable IP forwarding and NAT. Obviously you can’t use the same subnet for the VPN as your normal routing, so assume here eth0 is
ifconfig tun0 netmask up
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
  1. Back on the local machine (as root) setup the static routes you require to go down the VPN, in this case I’m connecting to the entire 10.93.x.x private network the other side of the tunnel. I found that the usual “route add….” syntax didn’t work, so moved to the new “ip” system as described here:
ifconfig tun0 netmask up
ip route add dev tun0

That’s it, now on the local machine any traffic you point at 10.93.x.x goes down the SSH tunnel and is forwarded onto the machines the other side, this is much better than a regular SSH tunnel which just connects you from local port A to remote port B, this allows any traffic from local A via remote B to target C.

If you wanted to forward all traffic via the remote machine, you’d just change step #5 to remove the default gateway and expand the scope of the VPN:

ifconfig tun0 netmask up
route del default gw
ip route add dev tun0

A bit easier and with less overhead than setting up OpenVPN.