Build a “VPN over SSH” tunnel

After being bored one day, I decided to see if it was possible to build a network tunnel over a SSH tunnel. This outlines the 3 steps I had to take to get it all to work.


Step 1

Make sure you have kernel-based tunneling enabled

$ cat /boot/config-$(uname -r) | grep CONFIG_TUN

If it returns:

CONFIG_TUN=y

Or:

CONFIG_TUN=m

Then it will work, otherwise you need to install another kernel version that has it enabled by default.

Step2

On the server edit /etc/ssh/sshd_config  and make sure that you have:

PermitTunnel yes

Then on the client side edit  /etc/ssh/ssh_config and add the following lines:

Host <host>

Tunnel [yes|point-to-point|ethernet]

where <host> is the address of the host you are connecting too and the three options you can specify means:

  • yes – Defaults to point-to-point mode
  • point-to-point builds an IP (OSI Layer 3) tunnel
  • ethernet builds an ethernet (OSI Layer 2) tunnel

On the server and client side edit /etc/network/interfaces to add the following lines:

auto tunX

iface tunX inet static

address X.X.X.X

netmask 255.255.255.252

Where tunX is the next avalable tun interface and X.X.X.X and X.X.X.X+1 as your chosen IP’s

Step3

Now all that is left is to make the tunnel:

$ ssh -NTCf -w X:Y <host>

Where  X is the tun interface on the client and Y the tun interface on the server.

Explanation of the options above from the ssh man page:

-N      Do not execute a remote command.  This is useful for just forwarding ports (protocol version 2 only).

-T      Disable pseudo-tty allocation.

-C      Requests compression of all data (including stdin, stdout, stderr, and data for forwarded X11 and TCP connections).  The compression algorithm is the same used by gzip(1), and the “level” can be controlled by the CompressionLevel option for protocol version 1.  Compression is desirable on modem lines and other slow connections, but will only slow down things on fast networks.  The default value can be set on a host-by-host basis in the configuration files; see the Compression option.

-f      Requests ssh to go to background just before command execution.  This is useful if ssh is going to ask for passwords or passphrases, but the user wants it in the background.  This implies -n.  The recommended way to start X11 programs at a remote site is with something like ssh -f host xterm

If the ExitOnForwardFailure configuration option is set to “yes”, then a client started with -f will wait for all remote port forwards to be successfully established before placing itself in the background.

-w local_tun[:remote_tun]      Requests tunnel device forwarding with the specified tun(4) devices  between the client (local_tun) and the server (remote_tun).

The devices may be specified by numerical ID or the keyword “any”, which uses the next available tunnel device.  If remote_tun is not specified, it defaults to “any”.  See also the Tunnel  and TunnelDevice directives in ssh_config(5).  If the Tunnel directive is unset, it is set to the default tunnel mode,  which is “point-to-point”.

Thats all there is to it!

Leave a Reply