Create SSH Tunnel


An SSH tunnel is used to enable encrypted access to network services on a server. A port is made available on the server and on the client side for this purpose. Access to the client is then as if the tunneled service were running locally.

This tutorial describes all the necessary steps to set up such an SSH tunnel.

I did all the steps in this tutorial on two Gentoo systems. However, the commands should generally be applicable to all distributions.

Client - Create user and generate public key

To create an SSH tunnel you need a user. It should be clear to everyone that ROOT is unsuitable for something like this. You can take an existing user or create a new one:

useradd -m -G users -s /bin/bash tunnel

In my case, I chose the “tunnel” user, which I will use throughout the tutorial.

Next we create a public key for this user. If you already have one for your user, you can just skip this part.

We switch to our user in a console:

su tunnel

Now we create a private key. The key length should be at least 2048 bits. In my example I use 4096 bits.

ssh-keygen -b 4096

For our needs, we should do without a password for the public key, since we don’t want or can’t enter a password every time we connect. All queries are simply confirmed with ENTER. After that you should see the following:

Generating public/private rsa key pair.
Enter file in which to save the key (/home/tunnel/.ssh/id_rsa): 
Created directory '/home/tunnel/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/tunnel/.ssh/id_rsa.
Your public key has been saved in /home/tunnel/.ssh/
The key fingerprint is:
The key's randomart image is:
+---[RSA 4096]----+
|                 |
|           .     |
|          . o    |
|         . o..   |
|        S +.=*...|
|         = *=B+..|
|        . =EX++o |
|        o+.===B+ |
|       o+oo+oBBo.|

The next step is to set up the server side.

Server - Create user

A user should also be selected on the server side for setting up the SSH tunnel. If you don’t have one, just create one:

useradd -m -G users -s /bin/bash tunnel

Here I also call my user “tunnel”. But you can have any name. Also, usernames don’t have to be identical on the client and server side.

Transfer public key from client to server

On the client machine we log in as user “tunnel” and transfer the public key to the server.

ssh-copy-id -i ~/.ssh/

Of course you should use your username here, as well as the hostname of your server. You will then be asked for the password for the user on the server. Enter this and you should then see that the key was transferred correctly.

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh ''"
and check to make sure that only the key(s) you wanted were added.

So let’s try to connect from the client to the server via SSH:


Now you should be able to log in without a password. If this does not work, check “/etc/ssh/sshd_config” on the server whether the following entry is included:

PubkeyAuthentication yes

Now everything is ready to create an SSH tunnel.

Create SSH tunnel

On the client machine we can now create a tunnel with the following command. You should of course be registered as the appropriate user (“tunnel”).

ssh -L 2234:localhost:1234 -N -f -C

The user “tunnel” logs into the server ( and then creates an SSH tunnel exposing port 1234 on the server as port 2234 on the client (localhost). Assuming a web server is running on port 1234 on the server, it should now be accessible on the client in the web browser with “http://localhost:2234”.

At the end of the command I set a few parameters that I want to explain briefly:

  • With the -N option, the SSH connection is restricted to its tunnel function and there is no login to a shell.

  • The -f option runs the SSH tunnel as a background service.

  • With the option -C we can also compress the data transfer to speed it up.


It is now possible for us to forward any application via an SSH tunnel. However, it should be noted that the tunnels have to be created again and again when the systems (client / server) are restarted. It certainly makes sense to automate this when the system starts. However, that should not be part of this tutorial.