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

  1. 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.

  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; GatewayPorts and AllowTcpForwarding must allow it.

  3. 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.

Next steps

Continue to