Introduction

Since version 4.3 of OpenSSH, the option to create IP tunnels has been added.

First, you need to check the OpenSSH version on both the server and client.

  ssh -v
  

You need root privileges on both machines. There are operations to perform, both at the configuration and network levels.

Configuration

Server

OpenBSD

The first thing to do is to tell OpenSSH to authorize tunnels by adding this directive:

  # Enable layer-3 tunneling. Change the value to 'ethernet' for layer-2 tunneling
PermitTunnel point-to-point
  

We need to ensure that forwarding is activated:

  sysctl net.inet.ip.forwarding=1
  

And will be activated at reboot:

  net.inet.ip.forwarding=1
  

Let’s create a tun interface:

  ifconfig tun0 create
ifconfig tun0 10.0.0.1 10.0.0.2 netmask 0xfffffffc
  

And again, make the configuration permanent:

  10.0.0.1 10.0.0.2 netmask 0xfffffffc
  

Now we can restart SSH:

  pkill -HUP sshd ; /usr/sbin/sshd
  

You also need to disable privilege separation, or adjust permissions on /dev/tun. For simplicity, I’ve added:

  UsePrivilegeSeparation no
  

Another solution is to grant read-write permissions to a specific group on /dev/tun, which is much simpler and safer.

  chmod :mygroup /dev/tun
  

And of course, be in that group.

You then need to load the tun module:

  modprobe tun
  

And add it to /etc/modprobe.preload for loading at next boot:

  echo tun >> /etc/modprobe.preload
  

Client

On the client side, we also need to add this directive but in the /etc/ssh/ssh_config file:

  # Enable layer-3 tunneling. Change the value to 'ethernet' for layer-2 tunneling
PermitTunnel point-to-point
  

Edit the /etc/network/interfaces file and add this interface:

        iface tun0 inet static
      pre-up ssh -S /var/run/ssh-myvpn-tunnel-control -M -f -w 0:0 5.6.7.8 true
      pre-up sleep 5
      address 10.254.254.2
      pointopoint 10.254.254.1
      netmask 255.255.255.252
      up route add -net 10.99.99.0 netmask 255.255.255.0 gw 10.254.254.1 tun0
      post-down ssh -S /var/run/ssh-myvpn-tunnel-control -O exit 5.6.7.8
  

You only need permissions on /dev/tun, so either run as root or have write permission on /dev/tun, as mentioned above, then do (where client is the server):

  ssh -w any:any client
  

You can look at the -f and -N options to avoid launching a shell on the remote machine. And of course, the usual options still work (key, tunnel, master/slave).

Then, as root, you can change the IP of the new tun0 interface on the server:

  ifconfig tun0 10.0.0.1
  

On FreeBSD:

  ifconfig tun100 inet 10.0.0.1 10.0.0.2 netmask 255.255.255.255
  

And do the same on the client:

  ifconfig tun0 10.0.0.2
  

or

  ifconfig tun100 inet 10.0.0.2 10.0.0.1 netmask 255.255.255.255
  

Finally, you can now test the ping from the client:

  ping 10.0.0.1
  

The rest is normal interface configuration. You can add routes, a firewall, anything.

However, you should know that TCP connections over TCP (as is the case with SSH) are not recommended, due to the nature of TCP.

FAQ

Connection closed by …

This is generally due to the server struggling. Check that it has the correct DNS settings and that in the configuration (/etc/ssh/sshd_config) the LoginGraceTime value is high enough.

Cannot fork into background without a command to execute

You may encounter this error message:

  Cannot fork into background without a command to execute
Failed to bring up tun1.
  

To resolve this issue, add the -N option to the SSH command.

Resources

Last updated 14 May 2010, 22:46 CEST. history