VPN with SSH

  As of version 4.3, OpenSSH can use the tun/tap device to encrypt a tunnel. This is very
  similar to other TLS based VPN solutions like OpenVPN. One advantage with SSH is that there
  is no need to install and configure additional software. Additionally the tunnel uses the
  SSH authentication like pre shared keys. The drawback is that the encapsulation is done
  over TCP which might result in poor performance on a slow link. Also the tunnel is relying
  on a single (fragile) TCP connection. This technique is very useful for a quick IP based
  VPN setup. There is no limitation as with the single TCP port forward, all layer 3/4
  protocols like ICMP, TCP/UDP, etc. are forwarded over the VPN. In any case, the following
  options are needed in the sshd_conf file:
PermitRootLogin yes
PermitTunnel yes

Single P2P connection

  Here we are connecting two hosts, hclient and hserver with a peer to peer tunnel. The
  connection is started from hclient to hserver and is done as root. The tunnel end points
  are 10.0.1.1 (server) and 10.0.1.2 (client) and we create a device tun5 (this could also be
  an other number). The procedure is very simple:
    * Connect with SSH using the tunnel option -w
    * Configure the IP addresses of the tunnel. Once on the server and once on the client.

Connect to the server

  Connection started on the client and commands are executed on the server.

Server is on Linux

cli># ssh -w5:5 root@hserver
srv># ifconfig tun5 10.0.1.1 netmask 255.255.255.252   # Executed on the server shell

Server is on FreeBSD

cli># ssh -w5:5 root@hserver
srv># ifconfig tun5 10.0.1.1 10.0.1.2                  # Executed on the server shell

Configure the client

  Commands executed on the client:
cli># ifconfig tun5 10.0.1.2 netmask 255.255.255.252   # Client is on Linux
cli># ifconfig tun5 10.0.1.2 10.0.1.1                  # Client is on FreeBSD

  The two hosts are now connected and can transparently communicate with any layer 3/4
  protocol using the tunnel IP addresses.

Connect two networks

  In addition to the p2p setup above, it is more useful to connect two private networks with
  an SSH VPN using two gates. Suppose for the example, netA is 192.168.51.0/24 and netB
  192.168.16.0/24. The procedure is similar as above, we only need to add the routing. NAT
  must be activated on the private interface only if the gates are not the same as the
  default gateway of their network.
  192.168.51.0/24 (netA)|gateA <-> gateB|192.168.16.0/24 (netB)
    * Connect with SSH using the tunnel option -w.
    * Configure the IP addresses of the tunnel. Once on the server and once on the client.
    * Add the routing for the two networks.
    * If necessary, activate NAT on the private interface of the gate.

  The setup is started from gateA in netA.

Connect from gateA to gateB

  Connection is started from gateA and commands are executed on gateB.

gateB is on Linux

gateA># ssh -w5:5 root@gateB
gateB># ifconfig tun5 10.0.1.1 netmask 255.255.255.252 # Executed on the gateB shell
gateB># route add -net 192.168.51.0 netmask 255.255.255.0 dev tun5
gateB># echo 1 > /proc/sys/net/ipv4/ip_forward        # Only needed if not default gw
gateB># iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

gateB is on FreeBSD

gateA># ssh -w5:5 root@gateB                          # Creates the tun5 devices
gateB># ifconfig tun5 10.0.1.1 10.0.1.2               # Executed on the gateB shell
gateB># route add 192.168.51.0/24 10.0.1.2
gateB># sysctl net.inet.ip.forwarding=1               # Only needed if not default gw
gateB># natd -s -m -u -dynamic -n fxp0                # see NAT
gateA># sysctl net.inet.ip.fw.enable=1

Configure gateA

  Commands executed on gateA:

gateA is on Linux

gateA># ifconfig tun5 10.0.1.2 netmask 255.255.255.252
gateA># route add -net 192.168.16.0 netmask 255.255.255.0 dev tun5
gateA># echo 1 > /proc/sys/net/ipv4/ip_forward
gateA># iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

gateA is on FreeBSD

gateA># ifconfig tun5 10.0.1.2 10.0.1.1
gateA># route add 192.168.16.0/24 10.0.1.2
gateA># sysctl net.inet.ip.forwarding=1
gateA># natd -s -m -u -dynamic -n fxp0                # see NAT
gateA># sysctl net.inet.ip.fw.enable=1

  The two private networks are now transparently connected via the SSH VPN. The IP forward
  and NAT settings are only necessary if the gates are not the default gateways. In this case
  the clients would not know where to forward the response, and nat must be activated.