SSH Tunnel

What is an SSH Tunnel?

A secure tunnel between two machines using the SSH protocol.

An SSH tunnel exists between an SSH client such as PuTTY/PLINK (Windows) or ssh on Linux, and an SSH Server (sshd). It can be used to securely connect a client on one machine to a server that is behind a firewall, by "tunnelling" all communications through the SSH connection.

How does the tunnel work?

The best way to describe an SSH tunnel is with a diagram.

Consider the following, which shows a normal connection between two machines:

Two more ports and hosts are now involved in the connection, making it more complex than before. However, the tunnel allows us to authenticate and send all traffic through the SSHD gateway server. To mysql.metawerx.net, the connection is now a local network connection. As a result, mysql.metawerx.net is now happy to accept our connection.

The following diagram shows all the port numbers being used above. This will be important when learning how the tunnel commands work.

When making connections outward, a random port number is selected. It is only the "listening" ports (connections inward) that we are concerned with.

As you can see, because of the connections, CLIENT thinks it is connected to a local database running on localhost:3307. Likewise, the MYSQL server thinks it is receiving a connection from ssh.metawerx.net (a local server, inside the firewall).

In this way, we are tricking the CLIENT and MYSQL by tunnelling all data securely between the two machines.

How to set up a tunnel

Now let's look at the command to establish the tunnel above. We will assume the following:

Your gateway server is ssh.metawerx.net, port 22 (the default)

Your username for ssh.metawerx.net is "ssh_cassie"

Your password is "cassiepass"

If using Windows, you have installed PLINK as c:\installers\putty\plink.exe

We are asking SSH to listen on the CLIENT SIDE (localhost:3307) on our local machine

After we connect to localhost:3307, SSH will tunnel to SSHD (ssh.metawerx.net:22)

SSHD will connect to the SERVER SIDE (mysql.metawerx.net:3306)

Our data will be passed to SSH, which will pass it through the tunnel to SSHD on the gateway, and SSHD will pass it on to the server

Checking the tunnel is active

If the tunnel is active and everything is working as expected, you should be able to connect to localhost:3307 with your client, and start interacting with the database. You can also try connecting with telnet.

telnet localhost 3307

If a blank screen appears, or something like the following, your tunnel is working well.

However, if you receive an error such as the following, your tunnel is not healthy.

telnet: Unable to connect to remote host: Connection refused

Let's look at some commands you can use to check that your SSH command is working the way you expected.

We can verify the CLIENT SIDE and GATEWAY parts of the command by checking if SSH is listening on the expected port.
This is done by using netstat, which shows all listening ports and connections on your machine.

Windows:

C:\Documents and Settings\Administrator>netstat -na
Active Connections
Proto Local Address Foreign Address State
TCP 127.0.0.1:1105 0.0.0.0:0 LISTENING
TCP 127.0.0.1:3307 0.0.0.0:0 LISTENING <=== Yes, listening on 127.0.0.1:3307
TCP 127.0.0.1:8005 0.0.0.0:0 LISTENING (127.0.0.1 is the same as "localhost")
TCP 192.168.0.18:53 0.0.0.0:0 LISTENING
TCP 192.168.0.18:4400 0.0.0.0:0 LISTENING We are also listening on a lot of other ports,
UDP 0.0.0.0:445 *:* but that is not important for this tutorial,
UDP 0.0.0.0:500 *:* so just look for 127.0.0.1:3307, or whatever you
UDP 127.0.0.1:53 *:* used in the CLIENT SIDE of the tunnel.
UDP 192.168.0.18:53 *:*
C:\Documents and Settings\Administrator>

On linux we use netstat as well. We will also use grep to ignore all lines except those that contain the text "3307" - the port we are checking for.

If you cannot see 127.0.0.1:3307 in the netstat command, your SSH program is not listening correctly, so retry the PLINK or ssh command.

If you close the tunnel by closing PuTTY/PLINK/SSH, you should notice that the listening port on 127.0.0.1:3307 disappears.

If you have verified that SSH is listening, then you have a good connection to the GATEWAY (SSHD) and the CLIENT SIDE of the tunnel appears to be working. If the tunnel itself still isn't active, then there could be a problem in the SERVER SIDE of the command. This can be seen in the logs on the server.

The point of this guide was to give a description of the way the tunnel works, and how to construct tunnels of your own.

If you are having problems setting up a tunnel, please continue by reading SSH Tunnel Troubleshooting, which contains guides to error messages and more help.