keepcalculator

06 Numbers and Powers

Reverse SSH Tunnel: Allow External Connections?

Card No. 06·57823 · Updated · Standard formula, shown below

Yes, a reverse SSH tunnel allows external connections to reach a device that is behind a firewall or NAT, provided the machine you tunnel through has a public IP and accepts the connection. You initiate the tunnel from the internal device to a public server, and then anyone (or just you) can connect to that public server on a chosen port to reach the internal device.

What Problem Does a Reverse SSH Tunnel Solve?

Normally, if you want to SSH into a computer at home or in a remote office, that computer needs a publicly reachable IP address and an open port. Many ISPs assign dynamic IPs, and corporate or home routers use NAT, which blocks inbound connections. A reverse SSH tunnel flips the direction: the device behind the NAT starts an outbound SSH connection to a server you control (one with a public IP). Once that connection is established, the server can forward traffic back through it to the device.

This is useful for:

  • Accessing a home server or Raspberry Pi from anywhere
  • Providing remote support to a client’s machine
  • Bypassing restrictive firewalls that block inbound ports
  • Exposing a local web service to the internet temporarily

How a Reverse SSH Tunnel Works

The command is run on the device that is behind the NAT. The syntax is:

ssh -R [remote_port]:localhost:[local_port] user@public_server

Here’s what each part means:

  • -R tells SSH to create a reverse tunnel.
  • remote_port is the port on the public server that will forward traffic to your device.
  • localhost means the connection will be forwarded to the device itself (you can also specify another host on your LAN).
  • local_port is the port on your device that you want to reach (e.g., 22 for SSH, 80 for a web server).
  • user@public_server is your account on the public server.

Once the tunnel is up, anyone can connect to public_server:remote_port and be forwarded through the encrypted SSH connection to your device’s local port. For example, if you run ssh -R 2222:localhost:22 user@example.com, then connecting to example.com:2222 will land you on the SSH server of your home device.

Setting Up the Public Server

The public server (the one you SSH into) must allow TCP forwarding. In the SSH server configuration file (/etc/ssh/sshd_config), ensure the following lines are present and not commented out:

GatewayPorts yes
AllowTcpForwarding yes

GatewayPorts is crucial if you want the tunnel to be accessible from the internet, not just from the server itself. By default, a reverse tunnel binds only to the server’s loopback interface (127.0.0.1), meaning only the server can reach it. Setting GatewayPorts yes makes the tunnel listen on all interfaces, so external clients can connect. If you cannot change that setting, you can still use the tunnel by connecting to localhost:remote_port on the server, but that’s only useful if you also SSH into the server first.

After editing the config, restart the SSH service: sudo systemctl restart sshd (on most Linux distributions).

Keeping the Tunnel Alive

A single SSH command will close when the connection drops. To keep the tunnel running, you can use autossh, a tool that automatically restarts the tunnel if it fails. A typical autossh command looks like:

autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -N -R 2222:localhost:22 user@public_server

Here, -M 0 disables autossh’s built-in monitoring (it uses SSH keepalives instead), and the ServerAliveInterval options send a keepalive every 30 seconds to detect dead connections. The -N flag tells SSH not to execute a remote command (just forward ports).

For a permanent solution, you can set up a systemd service or a cron job with @reboot to launch autossh automatically. Many users also set up SSH keys so the tunnel can start without a password prompt.

Security Considerations

Exposing a port on your local device to the internet is a double-edged sword. It gives you convenient access, but it also opens a door for attackers. Here are essential precautions:

  • Use strong authentication: Enable SSH key authentication on your device and disable password logins.
  • Change the default port: Use a non-standard remote port (e.g., 2222 instead of 22) to reduce automated scans.
  • Restrict access: On the public server, use firewall rules to allow only specific IP addresses to connect to the forwarded port.
  • Limit the tunnel: If you only need SSH, forward port 22. Don’t expose a web server or database unless absolutely necessary.
  • Use a jump host: Instead of exposing the tunnel directly to the internet, you can SSH into the public server first, then connect to localhost:remote_port from there. This way, the tunnel is only accessible to users who have an account on the server.

Also be aware that the public server operator (if it’s not you) can see and possibly intercept the traffic, even though it’s encrypted end-to-end. The tunnel is only as trustworthy as the server you connect through.

Common Pitfalls and Troubleshooting

Several issues can prevent a reverse tunnel from working:

  • GatewayPorts not set: If you can connect from the server but not from the internet, this is the most likely cause.
  • Firewall on the public server: The remote port must be open in the server’s firewall (e.g., ufw allow 2222).
  • Local service not listening: Verify that the service on your device is actually running and listening on the specified port (e.g., ss -tlnp on Linux).
  • SSH config on the client: Some SSH clients have AllowTcpForwarding disabled by default. On the device initiating the tunnel, check /etc/ssh/ssh_config for AllowTcpForwarding yes.
  • NAT on the public server: If the server itself is behind a NAT, the remote port won’t be reachable from outside.

To test, first try connecting to localhost:remote_port on the public server. If that works but external connections don’t, the issue is almost certainly GatewayPorts or the server’s firewall.

Alternatives to Reverse SSH Tunnels

Reverse SSH is not the only way to reach a device behind NAT. Depending on your needs, consider:

  • VPN (WireGuard, OpenVPN): A VPN creates a secure network overlay, allowing you to access all services on the remote network, not just one port. It’s more robust but requires more setup.
  • Port forwarding on your router: If you control the router and have a public IP, you can forward a port directly to your device. This is simpler but exposes the device to the internet and doesn’t work with carrier-grade NAT.
  • Dynamic DNS: If your IP changes, a DDNS service can give you a stable hostname. Combine with port forwarding for a full solution.
  • Cloud-based tunneling services (e.g., ngrok, Cloudflare Tunnel): These services provide a public URL that forwards to your local port, often with built-in authentication. They are easy to set up but introduce a third party.
  • SSH over a jump host: If you already have SSH access to a public server, you can use ProxyJump to hop through it, but that still requires a reverse tunnel if the target is behind NAT.

Frequently Asked Questions

Can I use a reverse SSH tunnel to expose a web server?

Yes, you can. Instead of forwarding port 22, forward port 80 (or 443) to your local web server. For example, ssh -R 8080:localhost:80 user@server makes your web server available at server:8080. However, if you want to use standard ports (80/443) and have a domain name, you’ll need to run the SSH command with root privileges on the server and set GatewayPorts yes.

Do I need a public IP on the device behind NAT?

No, that’s the whole point. The device only needs outbound internet access (which it has through NAT). The public server is the one with a public IP.

What if the SSH connection drops?

Use autossh or a similar tool to automatically restart the tunnel. You can also set up a systemd service with Restart=always to keep it alive.

Is a reverse SSH tunnel secure?

The traffic is encrypted with SSH, so it’s secure in transit. However, the security of the exposed port depends on the authentication and firewall rules you set. Always use key-based authentication and restrict access to specific IPs if possible.

Can I create multiple reverse tunnels in one command?

Yes, you can specify multiple -R flags. For example, ssh -R 2222:localhost:22 -R 8080:localhost:80 user@server forwards both SSH and HTTP traffic.

What is the difference between a local and a reverse tunnel?

A local tunnel (-L) forwards traffic from your local machine to a remote server, making a remote resource appear local. A reverse tunnel (-R) forwards traffic from a remote server to your local machine, making a local resource appear remote.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →