What is port forwarding?

It is the process by which SSH can be used to tunnel traffic from the client to the host and vice versa.

Any TCP/IP traffic can be wrapped inside SSH and, thus, encrypted.

Simple example

Suppose that you have a web server running on one of your host. The server currently supports HTTP only. But you need to browse some URLs on this server, perhaps supplying confidential information. Fortunately, our web server does have OpenSSH installed. So, one possible solution for this is to wrap your HTTP traffic inside an SSH tunnel. The following command would do the trick:

ssh -L 8080:localhost:80 remotehost

Now, to access the web server, you'll use the tunnel you just created. Open the web browser and navigate to http://localhost:8080. Now, although the protocol you are using is HTTP not HTTPS, SSH will intercept this traffic on your localhost and wrap it inside an encrypted tunnel.

Also notice that the traffic originating from your own machine is not going to be regarded as web traffic, as far as the firewall is concerned. The logs will show SSH traffic travelling to some remote host.

Types of SSH tunnels

There are three types of SSH tunnels aka port forwarding: local, remote, and dynamic. In this post, we are interested in the local type.

Local

The example that we've just set uses local port forwarding. It basically means: create a local port (8080) on my machine (localhost) and forward any traffic coming to this port to port 80 on the remote machine (remote host).

Use cases

You can use local port forwarding when the traffic that is supposed to go from or to the remote host will be originating or arriving at your local machine, or another machine that you choose.

For example:

  • Connecting to a remote web server that does not support HTTPS
  • Logging into a mail server that does not use encrypted POP3 and SMTP protocols
  • You can even telnet to servers using an SSH tunnel if the service you need supports telnet only

LAB: Tunneling telnet traffic inside SSH

We mentioned before that telnet is an unencrypted protocol. Any traffic passing through telnet can be easily revealed and/or tampered with by any packet sniffer.

However, some legacy applications only work on telnet (I personally know some AS/400 applications that will not work except on telnet). So, one possible solution for this is to create an SSH tunnel and force telnet traffic through it.

First, let's install and start telnetd on our Ubuntu machine:

sudo apt install telnetd xinetd
sudo /etc/init.d/xinetd start

You may test that the service is running and accepting connections by running:

telnet ubuntu

Enter your username and password if prompted.

Now, logout of this session and issue the following command to create a tunnel:

ssh -L 2223:localhost:23 ubuntu

From another terminal, issue the following command:

telnet 0 2223

Enter the Ubuntu username and password if prompted. Notice that 0 in telnet syntax means localhost. You are now connecting to the local port 2223. Once the ssh commands detects traffic on this port, it will forward it, inside an encrypted SSH tunnel, to the remote host, Ubuntu and delivers it to port 23.

Using local port forwarding, you were able to encrypt the natively unencrypted telnet traffic.

Tunnelling through a third machine

In our lab, we were interested in connecting to a remote machine using a port that was opened on our local one. However, SSH tunnelling also allows you to dedicate another machine to act as your gateway or jump server. In other words, the scenario could be as follows: localhost => gateway(port 2223) => ubuntu(port 23) All traffic leaving localhost, passing through gateway, and finally arriving at ubuntu will be encrypted inside the SSH tunnel. To make use of this scenario, modify the command to be as follows:

ssh -L 2223:gateway:23 ubuntu

Notice that you will need to have OpenSSH server running on both the gateway and ubuntu. You will also need to have an account on both hosts; as you will be asked for your login credentials twice. Once the tunnel has been established, you can use your telnet command again, only this time you will be connecting to the gateway server instead of your local machine:

telnet gateway 2223

Using PuTTY

On Windows, you still can make use of SSH tunnels. We'll use PuTTY for this example as it is the most popular SSH client for Microsoft Windows. To create a local port forwarding tunnel on PuTTY follow these steps:

  1. Open PuTTY and select SSH => tunnels from the left navigation as shown:

  2. Select local in the Destination field

  3. Enter 23 in the source port. This is the port that you want to forward traffic to

  4. Enter localhost:2223 in the box, where localhost is the source machine that you want to use and 2223 is the port that you will open on this machine to accept your traffic.

  5. Now go to session and write the IP address or the hostname of the desination host.

  6. Establish the connection as you'd normally do.

  7. The tunnel is now open, you can try to establish a telnet connection by using PuTTY. Just remeber to set the destination to localhost and the port number to be 22223.