Set Up a Reverse SSH Tunnel

By Raman Kumar

Updated on Sep 16, 2024

In this tutorial, we'll explain how to set up a Reverse SSH Tunnel for secure remote access.

A Reverse SSH Tunnel is a secure method used to create a connection from a remote server back to your local machine, allowing you to access services or resources on the local machine from a remote location. This technique is particularly useful when the local machine is behind a firewall or NAT (Network Address Translation) and cannot be directly accessed from the outside world.

This method is often used when you need to connect to a device that does not have a public IP address, such as IoT devices, home servers, or devices in restricted networks.

In a typical SSH connection, the client (local machine) initiates the connection to the server. However, in a reverse SSH tunnel, the client sets up a tunnel where the server can connect back to the client through a specified port. This setup enables remote access to services running on the local machine by forwarding a port from the local machine to a port on the remote server.

For example, if you have a web server running on your local machine on port 8080, but your machine is behind a firewall and you need to access it remotely, you can use a reverse SSH tunnel to forward this port to a port on the remote server. By connecting to the remote server's forwarded port, you effectively connect to the local web server as if it were directly accessible.

Reverse SSH tunnels are commonly used for remote support, accessing home or office networks while traveling, and securely managing devices in restricted networks. The connection is encrypted and secured using SSH, ensuring that data transmitted through the tunnel is protected.

Prerequisites

  • Remote Dedicated Server or KVM VPS (Publicly Accessible): A server with a public IP address and SSH access.
  • Local Machine: The machine you want to access remotely, which might be behind a firewall or NAT.
  • SSH Installed: SSH must be installed on both the remote server and the local machine.

Step 1: Verify SSH Installation

Before setting up the reverse SSH tunnel, ensure that SSH is installed and running on both the local machine and the remote server.

On the local machine:

ssh -V

On the remote server:

ssh -V

If SSH is not installed, you can install it using the following commands:

On Ubuntu/Debian:

sudo apt update
sudo apt install openssh-server
 

On CentOS/RHEL:

sudo yum install openssh-server

Step 2: Generate SSH Keys (Optional but Recommended)

For secure and password-less authentication, it is recommended to generate an SSH key pair on the local machine.

Generate SSH key:

ssh-keygen -t rsa -b 4096

Copy the public key to the remote server:

ssh-copy-id user@remote_server_ip

Replace user@remote_server_ip with the actual username and IP address of your remote server.

Step 3: Configure firewall

We need to add the ports in the firewall. Add it in both the local machine and the remote server.

ufw add 8080/tcp
ufw add 9000/tcp
ufw reload

Note: You need to add the ports that you want to use. 

Step 4: Enable GatewayPorts on the Remote Server

If the remote server is not allowing connections to the forwarded port, you may need to enable GatewayPorts in the SSH configuration.

Edit SSH Configuration:

sudo nano /etc/ssh/sshd_config

Add or Modify the Line:

GatewayPorts yes

Restart SSH Service:

sudo systemctl restart sshd

Step 5: Create the Reverse SSH Tunnel

Now, you'll create the reverse SSH tunnel from the local machine to the remote server. The command structure is as follows:

ssh -R remote_port:localhost:local_port user@remote_server_ip
  • remote_port: The port on the remote server that will forward the connection.
  • localhost: Specifies that the connection should be forwarded to the local machine.
  • local_port: The port on the local machine that you want to access.
  • user@remote_server_ip: The SSH login for the remote server.

Example: If you want to access port 8080 on your local machine via port 9000 on the remote server, use:

ssh -R 9000:localhost:8080 user@remote_server_ip

Step 6: Access the Local Service via the Remote Server

Once the reverse SSH tunnel is established, you can access the service running on the local machine via the remote server's IP and the specified remote_port.

Example: If you tunneled port 8080 to port 9000 on the remote server, access the local service by navigating to:

http://remote_server_ip:9000

Step 7: Automate the Reverse SSH Tunnel (Optional)

To ensure that the reverse SSH tunnel is always available, you can automate it using tools like autossh or by adding the command to a script or cron job.

Install autossh:

sudo apt install autossh

Create a script:

#!/bin/bash
autossh -M 0 -f -N -R 9000:localhost:8080 user@remote_server_ip

Make the script executable:

chmod +x reverse_ssh_tunnel.sh

Add the script to cron (optional):

crontab -e

Add the following line to run the script at reboot:

@reboot /path/to/reverse_ssh_tunnel.sh

Troubleshooting

If you encounter issues:

  • Verify SSH Connectivity: Ensure that SSH is working correctly between the local machine and the remote server.
  • Check Firewall Settings: Make sure that the ports used in the reverse SSH tunnel are open on both the local machine and the remote server.
  • Use Debug Mode: Add the -v flag to the SSH command for verbose output to help diagnose any issues.
  • ssh -v -R 9000:localhost:8080 user@remote_server_ip

Conclusion

Setting up a reverse SSH tunnel is a practical solution for secure remote access to devices behind firewalls or NAT. By following this guide, you can establish a secure connection, enabling remote access to services running on your local machine.