SSH Port Forwarding: Local, Remote & Dynamic Guide
Use SSH local, remote, and dynamic port forwarding, then compare a port-forwarding VPN with a public VPS for a reachable service endpoint.
Quick answer
SSH port forwarding carries selected TCP connections inside an encrypted SSH session. Use -L to reach a service near the SSH server, -R to publish a service near you at the SSH server, and -D to create a local SOCKS proxy. When that service needs a public endpoint, Proton VPN, PureVPN, or Private Internet Access can provide an incoming port without server administration; a small VPS gives -R a stable SSH host you control for fixed, long-running reverse tunnels and multiple services.
How SSH tunnel port forwarding works
SSH creates a TCP listener on one side of an authenticated session. A connection accepted by that listener becomes an SSH channel, crosses the encrypted session, and opens a normal TCP connection from the other side. The application does not need to understand SSH; it connects to a local or remote port as usual.
TCP listener
Created by -L, -R, or -D on the selected side
Encrypted SSH session
Carries independent forwarding channels over one login
Final TCP service
Database, web app, SSH, VNC, or another TCP listener
The direction is named after the listener
Local, remote, and dynamic SSH port forwarding
Pick the side that should accept the first connection. Add -N when the session exists only for forwarding and no remote shell is needed.
| Mode | Listener | Destination is reached from | Best for |
|---|---|---|---|
-L Local port forwarding | Your SSH client | Reached from the SSH server | Private databases, dashboards, and services behind a bastion |
-R Remote port forwarding | The SSH server | Reached from your SSH client | Publishing a local service through a reachable SSH server |
-D Dynamic port forwarding | Your SSH client | Chosen by each SOCKS-aware application | Browsing or tools that support a local SOCKS proxy |
Local port forwarding
ssh -N -L 127.0.0.1:5433:db.internal:5432 user@bastionPrivate databases, dashboards, and services behind a bastion
Remote port forwarding
ssh -N -R 8080:127.0.0.1:3000 user@serverPublishing a local service through a reachable SSH server
Dynamic port forwarding
ssh -N -D 127.0.0.1:1080 user@serverBrowsing or tools that support a local SOCKS proxy
SSH port forwarding commands, explained
Local port forwarding with SSH config or -L
This maps local port 5433 to PostgreSQL port 5432 on db.internal. The bastion resolves and connects to the database, so the database can remain private.
ssh -N -L 127.0.0.1:5433:db.internal:5432 user@bastion.example.comSSH remote port forwarding from server to client
This asks the SSH server to listen on port 8080 and sends every accepted connection back to port 3000 on the client side. Without an explicit bind address, OpenSSH normally keeps that listener on server loopback.
ssh -N -R 8080:127.0.0.1:3000 user@server.example.comDynamic port forwarding with SSH
This creates a SOCKS listener at 127.0.0.1:1080. A SOCKS-aware browser or tool supplies each destination; SSH opens those connections from the server. Keeping the listener on loopback prevents other LAN devices from using the proxy unintentionally.
ssh -N -D 127.0.0.1:1080 user@server.example.comVPN port forwarding or a VPS for a public SSH endpoint
A port-forwarding VPN gives the connected computer an inbound path at the VPN gateway. Outside clients use the VPN server address and forwarded port, and the provider carries that connection through the encrypted VPN tunnel to the service on the device, without requiring you to administer a cloud server. A VPS remains the better match when the endpoint itself must run OpenSSH and accept persistent -R forwards.
| Decision | Port-forwarding VPN | VPS + SSH -R |
|---|---|---|
| Fastest path to one service on this device | Install the VPN app, enable its incoming port, and point the SSH or TCP listener at that port. | Useful when that service must be reached through an actual remote SSH host rather than a VPN gateway mapping. |
| Public address and port | Clients use the VPN server address plus the provider-assigned or selected forwarded port. | Clients use the VPS public address and a port you choose in the -R command and VPS firewall. |
| Connection management | The provider app maintains the encrypted VPN connection and publishes the active port. | OpenSSH, systemd, or autossh maintains a long-running session to a server account you control. |
| Best growth path | A direct, low-administration route for a service on the connected computer. | A reusable endpoint for several reverse forwards, stable hostnames, and services from other private devices. |
Compare Proton VPN, PureVPN, and Private Internet Access
All three can create an incoming path through a VPN server. Choose by how the public port is assigned and how much control the service needs over that port.
| Provider | Port model | Best fit |
|---|---|---|
| Proton VPN | A paid P2P connection assigns an active incoming port; the Windows, macOS, and Linux apps display it. | The simplest included port-forwarding option when the application can follow the active port. |
| PureVPN | Its optional Port Forwarding add-on lets the account enable specific ports on supported connections. | Users who want to choose the SSH or application port, with a dedicated-IP bundle available for a consistent address. |
| Private Internet Access | A supported server region assigns an incoming port; the desktop app and CLI expose the current value. | Users who value open-source clients and want the assigned port available to scripts or another listener. |
Proton VPN
- 100M+ Proton accounts across its privacy ecosystem
- Five consecutive annual independent no-logs audits
- Open-source VPN apps with publicly reviewable code
- 30-day refund window for eligible paid-plan purchases
PureVPN
- 3M+ users and 17 years in cybersecurity
- Fourth consecutive independent no-log assessment
- ISO 27001-certified information security program
- 31-day refund window for eligible initial purchases
Private Internet Access
- 10+ years in the VPN market
- Open-source desktop and mobile applications
- Third independent Deloitte no-logs review
- 30-day refund window for eligible purchases
Affiliate disclosure: We may earn a commission when you purchase through links on this page, at no extra cost to you.
Build a public reverse SSH tunnel with a VPS
Publishing a service with a router rule ties access to one router, one local device address, and the current public IP. A reverse tunnel removes those moving parts: the private device starts SSH outbound, while the public listener lives on a VPS with a stable address.
The old path keeps breaking
- The router rule must keep pointing at the device and application listener.
- A changing home IP invalidates bookmarks and client configuration.
- Moving the device to another network breaks the router-specific setup.
- An ISP static-IP add-on fixes the address, but only for that one connection.
One VPS becomes the reusable endpoint
- One stable public IP remains valid when the private network changes.
- Home and mobile networks need only outbound SSH access.
- Several reverse ports can share the same encrypted SSH session.
- The VPS firewall exposes only the TCP services meant for outside clients.
Want to compare the router-based path before choosing a VPS? Start with the public IP address guide and the troubleshooting steps for port forwarding that is not working. A VPS avoids depending on the router rule by moving the public listener to the server.
ssh -N -R 0.0.0.0:8080:127.0.0.1:3000 tunnel@vps.example.comWhat must be public
How to set up SSH port forwarding on a public server
This setup publishes one local TCP service through the VPS. Change ports and hostnames to match the service, then reuse the same SSH host entry for additional forwards.
- 1
Deploy a small VPS with a public IP
Choose a region near the people connecting and install a current Ubuntu or Debian image. One shared-CPU instance is enough for an SSH control channel and ordinary administration traffic; size transfer for media or large downloads.
- 2
Create a dedicated SSH key
Generate an Ed25519 key on the device that will maintain the tunnel, add only its public key to the VPS account, and keep the private key on that device.
- 3
Allow the required forwarding mode
Set AllowTcpForwarding yes in sshd_config. If other internet clients must reach a reverse-forwarded port, add GatewayPorts clientspecified, restart sshd, and allow that one TCP port in the VPS firewall.
- 4
Start the reverse SSH tunnel
Run ssh -N -R 0.0.0.0:8080:127.0.0.1:3000 tunnel@vps.example.com from the private device. Connections to VPS port 8080 now travel through SSH to the local service on port 3000.
- 5
Make failure visible and keep the session alive
Add ExitOnForwardFailure yes, ServerAliveInterval 30, and ServerAliveCountMax 3 to the SSH host entry. Run the command as a systemd user service or with autossh so a network change starts a fresh session.
- 6
Test the service through the VPS address
Connect from another network to the VPS address and published port. The SSH client must stay connected; the VPS listener and local application listener should both match the addresses used in the command.
VPS options for a stable SSH remote forward
The functional value is the same: a reachable address outside the private network. Choose Vultr for the broadest default region choice; put DMIT first only when China or East Asia routing is the deciding factor.
Vultr
A broad region choice for placing the public endpoint near its users.
DMIT
A focused network option when the tunnel crosses East Asia or mainland China.
Need several private services rather than one public TCP listener? The remote access without port forwarding guide shows a whole-device and whole-LAN hub design on the same kind of VPS.
SSH config for keys, keepalives, and automatic restarts
A named host keeps the command short and gives a service manager an unambiguous success or failure signal. The remote listener below is public because its job is to accept outside connections at the VPS.
Host home-app-via-vps
HostName 203.0.113.10
User tunnel
IdentityFile ~/.ssh/id_ed25519
RemoteForward 0.0.0.0:8080 127.0.0.1:3000
ServerAliveInterval 30
ServerAliveCountMax 3
ExitOnForwardFailure yesDedicated key
Separates the unattended tunnel from administrator logins.
Keepalive
Detects a dead route instead of leaving a silent half-open session.
Service restart
systemd or autossh starts a fresh tunnel after a real network change.
SSH port forwarding not working: match the error to the fix
Start SSH once with -v. The message usually separates a listener failure, an SSH policy denial, and a final application refusal. For router-based paths, use the closed-port troubleshooting sequence.
| Symptom | What it means | Direct fix |
|---|---|---|
| bind: Address already in use | Another process already owns the listener port. | Choose a free bind port or stop the old tunnel. On Linux, use ss -lntp to identify the listener. |
| open failed: connect failed: Connection refused | SSH created the tunnel, but the final service is not listening at the host and port in the command. | Point the destination at the application listener—for example 127.0.0.1:3000—not at the tunnel port. |
| administratively prohibited | The SSH server policy denied forwarding. | Set AllowTcpForwarding yes for the tunnel account and remove a conflicting Match block or authorized-key restriction. |
| Remote forward works only on the VPS | The remote listener is bound to the VPS loopback address. | Use GatewayPorts clientspecified and request 0.0.0.0:PORT or the VPS public address in the -R specification. |
| Tunnel disappears after an idle period | A NAT device or broken link removed the idle session. | Add ServerAliveInterval 30, ServerAliveCountMax 3, and an automatic service restart. |
| SSH stays open after a forward fails | The shell session survived even though SSH could not create the listener. | Add ExitOnForwardFailure yes so the process exits and the service manager can restart it cleanly. |
Fast listener check
ss -lnt on the listener side. A local forward should appear on the SSH client; a remote forward should appear on the SSH server.SSH port forwarding FAQ
SSH forwarding specifications and manuals
Command behavior and server policy in this guide follow the OpenSSH manuals and the SSH connection protocol.