Master OpenSSH Port Forwarding: Local, Remote & Dynamic Tunnels Explained
Learn how to use OpenSSH for local, remote, and dynamic port forwarding, including command syntax, practical scenarios, configuration tips, and methods to keep connections alive, enabling secure access to internal services across NAT and firewalls.
Before reading this article, understand what OpenSSH is.
Quick link: OpenSSH 的发展脉络,背后的故事你知道吗?
SSH's core purpose is remote login and secure communication; port forwarding is a part of it, allowing traffic to be securely tunneled from one port to another for specific network traversal needs.
Port Forwarding Usage Scenarios
Assumptions:
Local host internal IP: 192.168.1.10
Remote host public IP: 23.25.26.99, internal IP: 171.71.168.9, login user: user
Local Port Forwarding
Accessing a port on the local host is equivalent to accessing a port on the remote host, useful for debugging remote services by forwarding local requests to the remote server's internal services.
# Format (similar to TCP specification)
ssh -f -N -C -L <localIP>:<localPort>:<remoteHostLocalIP>:<remotePort> [email protected]
# Example
ssh -f -N -C -L 192.168.1.10:7788:localhost:8877 [email protected]
# Bind to all local IPs
ssh -f -N -C -L 7788:localhost:8877 [email protected]Explanation of -f and -N: -f: Run the connection in the background. -N: Do not execute remote commands, only forward ports. -C: Compress data.
All port‑forwarding commands should include -f and -N.
The term “local host” refers to any machine on the same network, and the remote host can bind all its internal IPs.
Remote Port Forwarding
Remote port forwarding works opposite to local forwarding: accessing the remote side forwards traffic back to the local side, enabling internal‑network penetration.
# Format
ssh -f -N -C -R <remoteHostLocalIP>:<remotePort>:<localIP>:<localPort> [email protected]
# Example
ssh -f -N -C -R localhost:8877:localhost:7788 [email protected]
# Bind to all remote internal IPs
ssh -f -N -C -R 8877:localhost:7788 [email protected]Dynamic Port Forwarding
Dynamic forwarding removes the restriction on a specific remote port, allowing the local machine to access any service on the remote server, effectively acting as a VPN jump host.
# Format
ssh -f -N -C -D <localIP>:<localPort> [email protected]
# Example
ssh -f -N -C -D localhost:7788 [email protected]After configuring, set up a socket proxy (e.g., on macOS) to listen on the local port, so browser traffic is routed through the SSH tunnel.
macOS network configuration example:
Free Combination of Port Forwarding
SSH tunnels act like a green channel between hosts, enabling port forwarding to achieve connectivity.
Example scenario: a home machine cannot reach a corporate internal host.
Configure local port forwarding on the home machine to forward requests to a remote host.
Configure remote port forwarding on the corporate host to forward those requests back to the home machine.
Only one remote host is needed to bridge the networks.
SSH Related Configuration
Prevent Disconnection
When the SSH client runs in the background, idle connections may drop. Add parameters to keep the tunnel alive.
# Add extra parameters
ssh -L localhost:7788:localhost:8877 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 [email protected]Parameter meanings: -o ServerAliveInterval=60: Send a null packet every 60 seconds to keep the connection active. -o ServerAliveCountMax=3: Terminate if three consecutive keep‑alive messages receive no response. TCPKeepAlive=yes: Enable TCP keep‑alive.
These settings can be placed in /Users/user/.ssh/config to avoid typing them each time.
Host example
Hostname 23.25.26.99
User root
ServerAliveInterval 60
ServerAliveCountMax 3
TCPKeepAlive yes # Use the alias
ssh -L localhost:7788:localhost:8877 exampleTo manually close a connection, find the SSH process and kill it:
# Find SSH processes
ps aux | grep ssh
# Force kill the process
kill -9 <pid>For persistent connections, configure a cron job to start the tunnel on boot.
Q&A
Q: How does remote port forwarding locate a NAT‑behind local host?
A: The remote server learns the public IP address of the local machine during the SSH handshake. NAT creates a mapping of the internal IP and port to the public IP and a random external port. When the remote side receives traffic on the forwarded port, it uses this mapping to route the packets back to the correct internal machine.
The NAT router maintains a connection‑tracking table that records each session’s source IP, source port, and the corresponding internal destination, allowing the remote host to forward traffic correctly to the local IP and port.
Lin is Dream
Sharing Java developer knowledge, practical articles, and continuous insights into computer engineering.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
