Skip to main content

How to set up SSH dynamic port forwarding on Linux

Dynamic port forwarding allows for a great deal of flexibility and secure remote connections. See how to configure and use this SSH feature.
Image
How to set up SSH port forwarding on Linux hosts
Photo by Christina Morillo from Pexels

Many enterprises use Secure Shell (SSH) accessible jump servers to access business-critical systems. Administrators first connect to a jump server using SSH, possibly through a VPN, before connecting to the target system. This method usually works great as long as an administrator sticks with command-line administration. It gets a bit more tricky when an administrator wants to break out of the command-line realm and use a web-based interface instead.

Let's look at the following scenario: Bob is a system administrator at Securecorp, and he just got an alert indicating that a database cluster consisting of sirius.securecorp.io and orion.securecorp.io is performing poorly. For an initial analysis, he usually uses the RHEL8 web console. The firewall doesn't allow him to connect directly to this system from his workstation, but he can go through a jump server called bastion.securecorp.io.

[ You might also enjoy: 6 essential SSH guides for sysadmins ]

SSH command-line access to the database cluster is straightforward:

[bob@workstation ~]$ ssh bastion.securecorp.io
[bob@bastion ~]$ ssh sirius.securecorp.io
[bob@sirius ~]$
[bob@workstation ~]$ ssh bastion.securecorp.io
[bob@bastion ~]$ ssh orion.securecorp.io
[bob@orion ~]$

But what if Bob wants to access the RHEL8 web console of sirius.securecorp.io and orion.securecorp.io? There are multiple ways to achieve this goal using SSH, all involving port forwarding of some sort.

Disclaimer: In some organizations, security policies do not allow port forwarding. To make sure that you don't breach any rules, please consult with your IT security representative.

SSH port forwarding

Using SSH, Bob opens a TCP tunnel for both systems, pointing to the web console port (9090) for sirius.securecorp.io and port 9091 for orion.securecorp.io.

[bob@workstation ~]$ ssh -L 9090:sirius.securecorp.io:9090 bastion.securecorp.io
[bob@bastion ~]$
[bob@workstation ~]$ ssh -L 9091:orion.securecorp.io:9090 bastion.securecorp.io
[bob@bastion ~]$

Bob can now point his local workstation's browser to https://localhost:9090 to access the web console for sirius.securecorp.io, and https://localhost:9091 to access the web console for orion.securecorp.io.

This approach might work well in certain cases but has its limitations:

  • TLS certificate validation: The local browser is unhappy because, in most cases, the certificate Common Name doesn't match with the hostname in the address bar (localhost), so the certificate validation fails.
  • Redirects: When the website you are accessing redirects you to another URL, the connection fails because port forwarding is only valid for exactly this web server. This situation might be a problem when using single sign-on (SSO), for instance.

Start a browser on the jump server

Bob would also be to start a browser such as Firefox on the jump server and display it locally on his workstation. SSH provides a feature called X forwarding, which can be used in this situation.

[bob@workstation ~]$ ssh -X bastion.securecorp.io
[bob@bastion ~]$ firefox https://sirius.securecorp.io:9090 &
[bob@bastion ~]$ firefox https://orion.securecorp.io:9090 &

Using this method, the browser process runs on the jump server, and the connections to the web consoles of sirius.securecorp.io and orion.securecorp.io are allowed. Only the rendering of the browser window happens on Bob's workstation.

While this approach solves some problems of plain SSH port forwarding, it also has limitations:

  • Performance: This method usually performs rather poorly because the graphical output has to be transferred from the jump server to the workstation through the network, which is very inefficient.
  • Prerequisites: A browser such as Firefox needs to be installed on the jump server, and an X server needs to be running on the workstation.

Enter dynamic port forwarding

Having explored the previous two approaches and learned about their disadvantages, it would be great to have a third option, which brings us the best of both worlds:

  • The workstation's browser can be used.
  • Connectivity and DNS name resolution should be the same as on the jump server.

To achieve this, SSH provides a feature called dynamic port forwarding, which leverages the SOCKS protocol. In this configuration, SSH acts as a SOCKS proxy, relaying all relevant traffic through the SSH connection. For this to happen, the client (in our example, it is the browser) needs to be SOCKS-aware.

Bob can initiate an SSH session with dynamic port forwarding as follows:

[bob@workstation ~]$ ssh -D 1080 bastion.securecorp.io
[bob@bastion ~]$

After that, the browser on Bob's workstation needs to be made SOCKS-aware. The Firefox configuration can be accomplished like this:

  • Point the browser to about:preferences.
  • In the General tab, scroll down at the bottom, and click on Settings... in the Network Settings section.
  • In the Connection Settings window, choose Manual proxy configuration, specify localhost for SOCKS Host, 1080 as Port, and select SOCKS v5.
  • In the same window, select Proxy DNS when using SOCKS v5.
Image
SOCKS5 configuration in Firefox
SOCKS5 configuration in Firefox

Bob can now point the browser to https://sirius.securecorp.io:9090 and https://orion.securecorp.io:9090 to analyze the performance problems of his two database servers using the RHEL8 web console. He can also access any other internal resources as if the browser was running on bastion.securecorp.io.

Note: Port 1080 is the IANA registered port for SOCKS, but the connection can use any other port. The numbers in the SSH and browser configuration have to match.

Personally, I found it useful to create a separate browser profile so it is not necessary to constantly switch between proxy configurations. A new profile can be created by passing the -P switch to the firefox command, launching the Profile Manager. I called my profile Jump. After creating a new profile, an empty configuration is created. In this profile, I applied the configuration as described above while leaving my default profile untouched.

Image
Profile configuration in Firefox
Profile configuration in Firefox

After creating the profile, Firefox can be launched with the following command:

[bob@workstation ~]$ firefox -P Jump

Another helpful tip is to create a host-specific configuration for dynamic port forwarding in your ~/.ssh/config file. For example:

[bob@workstation ~]$ cat ~/.ssh/config
Host bastion
  Hostname bastion.securecorp.io
  User bob
  DynamicForward 1080

[ A free course for you: Virtualization and Infrastructure Migration Technical Overview. ] 

Wrap up

There are many ways to connect to internal systems using a jump server and the possibilities outlined above are by no means exhaustive. In my experience, though, SSH provides you with a very powerful tool kit, which in most cases is available and ready to go without many hurdles. Dynamic port forwarding is one of these tools and it has helped me to be more productive in specific situations, so please give it a try yourself.

Topics:   Linux   Linux administration   Security  
Author’s photo

Juerg Ritter

I am a Red Hat Certified Engineer who first dipped his toes in the world of Linux and open-source software around the year 2000. Since 2005, I have been working in a professional setup with Red Hat products in various roles. More about me

Try Red Hat Enterprise Linux

Download it at no charge from the Red Hat Developer program.