SSH Tunneling
Three different things, all named “SSH tunnel”:
-Llocal forward: a port on this machine is forwarded to a host:port as seen from the SSH server.-Rremote forward: a port on the server is forwarded back to a host:port as seen from this machine.-Ddynamic forward: a local SOCKS proxy. Applications send traffic through the SSH server.
In -L and -R, the middle hostname is resolved on the side that makes the onward connection, not on your laptop. That is the part most copy-paste snippets get wrong.
Local port forwarding (-L)
Syntax: ssh -L [bind:]local_port:destination:dest_port user@ssh-server. destination is reached from the SSH server. localhost there means the server itself, not your laptop.
| Scenario | Command | Explanation |
|---|---|---|
| Remote web server on the SSH host | ssh -L 8888:localhost:80 [email protected] | http://127.0.0.1:8888 is port 80 on the SSH server. |
| Database on a host only the jump box can see | ssh -L 5432:db.internal:5432 [email protected] | Your local client talks to 127.0.0.1:5432; the jump box connects to db.internal:5432. |
| Two forwards in one session | ssh -L 8080:localhost:80 -L 8443:localhost:443 [email protected] | Both destinations are on the SSH server. |
| Background, no shell | ssh -fN -L 8000:localhost:80 [email protected] | -f backgrounds after auth; -N skips a remote command. |
Remote port forwarding (-R)
Syntax: ssh -R [bind:]remote_port:destination:dest_port user@ssh-server. destination is reached from your local machine. By default the remote port is bound to loopback on the server only.
| Scenario | Command | Explanation |
|---|---|---|
| Expose a local app to the server | ssh -R 8080:localhost:3000 [email protected] | On the server, http://127.0.0.1:8080 is your laptop’s port 3000. Other hosts on the server’s network cannot use it yet. |
| SSH back to this machine | ssh -R 2222:localhost:22 [email protected] | From the server: ssh -p 2222 localhost. |
| Listen on all interfaces of the server | Set GatewayPorts clientspecified (or yes) in the server’s sshd_config, reload sshd, then ssh -R 0.0.0.0:8080:localhost:3000 [email protected] | Anyone who can reach the server’s IP on 8080 hits your local port 3000. That is an inbound hole; do not leave it open. |
Dynamic forwarding / SOCKS (-D)
OpenSSH implements SOCKS4 and SOCKS5 on the local port. Point the application at that port; it does not magically proxy the whole OS.
| Scenario | Command | Explanation |
|---|---|---|
| SOCKS on 1080 | ssh -D 1080 [email protected] | Browser/proxy setting: SOCKS5 host 127.0.0.1 port 1080. Enable proxy DNS in the browser so lookups happen on the far side. |
| Background | ssh -fN -D 1080 [email protected] | Same proxy, no shell. |
| Compression | ssh -C -D 1080 [email protected] | -C helps on slow links for text; it can hurt already-compressed data. |