5 Tunneling

One really interesting feature of SSH is the ability to “tunnel”. This feature is best explained with an example.

We’ll consider three hosts. The first host is officeboy, a computer that I use in the office. There is where I am physically located. The second host is homer, which is my home computer, connected to the internet via a residential gateway. My residential gateway is set up to forward port 22 traffic to homer. At home, I have a second computer named hidden. As the name implies, my residential gateway does not forward any ports to hidden.

Furthermore, I use hosts.allow and hosts.deny so that hidden only accepts telnet connections in the local area network 192.168.1.0/255.255.255.0. Now, I would like to use telnet to do something with hidden from my office. How can I set this up?

First off, telnetd must be configured on hidden. However, I don’t need to set up sshd on hidden.

Secondly, sshd must be configured on homer to allow port forwarding.

Thirdly, officeboy needs to have both ssh and telnet clients installed.

What happens now is the magical part.

First, on a command line, officeboy executes the following comamnd:

ssh -L2323:hidden:23 username@homer

I need to use username to authenticate at homer. However, this is no normal ssh connection. The extra -L option forwards port 2323 on officeboy to port 23 of hidden using homer as a relay. Note that the -L option specifies that the connection must originate from officeboy on port 2323.

Next, on another command line of officeboy, I execute the following command:

telnet localhost 2323

Normally, this opens a connection to port 2323 of the local host officeboy, which usually means it is not answered. However, the first ssh command sets up the system to “hijack” port 2323. Any attempt to connect to port 2323 is automatically received by the ssh command. As such any connection to port 2323 of the localhost is relayed to the SSH connection to homer.

Once port 2323 traffic reaches homer, the sshd server relays the traffic to hidden at port 23. Consequently, from the perspective of hidden, it is receiving traffic at port 23 from homer, a machine on the local area network. As a result, hidden gladly receives the connection, not knowing (really) that it is actually traffic originated from officeboy.

Once a connection is established, homer as a the relay of traffic back and forth between officeboy and hidden.

In this example, we only use port 23 as an example. It can be any port. Furthermore, a single SSH connection can tunnel an arbitrary number of ports.

There is a complementary option to -L to receive connections relayed by an SSH server. The -R option sets up the sshd server to proxy traffic originated from hidden to homer so that the traffic reaches officeboy in the end. This option is less commonly used (compared to -L) because someone or something must be initiating connections on the remote side for -R to be useful.