Skip navigation.
Home

SSH Tunneling

SSH has some nifty tunneling features which I have found to be extremely useful.  Some of the handy uses I have found are:

  • Tunnel VNC connections
  • Allow X-Window forwarding
  • Tunnel POP or IMAP connections which are behind a NATed firewall

First here are some SSH tunneling basics.  You can only tunnel TCP connections when the remote SSH server permits tunneling.  The configuration option for the OpenSSH server is:

AllowTCPForwarding yes

By default, this option is "yes" and must be explicitly set to "no".

There are two ways to forward a port:

  • forward a port on the client to a port on the server
  • forward a port on the SSH server to a port on the client

Client Port Forwarding

In the first case a connection attempt on the specified client port will be forwarded to a corresponding port on the server.  This is the most common type of port forwarding. As a concrete example suppose you want to download your POP mail on a server which only allows SSH connections, but blocks POP connections. A way to get your mail would be to forward a client port to the server's POP port (TCP port 110). If you do not have root access on your client, then you must forward a high port (>1023) to remote port 110 on the server.  Suppose the server is called server.somedomain.com, then the forwarding command on a Linux box would be:

ssh -L50000:localhost:110 server.somedomain.com

Please note the syntax for the -L option. It consists of 3 fields separated with colons.  The fields are:

  • local port number
  •  host name
  • remote port number

You may think the host name  field is redundant.  It is not because you can specify any host reachable from the server.  In most cases it is localhost which is the loopback interface on any machine. We set the remote host name to localhost because we want to connect to port 110 on the server itself.  The remote host name is relative to the server.  It is not the local interface on the client.  Diagrammatically, the connection looks like this:


The client connects to port 50000 on its loopback interface.  That is where the SSH process sets up a listener.  It establishes the connection with the local process (in this case a mail reader) and also establishes a connection with the server on port 110.  Presumably, this is where the POP server is listening for connection requests.  After the two connections are established, all the data sent from the client mail reader ends up being received by the POP server on the server.  As an added benefit, all the data is encrypted in the SSH connection.

You need to establish the SSH connection first in order for this to work.  After the SSH connection is established, you can start your mail reader on the client.  After the mail is downloaded,  you can logout from the SSH session.

Server Port Forwarding

Forwarding a port on the server to a port on the client is less common, but does have some applications. Suppose you have a system where you want to run a VNC server and connect to the server from your client machine.  Normally, you would create a VNC server, say, on port 5900 on the server and then connect to this service remotely with a VNC viewer application.  This works, but poses some potential security and configuration issues.

First all your network traffic is unencrypted.  This includes your VNC password.  Second, if the server is behind a firewall, you would have to open up port 5900 which is also a bad idea.  Instead, you can start up your VNC client and ask it to listen for connections on port 5500.  You can then SSH to your remote server and port forward the remote port 5500 to your local port 5500.and start up a VNC server. Finally, you can run vncconfig with the appropriate options to tell your VNC server to connect to local port 5500 which is port forwarded over the SSH tunnel to port 5500 on your client system where your VNC client is waiting for a connection. 

Here is what the connections look like for this case.

remote_ssh_tunnel

The command sequence to do the above using standard Linux command is as follows:

vncviewer -listen &

ssh -R 5500:localhost:5500 server.somedomain.com

vncserver

vncconfig -display :1 -connect localhost:5500

All commands are run with respect to the client.  We put the VNC viewer in the background and then set up the SSH connection to the server with the appropriate port forwarding.  We then run the vncserver command and note the display number in the output.  Finally, we run vncconfig with the display number output from the vncserver command and tell it to make a reverse connection to port 5500 on the server which is forwarded over the SSH connection back to the listening VNC viewer.

This has a number of advantages from a security perspective.  First of all the VNC traffic is encrypted.  Second the VNC server only needs to be listening on its own loopback interface.  And finally, this method does not require a password, since there are no remote connections.

Conclusion

There is more to SSH tunneling and port forwarding than these two examples.  In future posts, I will expand on further uses of SSH tunneling.