Understanding SSH Tunneling
Tags: linux, ssh, learning, tutorial
Published: 2024-04-30 12:34:46

**What is SSH Tunneling and why is it useful?**

Usually when we think of ssh, we think about logging into a remote machine securely using a public/private key pair to execute commands, change configuration files, setup a web server or perform different actions. 

In the case of SSH Tunneling the same thing happens, but with a slight difference. SSH Tunneling also involves establishing a connection between a local machine and a remote server, but the main purpose of this connection is not to directly gain access to the remote server. The remote server acts as an intermediary to forward access to a specific port or host. 

Let's say you are working at home using your PC, but you want to gain access, to a web server, a database or service that is running locally on another private network. Maybe this service that you are trying to gain access to is running on the remote machine, but it's not exposed to the internet, it's running on localhost for security reasons. 

How can you gain access to it then? This is where SSH Tunneling comes into play allowing you to connect to local resources through a "tunnel". As mentioned before, the remote server takes care of forward your request to a specific host and port. Let's dive more into it.

### Local SSH Tunnels and Remote SSH Tunnels

There's two different types of ssh tunnels that we'll be exploring and that can be used depending on what your needs are.

#### Local/Forward SSH Tunnels

![local ssh tunnel diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ohu92ahwu28erb1eyii3.png)

Essentially what we achieve by setting up a local ssh tunnel between two hosts, is mapping a specific port in our local machine to a service that is running in the remote server locally with a reserved port, this can be helpful if we want to for example administer a database that is running in a remote machine, but it's not exposed to the internet. It's worth mentioning, sticking to our database example, that the database doesn't need to be run in the remote machine that we are establishing the ssh connection with, the remote server as long as it has access to other machines inside the same private network it can forward the request to that specifig machine.

![local ssh tunnel forwarding](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/195nasoxtqrsxpx4437n.png)

In the example above we're mapping port 3333 on localhost to port 3306
on the local machine with ip 192.168.1.55 that is running on the same network as the remote machine(44.65.167.34), which is the one responsible to forward our traffic and act as an intermidiary between both, otherwise traffic between this two local machines wouldn't be possible.

All this process is accomplished by executing the following command in local machine:

`ssh -N -L 127.0.0.1:3333:192.168.1.1 44.65.167.34`

With the `-N` flag we are specifying to not log in the remote machine shell and execute any commands and with the `-L` flag we are specifying that we want to perform a local ssh tunnel.

![local ssh tunnel command](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tq1ef9i8hg0lourtn9u4.png)

#### Remote/Reverse SSH Tunnels

Remote ssh tunnels are slightly complex to grasp in comparison to local ssh tunnels, but deep down, the functionality behind it, still remains the same, you still have a remote server forwarding traffic from A to B, that's basically it.

Let's say you're running a web server locally, that is not exposed to the internet at home and you want to gain access to it, but at this moment you are at your workplace. If you have a home server setup at your place you can still access your web server, since they both belong to your home private network, even though as previously mentioned, the web server is running on localhost.

To Accomplish this we will open a port in our home server that then will be mapped directly to the local machine and port that our web server is running on. This way everytime we access our home server on that specific port we will be redirected to our web server that is running locally. Anyone can access your web server this way, so it's not recommended to do this, this is just an example, but you can also think about establishing an ssh connection to your local machine located at home, the functionality is the same, in this case you would establish a ssh connection to your home server using the port that is mapped to your local machine.

![remote ssh tunnel diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tock64xjnmgjdt7kfneu.png)

In the example above, the remote machine is sending a request to the remote server ip address on port 8888, and then the server is forwarding the traffic to the host with which it's connected to via ssh.

To setup a remote ssh tunnel and allow this kind of traffic we will have to gain access to the `/etc/ssh/sshd_config` file and set the parameter `GatewayPorts` to `yes`(you can also uncomment it) in the remote server and then run the following command in your local machine in which your web server is running (your web server could be running on another local machine and you can still forward the traffic to it, since they are in the same network, but for the sake of the example we will do it this way):

`ssh -N -R 8888:localhost:80 remote-server-ip`

![remote ssh tunnel command](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43vfl3bcxaotue90io8v.png)