SSH Port Forwarding in Linux: Configuration and Examples

Sarath Pillai's picture
SSH Port Forwarding

During the mid 90's (1995 to be precise) one researcher named Tatu Ylönen, at the university of Helsinki (Finland) designed a protocol, that eventually replaced all remote login programs. The primary objective behind Tatu Ylönen's design of the new protocol was to stop password sniffing attacks.

 

In other words, remote login programs prior to 1995 used to send login credentials and other critical information in clear text format through the wire. Due to this, anybody with a little bit technical knowledge can sniff the packets and read the password.

 

The new design and implementation made by Tatu Ylönen, is called as SSH (Secure Shell.). System administrators use this tool day and night to gain access to their remote systems. If you daily use SSH and wants to know how this thing works, then I would recommend reading the below post.

 

Read: How Does Secure Shell Work

 

SSH secured our primary task of remote login, by authenticating both the client and the server and also securing the data transmitted with powerful encryption algorithms. However there are many other protocol's that needed to be secured.

 

After the initial introduction of SSH in 1995, the protocol has went a couple of iterations and the current secure version is SSH version 2 protocol. There is a better modified application which was inspired by ssh, and is now available. It has got several advanced features compared to ssh. We have already discussed about that modified version, which is a good alternative to ssh.

 

Read: Better Alternative to SSH

 

The SSH application that comes with many of the Linux distribution is called as OpenSSH. And it has got several good features, that can even help secure some other insecure protocols. I must say using this feature, you can go ahead and secure any insecure protocol available.

 

There are too many weakly authenticated applications out there, which can be secured by using SSH. You might be thinking how can you secure another application which will be running on another port, other than ssh using SSH itself.

 

Yes that can be done. The main objective of this article is to explain the working of securing other insecure applications by using a secure SSH connection.

 

The idea behind this is to forward or tunnel other insecure communication channels inside an ssh secure channel.  You can say that the insecure protocol, will travel inside the secure SSH connection.

 

So the security features that secures an SSH connection can now be used to secure other protocols as well. The main point to note here is that, the application that you will secure using SSH will not even be aware of this, hence there is no major modification required on that application (But yeah you need to modify the ssh settings ).

 

Another added advantage of securing other insecure applications using SSH is that, the security provided by ssh will be an added layer of security apart from the existing security layer provided by the application itself. Hence redundant levels of security can be achieved using this.

 

This feature of securing other insecure application/protocols using SSH is referred to as Port Forwarding, or sometimes called as Tunneling. Its called as tunneling because other application traffic is being tunneled through SSH channel. Before the end of the article, you will come to know that why is it also called as Port Forwarding.

 

 

What are the main reasons to use SSH Port Forwarding/ Tunneling.?

 

The first major reason is the one which we already discussed (To secure other insecure protocol). However apart from this, there can be another reasons due to which you can use this feature. A couple of those reasons are mentioned below.

 

  • The firewall behind which your server is, only allows traffic to port 22.
  • You need to compress the traffic send over wire, using SSH compression feature.

 

Please note the fact that you can only tunnel TCP traffic using SSH Tunneling or Port Forwarding. However, there are some techniques using which you can even tunnel UDP Traffic using SSH port forwarding. I will not be discussing UDP Tunneling in this article. I Will write a separate post on SSH UDP tunneling, as it requires some special attention.

 

Before getting inside the configuration part, let's first understand how this Tunneling/forwarding works.

 

How does SSH port forwarding work

 

In the above shown diagram, i have shown that a telnet connection is encrypted over SSH. You might be thinking, why would one use telnet, if you have ssh. Yeah that's correct ! Nobody will use telnet if you ssh available smiley.  I have used telnet, to show this illustration( Also telnet is insecure ).

 

If you see the diagram, it seems quite clear that the telnet client software, will send its connection traffic to the local SSH. And then the local SSH will send it to the target server's SSH. The target server's SSH will submit the traffic back to telnet. Hence the entire data was encrypted over wire.

 

Now let's see how to configure this. The first step is to enable SSH TCP Port Forwarding feature, on both the sides(The ssh client and the server ). This can be done by modifying the ssh configuration file /etc/ssh/sshd_config. You need to add a line that enables TCP Port Forwarding. Its shown below.

 

AllowTcpForwarding yes

 

Once you added the above line, you need to restart SSH service, for the new configuration to take effect.

 

# service ssh restart

 

Now we need to know two port numbers. One is the default telnet port 23, which we already know, and the other is an arbitery port number, which is not currently used on your machine. For showing this example, i will use port number 8888(You can use any port number of your wish. Please remember that for using port numbers above 1024, you need root permission).

 

No what we will do is to ask our SSH server to forward all requests on our selected port 8888, to target server's(our remote telnet server) 23 port. This can be done by the following command. Let's first see the syntax of the command, and then we will see the command.

 

#ssh -L<Local Port>:<Local Machine>:<Target Port>  <Target Machine>

 

Local Port: Is the random port we selected (in our case its 8888)

Local Machine: Enter localhost here, because its your localsystem

Target Port: This is the target service port number, in our case its 23, because we are tunneling telnet

Target Machine: This is the target server's IP address/Hostname

 

Hence our command to tunnel telnet traffic through SSH will be something like the below.

 

#ssh -L8888:localhost:23 192.168.0.106

 

In my case the target server is one machine in my intranet 192.168.0.106. Replace this with your remote server IP address.

 

Running the above command by surprise will log you inside the target host (after asking you for the password, it will be better if you have key based authentication setup, because that wont ask you the password).

What ? i don't want to log inside that target server, but i want to only create a tunnel between my system and the target server, so that i can forward my telnet traffic through that. So the thing is, when you run the above command, the local system first will create a connection by logging you inside that server, so that you are authenticated, and other traffic (telnet traffic ) will flow through that connection.  If you logout or close this ssh connection, then telnet traffic will not be able to use SSH tunneling (because the connection is not there, and how will you tunnel it).

 

Hence we need to use an additional option in the previous shown command. And the option is -N and -f.

#ssh -N -f -L8888:localhost:23 192.168.0.106

 

Of course the above command will also ask you a password (if you are using password ssh authentication ), but will not log you inside the target server. It will fork an SSH process, and will wait there for your requests to be tunneled.

 

Now you can log into your target server's telnet, by using the localhost port 8888. Hence when you run the below command, you will log inside the target telnet server.

 

#telnet localhost 8888


 

There is an interesting thing to this telnet session you just established using SSH tunneling. If you run "who" command (on the target server, after logging inside through telnet), it will show that you are logged in from "localhost", instead of your server IP address.

 

Because we are really logging in from localhost port 8888 and ssh is doing all the trick of taking the traffic on localhost port 8888 to the target server ssh port, which after decrypting the content, will give it to telnet port 23.

 

The application that requires SSH tunneling apart from telnet and other insecure remote login program is VNC. Because telnet was shown just this illustration purpose, and nobody really uses telnet these days. VNC is a highly used application which is insecure. Data send and received by a VNC server is all in clear text format, and hence needs to configure something like SSH tunneling to secure it.

 

By default VNC listens on port 5900, 5901, 5902. Hence you can easily setup a port forwarding for tunneling your insecure VNC sessions. The command is pretty much the same..

 

#ssh -N -f -L5900:localhost:5901 192.168.0.106

 

 

The above command means that if you connect to port no 5900 using vnc viewer on localhost, you will get connected to the target server VNC. In our case we can simply run the below vncviewer command to get connected.

 

 

#vncviewer localhost:2

 

Please note the fact that port no 2 used in the above command is VNC session port, which is different for different user,  (this port has nothing to do with the TCP port.). Also if you notice, we have not mentioned the TCP port we have used while creating the tunnel ( port 5900 ), that's because the vncviewer will use the default port in case if you don't mention.  And we purposely configured the default port 5900 as our Local Port during the tunnel configuration.

 

What we have seen in the previous example's of port forwarding is called as Local Port forwarding. Now why is it called as Local Port Forwarding?. Its because, the target server's port (The server to which you are making connection) is available in the form of a local port. We have used our local port 8888 to reach remote telnet port 23. 

 

Also we have used the option -L, while configuring SSH port forwarding. L stands for Local. Now there is another type of port forwarding called as Remote Port Forwarding. Let's have a look at what it is.

 

What is Remote Port Forwarding?

 

Don't get confused between the two ( Remote Port Forwarding and Local Port Forwarding ), because both of them are almost very much similar, except a very slight difference. This very slight difference can sometimes become the source of confusion.

 

This remote forwarding is used when you are inside the target server and want to set up port forwarding for the client. It is called as remote port forwarding because you are setting this port forwarding from the remote server (Target server.). For instance, let's consider that you are inside that target server 192.168.0.106 (The same server where you have telnet server running, to which we set up a local port forwarding previously ). You can configure Remote Port Forwarding by the below command.

 

#ssh -N -f -R8888:192.168.0.106:23 192.168.0.105

 

In the above shown command, we have used -R option to set up remote port forwarding, because we were in the target system( 192.168.0.106 ). And from the target system we are configuring port forwarding for our client ( 192.168.0.105 )to login securely.

So if you run the command with -R option from the target server, which will log inside the client system and open a port and forward it back to itself through SSH, then its called as remote port forwarding.

 

The only thing to note is we have executed the command from the target machine, so that the client can connect to it securely by the below command. Please note that the client will connect it using the same command, as we used during local port forwarding. There is no difference as far as the method used by the client to get connected.

 

#telnet localhost 8888

 

Hence to put a final note on the difference, and to avoid further confusion...

 

  • Use Remote Port Forwarding when you are inside the server which contains the application (Example the telnet server)
  • Use Local Port forwarding when you are on a client machine and the application is on a remote machine.

 

Now there is a third kind of port forwarding called as Dynamic Port Forwarding. It is commonly used to bypass firewall rules and other filtering. Let's see how this Dynamic Port Forwarding Works.

 

What is Dynamic Port Forwarding?

Let's take one example to understand how this thing works. To make this example interesting, let's imagine that you are inside your university network. And the university firewall only allows you to browse several web pages like wikipedia.com, google.com, etc. Hence you cannot open pages like facebook.com, or youtube.com.

 

Imagine you have a server at your home which has got public IP address to it. And has SSH server installed on that, and you can access it from anywhere.  Now you can simply run the below command on your terminal from the university workstation.

 

$ ssh -D 6868 user@<remot-host>

 

 

In the above command, you have asked to open a local port 6868 on the university workstation (localhost), which will forward all requests to that port to the remote host (which will be your server at home).

 

Now the question is how will you use this to browse the restricted websites?

 

Before beginning to browse those restricted web pages, let's understand what is happening. When you ran the above command, your server at home has become a SOCKS proxy server.  SOCKS stands for Socket Secure. It acts like a Proxy server that will make TCP connection to any destination suggested by the client.

 

So in short the remote host (your server at home) acts as a proxy for all connections you send on localhost 6868. Unlike a regular HTTP proxy server, our SOCKS proxy server does not intepret the HTTP traffic that flows through it. A normal HTTP proxy is intelligent enough to understand HTTP protocol that flows through it, but it only understand HTTP traffic, and cannot be used to tunnel all TCP traffic through it. Our SOCKS proxy server can be used to tunnel any kind of TCP traffic through it(Provided the application using which you are sending traffic, knows SOCKS proxy).

 

So if you are using a web browser, it knows how to send SOCKS messages to our SOCKS server. Hence let's go ahead and configure our web browser to send all http traffic to localhost port 6868 ( which will intern send them to our remote home ssh server )

 

In Firefox you can configure SOCKS proxy by going to EDIT ---> Preferences ---> Advanced ---> Network ---> settings. Select manual proxy configuration from the window.

Firefox socks proxy

 

Once you save the settings and restart firefox, you will now be able to access all URL's using our newly configured SOCKS proxy server. Firefox will forward requests to localhost 6868 port, which will intern forward it to our remote home server through secure SSH tunnel.

 

This technique can also be used if you are accessing internet from an insecure network. Like for example, you are in a hotel and using their wifi. But you want to hide whatever you are accessing on the internet.

Rate this article: 
Average: 4.8 (88 votes)

Comments

Yes , understood , most of the stuff . But for reverse port forwarding , how can you open port 8888 on the local box from remote box ?

Hi
I've learnt a little more about the use of ssh and port forwarding to access a remote server.
I'm trying to set up remote access to a server that is on a remote network with dynamic IP address. I've registered with dyndns.org to get a domain name, and on the router, I've configured port forwarding (port 22 for server IP 192.168.0.120) and the DDNS settings to dyndns.
My server is running RedHat.
Should I be running ssh on the server using '-R' and pointing port 22:192.168.0.120 to itself (since the remote client is on another network)?
Thanks
Peter

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.