Fun with Forwarding and SSH Tunnelling

Linux (and all UNIX-based systems for that matter) is a pretty well thought out operating system with tones of useful features. I use either macOS or Linux every day for work and leisure and feels like every day I learn about some new cool features I can use to make my life as a researcher and nerd incredibly useful.

One of these features which I have come to use a lot is the ssh command – more specifically, SSH Forwarding. For those who identify as sysadmins, this may not sound very exciting but there is a lot more to this feature than what people think!

What is SSH?

For those who are unfamiliar with SSH, Wikipedia describes this as…

a cryptographic network protocol for operating network services securely over an unsecured network.^[1]^ Typical applications include remote command-line, login, and remote command execution, but any network service can be secured with SSH.


TLDR: A secure way to control a remote computer over an unsecured network.

The general syntax for SSH is as follows:

ssh [your-username]@[url-or-ip]

Unless you have already configured SSH keys (which I’m assuming you haven’t) you will then be prompted to enter your password. Congratulations! You have successfully logged into the server and can now control over it!

Useful commands

Now that you can connect to the server, you can start to perform some really cool networking hacks between your local machine (the client) and the server! With respect to forwarding, these features come in one of two forms; local and remote forwarding.

Local Forwarding

Local forwarding is the ability to send data from your local machine to a server by mapping a pair of ports together. Basically, your local machine shall listen for a connection on a given port (let’s call this port A) and tunnel it to a server where it will receive it on port B.

The syntax for this goes like this using the -L listen flag:

ssh -L [PORT-A]:localhost:[PORT-B] [SERVER]

Remote Forwarding

Perhaps the most useful feature of the two, remote forwarding is used to send data from the server tunnelled back to the client or local machine. In essence, this the reverse of local forwarding where any data sent using TCP to the server on port A will be directed back to your local machine on port B.

This syntax is a follows with the -R flag:

ssh -R [PORT-B]:localhost:[PORT-A] [SERVER]

This approach, in particular, presents several benefits when it comes to data transmission and security. It conveniently provides a way to around challenging firewalls by directing traffic securely through SSH’s port 22. This also means there is no need for port forwarding on a LAN network to expose a local device to the internet. Simple!


By no means exhaustive, here are just a few use case to put SSH forwarding to use. To make the most of these features, it’s worth configuring a VM with a static IP (like a DigitalOcean or Vultr instance). In my case, I have configured a dedicated server running Ubuntu 18.04 LTS.

Web Server

With the help of nginx or Apache, its possible to use a remote forward to direct web traffic on port 80 (or port 443 for HTTPS) to a device on your local network. This could be a good way dust that old Raspberry Pi of and use it to serve your projects to the world. I plan on doing this with my blog and cloud server at some point with my Pi4.

File Transfer using scp

As well as serving websites, the scp (secure copy) can be used to copy files between computers. Furthermore, with the use of a dedicated machine, a relay server can be established to send files using a P2P network.


Although explicitly it may not be an ssh command, netcat is another useful command for utilising networked computers. It’s also useful for sharing large files.


By using services like open OpenVPN or Wireguard your server can also double-up as a VPN server anywhere in the world. This also makes it easier to manage SSH tunnels.


To finish off, I’m sure that there are many more features I have missed out in this blog post as I am still new to this myself. I plan that over time, I will become familiar with more-advanced networking principles to the point where I can produce host my own software and build on top of existing services. As I’m writing this, I’m currently experiencing a government lockdown in response to the COVID-19 outbreak meaning I have more time on my hands for blogging and code 🙂