SSH tunnels explained
Topic: Networking basics
Summary
An SSH tunnel forwards a local or remote port over the SSH connection so you can reach a service as if it were on your machine or expose a local service through the SSH server. Use for one-off secure access to a single port (e.g. DB, admin UI) without a full VPN. Conceptual only; assumes you can SSH to the target host.
Intent: How-to
Quick answer
- Local forward: bind a port on your machine and forward it to a host:port reachable from the SSH server (e.g. ssh -L 8080:internal-host:80 jump). You connect to localhost:8080 and traffic goes through the SSH server to internal-host:80.
- Remote forward: the SSH server binds a port and forwards it to a host:port reachable from your machine (e.g. ssh -R 8080:localhost:80 target). Someone connecting to target:8080 gets forwarded to your local port 80. Often restricted by server config.
- Dynamic (SOCKS): ssh -D 1080 jump gives a local SOCKS proxy; point your app at localhost:1080 to send traffic through the SSH server. Use when you need to reach many hosts via the jump host, not just one port.
Prerequisites
Steps
-
Local port forward
ssh -L LOCAL_PORT:TARGET_HOST:TARGET_PORT SSH_SERVER. Your machine listens on LOCAL_PORT; when you connect to localhost:LOCAL_PORT, SSH sends the stream to TARGET_HOST:TARGET_PORT from the SSH server. Use to reach an internal service (e.g. DB, UI) via a jump host.
-
Remote port forward
ssh -R REMOTE_PORT:LOCAL_HOST:LOCAL_PORT SSH_SERVER. The SSH server listens on REMOTE_PORT and forwards to LOCAL_HOST:LOCAL_PORT from your side. Use to expose a local service through the server; GatewayPorts and AllowTcpForwarding must allow it.
-
Dynamic (SOCKS) proxy
ssh -D 1080 SSH_SERVER. Your machine gets a SOCKS proxy on port 1080; configure apps to use localhost:1080 and their traffic goes through the SSH server. Use when you need to reach many destinations via the jump host.
Summary
SSH can forward ports: local (your port to a host reachable from the server), remote (server port to a host reachable from you), or dynamic (SOCKS proxy through the server). Use local forwards for one-off access to a single service; use dynamic when you need to reach many hosts via the jump host. No full VPN required.
Prerequisites
Steps
Step 1: Local port forward
ssh -L LOCAL_PORT:TARGET_HOST:TARGET_PORT SSH_SERVER. Your machine listens on LOCAL_PORT; connections to localhost:LOCAL_PORT are forwarded to TARGET_HOST:TARGET_PORT from the SSH server. Use to reach an internal service via a jump host.
Step 2: Remote port forward
ssh -R REMOTE_PORT:LOCAL_HOST:LOCAL_PORT SSH_SERVER. The SSH server listens on REMOTE_PORT and forwards to LOCAL_HOST:LOCAL_PORT from your side. Use to expose a local service through the server; server config (GatewayPorts, AllowTcpForwarding) must allow it.
Step 3: Dynamic (SOCKS) proxy
ssh -D 1080 SSH_SERVER. You get a SOCKS proxy on port 1080; point apps at localhost:1080 and traffic goes through the SSH server. Use when you need to reach many destinations via the jump host.
Verification
You can describe local vs remote vs dynamic SSH tunnels and when to use each; you can form a correct ssh -L or -R command for a given scenario.
Troubleshooting
Remote forward not reachable — Server may have GatewayPorts no or AllowTcpForwarding no; bind is often localhost-only. Connection refused on forward — Ensure TARGET_HOST:TARGET_PORT (for -L) or LOCAL_HOST:LOCAL_PORT (for -R) is listening and reachable from the side that originates the forward.