A Guide to SSH Port Forwarding/Tunnelling
SSH is a widely used protocol for system administration and file transfer. In addition, it has a feature called SSH tunnelling (or SSH port forwarding). It creates an encrypted connection between a local computer and a remote computer through which you can relay traffic. It is very useful, and you can use it to securely access unencrypted protocols such as VNC or firewalled resources like database servers. You can also use it as a form of proxy/VPN and get around restrictive, firewalled networks.
In this article, we’re going to take a look at using SSH port forwarding.
Before you can begin, you need to check if forwarding is allowed on the SSH server you’ll connect to.
If you’re using the OpenSSH server, open
/etc/ssh/sshd_config in a text editor. If you find
AllowTcpForwarding is set to
No, change them to
Yes. In addition, if you’re going to use remote port forwarding (discussed later in this article), you also have to set
Yes. Then, you need to restart the server for the change to take effect.
If you’re on Linux, depending upon the init system used by your distro, run:
sudo systemctl restart ssh sudo service ssh restart
Again, depending on your distro, you may find that the service is named
sshd instead of
If you’re on a Mac, you can restart the server like so:
sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist
You also need to have a SSH client on the computer you’re working on. On most Unix-like systems, it’s already installed by default. If you’re on Windows 10 and you use Bash on Windows, you can install OpenSSH in it the way you would on a regular Ubuntu system. However, you may need to add the
-4 switch, as IPv6 is not supported properly there.
For other versions of Windows, you can use the OpenSSH package from MSYS2 or Cygwin. If you’re not willing to bring an entire Unix-like system on your computer, try Putty.
(If you’re using Putty as your SSH client, simply replace the
ssh command with
putty in the examples below.)
Local port forwarding
Local port forwarding allows you to forward traffic on a port of your local computer to the SSH server, which is forwarded to a destination server.
That was quite a mouthful, so let’s look at a few examples. Say, you want to connect to a database server running at port 3306 on your server. The port for the database server is firewalled to protect it from external attackers. Although you can’t directly access the database server, you can do through SSH.
On your local computer, type in:
ssh -L 4000:127.0.0.1:3306 [email protected]
Now, SSH will bind to port 4000 on your computer. Any traffic that comes to this port is sent to the SSH server. Then, the traffic received is sent to port 3306 of 127.0.0.1, which is the server itself.
Now, you can connect to the database. You simply need to set the database client to use 127.0.0.1 as the host and 4000 as the port.
Moreover, you can forward multiple sets of ports in a single
ssh -L 5901:127.0.0.1:5901 -L 4000:127.0.0.1:3306 [email protected]
In addition to forwarding the local port 4000 to 127.0.0.1:3306, we’ve also forwarded the local port 5901 to 127.0.0.1:5901.
Note that the destination to which the SSH server forwards the traffic is from the perspective of the server itself. This has some very interesting implications. Say for example, there’s a single server having public SSH access in your company. You want to connect to the database server, which is running on
server003.local in the internal network, on port 3306. Now, you can forward ports like so:
ssh -L 4000:server003.local:3306 [email protected]
Now, point your database client to 127.0.0.1:3306 and bam — you’re connected to the database server!
Remote port forwarding
Remote port forwarding is the exact opposite of local port forwarding. It forwards traffic coming to a port on your server to your local computer, and then it is sent to a destination. Again, let’s take a look at an example.
Suppose, you’re developing a web application that’s running on port 8000 of your local computer. Other people can’t access it directly because you’re sitting behind a NAT network without a public IP. Now, you would like to show a customer how the application looks like. Fortunately, remote forwarding can help you with this. Type in:
ssh -R 7000:127.0.0.1:8000 [email protected]
When you run this command, the SSH server binds to the 7000 port on example.com. Any traffic that it receives on this port is sent to the SSH client on your local computer, which in turn forwards it to port 8000 on 127.0.0.1. Now, the customer can open
http://example.com:7000 in a browser, and they can use your application!
Again, as with remote port forwarding, you can also use a different destination. Say for example, you want a friend to help you with configuring a router. Since they can’t access your router directly, you can use remote port forwarding like so:
ssh -R 8080:192.168.100.1:8000 [email protected]
Dynamic port forwarding
So far, we’ve seen how to forward local ports with SSH. Although it comes very close to acting like a proxy, but you can’t use it as-is. This is because, you’ll need to specify different ports for every destination and every service you want to access, which simply isn’t practical.
Fortunately, there’s another type of forwarding called “dynamic port forwarding” which can be used for this purpose. In order to set up dynamic port forwarding, type the following command:
ssh -D 4000 [email protected]
The SSH client creates a SOCKS proxy at port 4000 on your local computer. Any traffic sent to this port is sent to its destination through the SSH server.
Next, you’ll need to configure your applications to use this server. The “Settings” section of most web browsers allow you to use a SOCKS proxy. Moreover, there are some extensions like Proxy Helper(Chrome) and FoxyProxy Standard(Firefox) that allow you to set up and switch proxies quickly.
For other applications, the Arch Linux wiki has some great instructions on using SOCKS proxies.
A few tips
If you’ve tried the above examples, you may have noticed that running the command also opens up a shell. If you don’t need the shell, you can disable it with the
ssh -N ... [email protected]
If you want SSH to go into the background, you can do so with the
ssh -f -N ... [email protected]
If you’re using SSH as a proxy, it’s best not to run a HTTP server on the remote machine. This is because many services will refuse registrations and transactions under the assumption that you’re using a web proxy.
In this article, we’ve seen how to use SSH forwarding, and how its useful in a variety of situations. If you have questions, feel free to ask in the comments below!
(BTW, if you’re using any of this at your workplace, you should first see if it’s okay with management — they might not be cool with it, after all.)