How to use SSH port forwarding to protect insecure connections

Port forwarding is using an SSH connection to forward another network application connection, as illustrated in the following diagram:

SSH port forwarding

Instead of conncting directly from the application client to the application server, the application client first connects to an SSH session running on the client side, which encrypts the data and forwards to the server's SSH server daemon. The SSH server daemon decrypts the data and forwards them to the application server. Thus, we can use SSH connection to protect insecure connections such as telnet.

1. Local forwarding

We use telnet as an example to set up a local port forwarding. Suppose the client's IP address is 10.1.43.50, and the server's IP address is 10.1.43.52. Without port forwarding, we can issue the following command to initiate a telnet connection directly from the client to server:

$ telnet 10.1.43.52

And we get the output like this:

Trying 10.1.43.52...

Connected to 10.1.43.52.

Escape character is '^]'.

Fedora release 8 (Werewolf)

Kernel 2.6.24.3-50.fc8 on an i686

login:

We know the telnet session is not secure because all the data are transmitted in clear text. So we build an SSH port forwarding session like this:

$ ssh -L3000:localhost:23 zhouhon1@10.1.43.52

And we get the output like this:

zhouhon1@10.1.43.52's password:

Last login: Wed Apr 16 09:39:27 2008 from localhost

We initiated an SSH session just like a regular session, but we also enabled port forwarding. Now the SSH session is also listening on port 3000 on the client and is ready to forward any packets it receives to port 23 (telnet) on the server (10.1.43.52).

From now on, we can initate the telnet connection to local port 3000, which is forwarded to port 23 on the server, which looks like a regular telnet session, except that the data are protected by SSH encryption.

$ telnet localhost 3000

Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

Fedora release 8 (Werewolf)

Kernel 2.6.24.3-50.fc8 on an i686

login:

We can use special escape sequence ~ # to show all forwarded connections in the SSH session:

$ ~#

The following connections are open:

#2 client-session (t4 r0 i0/0 o0/0 fd 7/8 cfd -1)

#3 direct-tcpip: listening port 3000 for localhost port 23, connect from 127.0.0.1 port 49863 (t4 r1 i0/0 o0/0 fd 10/10 cfd -1)

2. Remote forwarding

Local forwarding is initiated from the client. It is also possible to initiate port forwarding from the server, which is called remote forwarding.

Suppose you already log into the server (with SSH), now you can issue the command on the server for remote forwarding:

$ ssh -R3001:localhost:23 zhouhon1@10.1.43.50

And we will get the output like this:

zhouhon1@10.1.43.50's password:

Last login: Wed Apr 16 14:29:47 2008 from mc106eg6q7m71f.srunet.sruad.edu

Now, on the client, you can issue the telnet command to connect to the localhost side to be forwarded to the server:

$ telnet localhost 3001

Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

Fedora release 8 (Werewolf)

Kernel 2.6.24.3-50.fc8 on an i686

login: