SSH Tunnelling or TCP Forwarding

Posted 3 years, 2 months ago | Originally written on 17 May 2014

This has to rank as the most confusing topic in using the Linux command line. It is even confusing using Fugu because there are three user, host and ports that can be used leading to a lot of possibilities to get it wrong. To the best of my understanding, SSH tunnelling is TCP forwarding - at least as far as the SSH man page goes.

The canonical problem that one would want to solve using tunnelling is to burrow through an intermediate public-facing machine to get to a private machine that shares an network with the public-facing machine. I'll label the three machines CLIENT, TUNNEL and TERMINAL. The goal is to get to TERMINAL from CLIENT through TUNNEL.

The syntax is as follows:

[email protected]_NAME [-p TUNNEL_PORT] sleep 10

NEW_CLIENT_PORT is a local port with value over 1023, say 2000.

Brackets ([]) indicate optional parameters:

  • You can omit CLIENT_NAME if it is 'localhost'
  • You can omit -p TUNNEL_PORT if you use SSH (-p 22) unless it is on a non-standard port


  • CLIENT_NAME could refer to the hostname or the IP address.
  • The -f argument indicates that this command should be run in the background. You want SSH to return the console so that you can connect to TERMINAL.
  • The sleep 10 command will be run in TUNNEL upon successful connection to TUNNEL. In this case, you have 10 seconds to try to connect to TERMINAL. If 10 seconds elapses before a successful connection then the tunnel will be closed.

Once you are connected to TUNNEL and get back the command prompt type the following:

me@home:~$ ssh [email protected]_NAME -p NEW_CLIENT_PORT


CLIENT_NAME = localhost
TERMINAL_NAME = terminal.server.ten
TUNNEL_USER = tunneler
TUNNEL_NAME = public.server.ten
TERMINAL_USER = terminator
[email protected]:~$ ssh -f -L 2000:terminal.server.ten:22 [email protected] sleep 10
[email protected]:~$ ssh [email protected] -p 2000


SSH man page