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:
me@home:~$ ssh -f -L [CLIENT_NAME:]NEW_CLIENT_PORT:TERMINAL_NAME:TERMINAL_PORT \ TUNNEL_USER@TUNNEL_NAME [-p TUNNEL_PORT] sleep 10
NEW_CLIENT_PORT
is a local port with value over 1023, say 2000.
Brackets ([]
) indicate optional parameters:
CLIENT_NAME
if it is 'localhost'-p TUNNEL_PORT
if you use SSH (-p 22
) unless it is on a non-standard portNotes:
CLIENT_NAME
could refer to the hostname or the IP address.-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
.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 TERMINAL_USER@CLIENT_NAME -p NEW_CLIENT_PORT
Example:
CLIENT_NAME = localhost NEW_CLIENT_PORT = 2000 TERMINAL_NAME = terminal.server.ten TERMINAL_PORT = 22 TUNNEL_USER = tunneler TUNNEL_NAME = public.server.ten TUNNEL_PORT = 22 TERMINAL_USER = terminator me@home:~$ ssh -f -L 2000:terminal.server.ten:22 [email protected] sleep 10 me@home:~$ ssh terminator@localhost -p 2000
Reference:
SSH man page