SSH tunnel. Local, Remote Port Forwarding

SSH Tunnel - Local and Remote Port Forwarding Explained With Examples. The best way to understand these is by an example, let’s start with local port forwarding.

Local Port Forwarding

$ ssh -L local_port:remote_host:remote_port ssh_login@remote_ssh_host

Example:

$ ssh -L 9000:example.com:80 user@my-web-server-host.com

-L - key here is which says we’re doing local port forwarding. 9000 - port local for forwarding example.com - remote host for forawrding via server 80 - remote port forwarding user - login for login to remote server with host: my-web-server-host.com

Then it says we’re forwarding our local port 9000 to example.com:80, which is the default port for HTTP. Now open your browser and go to http://localhost:9000. This is the same as open http://example.com:80

Forward local server port

Another good example is if you need to access a port on your server which can only be accessed from localhost and not remotely. An example here is when you need to connect to a database console, which only allows local connection for security reasons. Let’s say you’re running PostgreSQL on your server, which by default listens on the port 5432.

$ ssh -L 9000:localhost:5432 user@my-web-server-host.com

The part that changed here is the localhost:5432, which says to forward connections from your local port 9000 to localhost:5432 on your server. Now we can simply connect to our database.

$ psql -h localhost -p 9000

Remote port forwarding

Sometimes this can be solved by configuring NAT (Network Address Translation) on your router, but this doesn’t always work, and it requires you to change the configuration on your router, which isn’t always desirable. This solution also doesn’t work when you don’t have admin access on your network.

To fix this problem you need to have another computer, which is publicly accessible and have SSH access to it. It can be any server on the internet, as long as you can connect to it. We’ll tell SSH to make a tunnel that opens up a new port on the server, and connects it to a local port on your machine.

$ ssh -R remote_port:local_ip_or_hostaname:local_port ssh_login@remote_ssh_host

Example:

$ ssh -R 9000:localhost:3000 user@my-web-server-host.com

First you need to specify the port on which th remote server will listen, which in this case is 9000, and next follows localhost for your local machine, and the local port, which in this case is 3000.

There is one more thing you need to do to enable this. SSH doesn’t by default allow remote hosts to forwarded ports. To enable this open /etc/ssh/sshd_config and add the following line somewhere in that config file.

GatewayPorts yes

Make sure you add it only once!

 $ sudo nano /etc/ssh/sshd_config

And restart SSH

sudo service ssh restart

Notes

You might have noticed that every time we create a tunnel you also SSH into the server and get a shell. This isn’t usually necessary, as you’re just trying to create a tunnel. To avoid this we can run SSH with the -nNT flags, such as the following, which will cause SSH to not allocate a tty and only do the port forwarding.

$ ssh -nNT -L 9000:example.com:80 user@my-web-server-host.com

SSH has a huge number of features, so I’d recommend you to checkout the manual page at man ssh, which contains even more tips.

2019-08-17 11:12:30