Guide to Configuring SSH Tunnel: Local, Remote, and Dynamic Port Forwarding

Network tutorial - IT technology blog
Network tutorial - IT technology blog

Problem Introduction: Overcoming Network Barriers with SSH

In my work, I often need to access services located behind firewalls or secure connections when working in public places. Have you ever wondered how to access an internal database from home, or test webhooks on a dev machine without directly opening ports?

In such situations, SSH is more than just a remote login tool. For me, it’s a versatile “Swiss Army knife” for tech professionals. Besides providing a secure shell, SSH can create encrypted tunnels. These tunnels allow us to forward network traffic securely and flexibly. With experience managing networks for a 50-person office and a small data center, I’ve found SSH Tunnel to be particularly effective. It simplifies many complex tasks and significantly enhances security.

This article will delve into the three most common types of SSH Tunnels: Local, Remote, and Dynamic Port Forwarding. I will explain when to use each type, how to configure them in detail, and provide practical examples to help you apply them immediately in your work.

Core Concept: What is an SSH Tunnel?

Before diving into the details, imagine an SSH Tunnel simply as creating an encrypted communication channel between two points via an intermediate SSH server. All data passing through this tunnel is encrypted, protecting you from threats like eavesdropping or impersonation. This is especially useful when you need to securely access unencrypted services (such as HTTP, Telnet, or regular databases) over a public network.

There are three main types, each serving a different purpose:

  • Local Port Forwarding: When you want to access a service on a remote server as if it were running on your local machine.
  • Remote Port Forwarding: When you want a service on your local machine to be accessible from a remote server, or from another location via that remote server.
  • Dynamic Port Forwarding (SOCKS Proxy): When you want to turn a remote server into a proxy, routing all your network traffic through it, which is very convenient for hiding your real IP address or bypassing network censorship.

Detailed Practice: Configuring SSH Tunnel Types

Local Port Forwarding (Connecting from local machine outwards)

When to use Local Port Forwarding?

Local Port Forwarding is the case I use most frequently. Imagine you are at home, needing to access the admin panel of a web application running on a server in the datacenter. This application only listens on an internal port (e.g., 8080) and is not exposed to the internet for security reasons. Or you need to connect to a database (PostgreSQL, MySQL) on the server, but that database also doesn’t allow external connections.

Instead of SSHing into the server and then using curl or CLI clients to interact, I would create an SSH tunnel. This tunnel forwards a port on my local machine (e.g., 8080) to port 8080 of the service on the remote server. Then, I just need to open my browser and access http://localhost:8080 to see the admin interface. Very simple and secure.

Syntax and Explanation

Basic syntax:


ssh -L <local_port>:<remote_host>:<remote_port> <user>@<ssh_server_ip>
  • -L: Specifies Local Port Forwarding.
  • <local_port>: The port on your local machine that you want to listen on.
  • <remote_host>: The IP address or hostname of the server where the service you want to access is running. This is often localhost if the service is running on the SSH server itself.
  • <remote_port>: The port of the service on <remote_host>.
  • <user>@<ssh_server_ip>: The username and IP address of the SSH server through which you will create the tunnel.

Practical Examples

Suppose you have an internal web app running on server_remote at port 8080, and you want to access it from your local machine (my_laptop) on port 8000.


# From local machine (my_laptop)
ssh -L 8000:localhost:8080 user@server_remote_ip

After this command runs successfully and you have logged into server_remote via SSH, you can open a browser on your my_laptop and access http://localhost:8000. All traffic from port 8000 on your my_laptop will be encrypted. Then, it will be sent through server_remote and forwarded to port 8080 of the service on server_remote.

Another example: accessing a PostgreSQL database running on server_remote (port 5432):


ssh -L 5432:localhost:5432 user@server_remote_ip

Now, you can use PostgreSQL management tools (like DBeaver, pgAdmin) on your local machine and connect to localhost:5432. The data will travel through the secure SSH tunnel.

Remote Port Forwarding (Opening a port from the SSH server to the internal network)

When to use Remote Port Forwarding?

Remote Port Forwarding is the opposite. There was a time I needed a partner to temporarily access a dev service on my local machine (e.g., an API running on port 3000). I didn’t want to open the port directly on the firewall or deploy it externally. Remote Port Forwarding was the neatest solution.

In other words, you want a service running on your local machine (e.g., my_laptop:3000) to be accessible from the outside. This is done through a port on the SSH server (server_remote).

Syntax and Explanation

Basic syntax:


ssh -R <remote_port>:<local_host>:<local_port> <user>@<ssh_server_ip>
  • -R: Specifies Remote Port Forwarding.
  • <remote_port>: The port on the SSH server (ssh_server_ip) that you want to expose for others to access.
  • <local_host>: The IP address or hostname of your local machine (usually localhost or 127.0.0.1).
  • <local_port>: The port of the service running on your local machine.
  • <user>@<ssh_server_ip>: The username and IP address of the SSH server through which you will create the tunnel.

Important Note: For Remote Port Forwarding to work, you need to allow others to access the port on the SSH server. Ensure the GatewayPorts yes option is enabled in the /etc/ssh/sshd_config configuration file on the SSH server. Afterward, restart the SSH service (sudo systemctl restart sshd).

Practical Examples

You have a web server running on your local machine (my_laptop) on port 3000. You want it to be accessible via port 8000 on server_remote.


# From local machine (my_laptop)
ssh -R 8000:localhost:3000 user@server_remote_ip

After this command runs and you have logged in via SSH, anyone accessing http://server_remote_ip:8000 will be forwarded to localhost:3000 on your my_laptop through the secure SSH tunnel. I have used this method to quickly demonstrate a demo to a partner without worrying about complex network configurations.

Dynamic Port Forwarding (Creating a SOCKS Proxy)

When to use Dynamic Port Forwarding?

This is a ‘trick’ I often use when I need to ‘travel the network’ or enhance security. When traveling or working in a cafe, I always use Dynamic Port Forwarding to encrypt all web browsing traffic. This ensures no one can eavesdrop on my data over public Wi-Fi networks. Or, when needing to access geo-blocked websites, Dynamic Port Forwarding will route traffic through an SSH server in another country.

Dynamic Port Forwarding creates a SOCKS proxy on your local machine. Any application (web browser, chat application, etc.) configured to use this proxy will send traffic through the SSH tunnel to the remote SSH server. From there, the SSH server will connect to destinations on the Internet on your behalf.

Syntax and Explanation

Basic syntax:


ssh -D <local_port> <user>@<ssh_server_ip>
  • -D: Specifies Dynamic Port Forwarding, creating a SOCKS proxy.
  • <local_port>: The port on your local machine that the SOCKS proxy will listen on.
  • <user>@<ssh_server_ip>: The username and IP address of the SSH server that will act as the proxy.

Practical Examples

Create a SOCKS5 proxy on your local machine on port 9090, using server_remote as the proxy server:


# From local machine (my_laptop)
ssh -D 9090 user@server_remote_ip

After this command runs, you need to configure your browser or application to use this SOCKS proxy. For example, in Firefox:

  1. Go to Settings -> Network Settings.
  2. Select Manual proxy configuration.
  3. In the SOCKS Host section, enter localhost and Port as 9090. Select SOCKS v5.
  4. Save and you can now browse the web via server_remote_ip.

For Chrome, you can launch it with proxy options (or use an extension like FoxyProxy):


# On Linux
google-chrome --proxy-server="socks5://localhost:9090"

# On macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --proxy-server="socks5://localhost:9090"

Other Useful Options

To optimize SSH Tunnel usage, I often combine several other useful options:

  • -N: Do not execute a remote command. Very useful when you only want to create a tunnel without opening an SSH shell.
  • -f: Go to background after authentication success. This allows you to continue using your terminal.
  • -q: Quiet mode, suppresses warnings and diagnostic messages.
  • -p <port>: Specifies the SSH port on the remote server if it’s not the default port 22. For example: ssh -p 2222 ....

Combining them, a command to create a Local Port Forwarding tunnel running in the background might look like this:


ssh -fN -L 8000:localhost:8080 user@server_remote_ip

This command will create the tunnel and immediately run in the background, returning control of the terminal to you.

Conclusion

SSH Tunneling is a powerful, flexible feature of SSH, helping to solve many daily problems. From securely accessing internal services to intelligently bypassing network limitations. In my role as a network system administrator, mastering and applying Local, Remote, and Dynamic Port Forwarding has saved me a lot of time and effort. At the same time, it has significantly enhanced the security of online activities.

I hope through this article, you have gained a clear understanding of each type of SSH Tunnel, knowing when to use them and how to configure them. Don’t hesitate to experiment with the example commands, as that’s the best way to truly master this amazing tool. Start exploring and turn SSH into your powerful ally in the challenging field of IT!

Share: