Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SSH Reverse Tunnel

Overview

An SSH reverse tunnel exposes a local service to the internet through a VPS. It works by establishing an outbound SSH connection from your local machine to the VPS, which then forwards incoming traffic back through that connection to your local service.

This is useful when you are behind NAT, a firewall, or lack a public IP address.

Architecture

Internet Request
       │
       ▼
┌─────────────────┐
│  VPS (Public)   │
│  nginx :443     │
│       │         │
│       ▼         │
│  localhost:5201 │◄── SSH tunnel listens here
└────────┬────────┘
         │
    SSH Connection
    (outbound from local)
         │
         ▼
┌─────────────────┐
│  Local Machine  │
│  localhost:8080 │◄── Your service
└─────────────────┘

Traffic flow:

  1. Client requests https://<domain>
  2. nginx terminates TLS and proxies to 127.0.0.1:5201
  3. Port 5201 is the remote end of the SSH tunnel
  4. Traffic flows through the tunnel to your local machine on port 8080

Prerequisites

  • VPS setup completed (see VPS Setup)
  • nginx installed and configured (see nginx Setup)
  • A local service running (this guide uses localhost:8080)

Setup

Configure a subdomain with nginx reverse proxy to 127.0.0.1:5201 and enable SSL (see nginx Setup).

SSH Reverse Tunnel Command

From your local machine:

ssh -N -R 5201:localhost:8080 <username>@<vps-ip>
FlagPurpose
-NDo not execute a remote command. Port forwarding only.
-R 5201:localhost:8080Bind remote port 5201 to local port 8080.

Format: -R [remote_port]:[local_host]:[local_port]

The tunnel remains open while the SSH connection is active.

Observability

Stream VPS nginx logs to your local machine:

ssh <username>@<vps-ip> "tail -f /var/log/nginx/access.log" | grep --line-buffered <domain>

Example

# Start local service
npm run dev  # localhost:3000

# Establish tunnel
ssh -N -R 5201:localhost:3000 <username>@<vps-ip>

Access from anywhere: https://<domain>