Limited time offer! 25% off our lifetime plans with code LMT25 at checkout. View plans →

Linux Administration

SSH Reverse Tunnel: How to Set Up and Secure It

SSH REVERSE TUNNEL
On this page

An SSH reverse tunnel lets you access a service on a machine that cannot accept direct incoming connections. It works by establishing an SSH connection from that machine to a reachable server and forwarding a port on the server back to a service on the original machine.

This technique is useful when a Linux server sits behind a firewall, a device uses a private IP address, or you need temporary access to a development service without exposing it directly to the internet. You can create a reverse SSH tunnel with the ssh -R command and control how the forwarded port is accessed.

In this guide, you will learn how reverse SSH tunneling works, how to configure it on Linux, how to test the connection, and how to troubleshoot common problems without creating unnecessary security risks.

What Is an SSH Reverse Tunnel?

An SSH reverse tunnel is a form of remote port forwarding that carries network connections through an existing SSH session. It allows a machine to make a connection to a reachable SSH server and provide access to a service running on the machine that initiated the connection.

Consider a Linux computer running a development application on port 3000. The computer is behind a router or firewall, so another machine on the internet cannot connect directly to it.

If the Linux computer can connect to a public server over SSH, it can create a reverse tunnel. The public server listens on a selected port, and connections to that port travel through the SSH connection back to the application on the Linux computer.

This approach does not require you to open a direct incoming connection to the original computer. However, the public server must allow the required SSH forwarding, and its firewall must permit access to the listening port when needed.

Reverse tunneling SSH is also useful for temporary remote administration, testing, and accessing internal services through an approved gateway.

How Does Reverse SSH Tunneling Work?

A reverse SSH tunnel involves two main machines:

  • Source machine: The computer running the service you want to access. It initiates the SSH connection.
  • Remote server: A reachable SSH server that receives the connection and provides the remote forwarding port.

The connection works in the following order:

  1. The source machine establishes an SSH connection to the remote server.
  2. The SSH client requests a remote port forward using the -R option.
  3. The remote SSH server opens a listening port, subject to its configuration and available ports.
  4. A client connects to that port on the remote server.
  5. SSH carries the connection through the established tunnel to the destination service on the source machine.

The important detail is that the SSH session starts from the source machine, but the forwarded port is created on the remote server.

For example, a reverse tunnel might map port 8080 on the remote server to port 3000 on the source machine. A client using the remote server’s loopback address can then reach the application through the tunnel.

By default, OpenSSH binds remote forwarded ports to loopback addresses. Other machines cannot automatically access the forwarded port just because the tunnel exists. Exposing it to other network interfaces requires additional configuration and careful access controls.

When Should You Use an SSH Reverse Tunnel?

A reverse SSH tunnel is useful when you need controlled access to a service but cannot or do not want to expose the source machine directly.

Common use cases include:

Accessing a Server Behind a Firewall

A machine may be able to make outgoing SSH connections while its firewall blocks incoming connections. If you have an authorized account on a reachable server, you can establish a tunnel from the restricted machine and access a selected service through the remote endpoint.

Remote Access to a Development Application

Developers often run applications on local ports that are not publicly accessible. A reverse tunnel can make a development service reachable through another server for testing, provided the port is protected and the application is safe to expose to the intended users.

Connecting to an Internal SSH Service

You can forward a port on a reachable server back to port 22 on a remote Linux machine. This can help with authorized administration when direct SSH access is unavailable.

Troubleshooting Private Infrastructure

System administrators can use reverse tunneling to reach a specific service during an investigation without making that service permanently public. This is particularly useful for temporary maintenance, testing, and diagnosing connectivity problems.

A reverse tunnel is not a replacement for a proper VPN or a complete network access policy. For regular production access, consider whether a VPN, managed access gateway, or other controlled remote access solution is more suitable.

How to Create an SSH Reverse Tunnel on Linux

Before creating a reverse tunnel, make sure you have:

  • A Linux machine running the service you want to access.
  • A reachable server with SSH access.
  • An authorized SSH account on that server.
  • Permission to use remote port forwarding.
  • A port that is available on the remote server.

The following example assumes that an application is listening on port 3000 on the source machine and that you want to forward it through port 8080 on the remote server.

Step 1: Confirm That the Local Service Is Running

On the source machine, check whether the application is listening on port 3000:

ss -lntp

Review the output for the expected port. You can also test the application directly if it serves HTTP:

curl http://127.0.0.1:3000

This request should reach the application if it is running and listening on that address. If it fails, fix the local service first. An SSH tunnel cannot make an unavailable application work.

Step 2: Connect to the Remote Server With Remote Port Forwarding

Run this command on the source machine:

ssh -N -R 8080:127.0.0.1:3000 user@your-server-ip

Replace user with your SSH username and your-server-ip with the actual address or hostname of your remote server.

Here is what each part means:

Option or valuePurpose
sshStarts an SSH connection
-NDoes not execute a remote command; the connection is used for forwarding
-RRequests remote port forwarding
8080Port opened on the remote server
127.0.0.1:3000Destination address and port on the source machine
user@your-server-ipSSH account and remote server

The command remains connected while the tunnel is active. Enter your password or complete SSH key authentication if prompted.

If the remote server rejects the forwarding request, check the server’s SSH configuration and the error message. The account must be allowed to request the required remote forward.

Step 3: Test the Tunnel From the Remote Server

Open another terminal and connect to the remote server normally:

ssh user@your-server-ip

Once connected, test the forwarded port:

curl http://127.0.0.1:8080

If the application is an HTTP service, you should receive its response through the tunnel.

You can also check whether the remote port is listening:

ss -lnt

Look for port 8080 in the output. If it is missing, the forwarding request may have failed, the connection may have ended, or the port may not have been created as expected.

Step 4: Understand Where the Forwarded Port Is Accessible

In the example above, the remote listener normally binds to loopback. That means you can test it from the remote server itself using 127.0.0.1:8080, but another computer cannot automatically reach it using the remote server’s public IP address.

This default is useful because it limits exposure.

If your goal is to let other authorized machines connect to the forwarded service, you need to configure the remote bind address and server-side SSH forwarding policy appropriately. You must also review the server firewall and restrict access to trusted clients.

Do not change the listener to a public interface unless you understand the consequences and have protected the service.

How to Create a Reverse SSH Tunnel for Remote Administration

You can use the same method to forward an SSH connection back to the source machine.

Suppose the source machine runs an SSH server on port 22, but it does not accept direct incoming connections from your administration computer. You can forward port 2222 on the remote server back to port 22 on the source machine.

Run this command on the source machine:

ssh -N -R 2222:127.0.0.1:22 tunneluser@your-server-ip

Here, tunneluser is the account on the remote server that establishes the tunnel. The SSH service on the source machine must also be running and configured to accept the intended login.

From the remote server, connect to the forwarded port:

ssh -p 2222 localuser@127.0.0.1

Replace localuser with a valid account on the source machine.

The second SSH connection travels through the reverse tunnel and authenticates against the SSH service on the source machine. Use an authorized account and key, and avoid enabling unnecessary access for the tunnel user.

This configuration is useful for controlled administration, but the tunnel should be monitored and kept active only for as long as needed.

How to Keep an SSH Reverse Tunnel Running

An SSH reverse tunnel normally ends when the SSH session terminates. If the terminal closes, the network connection drops, or the source machine restarts, the tunnel may stop working.

For a temporary task, leaving the SSH session open is often enough. For a longer-running setup, use a method that can detect and recover from connection failures.

Use SSH Options to Detect Forwarding Failures

You can add ExitOnForwardFailure to make SSH exit if it cannot establish the requested forwarding:

ssh -N \
  -o ExitOnForwardFailure=yes \
  -R 8080:127.0.0.1:3000 \
  user@your-server-ip

This helps detect cases where SSH authentication succeeds but the requested remote port forward cannot be established.

It does not guarantee that the tunnel will remain connected forever. A later network failure can still interrupt the session.

Use a Supervised Service for Long-Running Tunnels

For a persistent tunnel, a systemd service or a tool such as autossh can help monitor the connection and restart it when necessary. Configure the service to use SSH keys, appropriate permissions, and a deliberate restart policy.

Before deploying an automated tunnel, test the command manually. Confirm that it connects, forwards the intended port, and stops cleanly when required.

Avoid storing SSH passwords in scripts. Use key-based authentication and restrict the tunnel account to the minimum permissions needed.

SSH Reverse Tunnel vs. Local Port Forwarding

Both reverse and local SSH port forwarding carry traffic through an encrypted SSH connection, but they create listeners on different sides of the connection.

FeatureSSH reverse tunnel (-R)Local port forwarding (-L)
Listening portNormally created on the remote serverNormally created on the local client
Main purposeMake a source-side service reachable through a remote serverAccess a remote-side service through a local port
Typical use caseReach a machine behind a firewallAccess a private service through an SSH server
Connection directionSSH starts from the source machine to the remote serverSSH starts from the client to the remote server
Common examplessh -R 8080:127.0.0.1:3000 user@serverssh -L 8080:127.0.0.1:3000 user@server

With local forwarding, the 127.0.0.1:3000 destination is interpreted from the remote server’s perspective. With the reverse-forwarding example, the destination is interpreted from the source machine’s perspective.

Choosing the right option depends on which machine can initiate the SSH connection and where you need the listening port to appear.

Common SSH Reverse Tunnel Errors and Fixes

A reverse tunnel can fail because of SSH configuration, network restrictions, an occupied port, or an unavailable destination service. Check the error and verify each part of the connection before changing server settings.

Error or symptomLikely causeWhat to do
remote port forwarding failedPort is occupied or forwarding is deniedChoose an available port and check server policy
Connection refusedSSH server or destination service is not listeningVerify the relevant service and address
Permission deniedSSH authentication failedCheck the username, key, and account permissions
Tunnel connects but application is unreachableWrong destination address or portTest the destination locally on the source machine
Tunnel stops unexpectedlyNetwork interruption or process terminationReview SSH logs and use a supervised connection if needed
Remote port is not reachable externallyListener is bound to loopbackKeep it private or configure controlled access deliberately

Fix a Remote Port Forwarding Failure

If SSH reports that remote port forwarding failed, first check whether another process is using the requested port on the remote server:

ss -lnt

If the port is already occupied, select another available port and retry.

If the port is free but forwarding still fails, inspect the SSH server configuration. The AllowTcpForwarding, DisableForwarding, PermitListen, and GatewayPorts settings can affect which forwarding requests are allowed and where listeners can bind.

Do not enable unrestricted forwarding just to make the error disappear. Apply the narrowest policy that supports the intended use case.

Fix a Connection Refused Error

A connection refused error often means that the destination service is not listening at the specified address and port.

On the source machine, test the application directly:

curl http://127.0.0.1:3000

If that request fails, investigate the application or its listener configuration before troubleshooting SSH. If it works locally but fails through the tunnel, check the SSH session, remote listener, and forwarding request.

Investigate an Unexpected Disconnect

For more detail, run SSH in verbose mode:

ssh -v -N \
  -R 8080:127.0.0.1:3000 \
  user@your-server-ip

The output can help identify authentication issues, forwarding failures, and connection interruptions.

Also review network stability, server logs, and any idle-connection policies that might affect the session. Use -vv or -vvv only when more detailed debugging is needed, and avoid sharing logs publicly without reviewing them for sensitive information.

How to Secure an SSH Reverse Tunneling

A reverse tunnel can provide useful remote access, but it also creates a path to a service that may otherwise be unreachable. Security should be part of the setup, not something added after the tunnel is working.

Use SSH Key Authentication

Use a dedicated SSH key for the tunnel where practical. Protect the private key, limit access to it, and remove credentials that are no longer needed.

Key-based authentication reduces reliance on passwords, but a key should not grant more access than the tunnel requires.

Keep the Listener Private by Default

OpenSSH normally binds remote forwarded ports to loopback addresses. Keep that default when you only need to access the service from the remote server itself.

If other systems need access, restrict the listening address and network access deliberately. Avoid opening a forwarded application port to the entire internet unless there is a clear requirement and appropriate protections are in place.

Restrict SSH Forwarding Permissions

Server administrators can control remote forwarding through SSH server configuration. Depending on the intended setup, settings such as AllowTcpForwarding, PermitListen, and GatewayPorts determine whether forwarding is allowed and which listening addresses or ports are available.

A dedicated tunnel account with limited permissions is safer than using a powerful administrator account for every tunnel.

Monitor Access and Disconnect Unused Tunnels

Review SSH logs and monitor long-running tunnel processes. If a tunnel is no longer needed, close the SSH session and remove any temporary access rules that were created for it.

For general SSH hardening practices, see CyberPanel’s Linux hardening guide.

For the full list of SSH client and server options, refer to the official OpenSSH manual and SSH server configuration manual.

Frequently Asked Questions

What does ssh -R do?

The -R option requests remote port forwarding. It creates a listening port on the remote SSH server and forwards connections through the SSH session to a destination reachable from the machine that initiated the connection.

Is a reverse SSH tunnel secure?

SSH encrypts the traffic carried through the tunnel, but the overall setup still depends on authentication, forwarding permissions, listener exposure, and the security of the destination service. Keep access restricted and use the least privilege necessary.

What is the difference between reverse tunneling SSH and a VPN?

A reverse SSH tunnel forwards selected TCP ports through an SSH connection. A VPN typically provides broader network connectivity between authorized devices or networks. A reverse tunnel may be sufficient for one service, while a VPN may be more appropriate for ongoing access to multiple internal resources.

Conclusion

An SSH reverse tunnel provides a practical way to access a service on a machine that cannot accept direct incoming connections. With the ssh -R option, you can forward a port through a reachable server without opening a direct incoming connection to the source machine.

Start by verifying that the local service works, create the tunnel, and test the remote listener. If the tunnel fails, check the port, SSH permissions, destination address, and network connection. For persistent use, configure supervised reconnection and limit access to the intended users.

A well-configured reverse tunnel can simplify remote administration and troubleshooting while keeping access controlled.

Leave a Reply

Your email address will not be published. Required fields are marked *

Chat on WhatsApp