Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild

SSH Tunnel: Local and Remote Port Forwarding, and SOCKS Proxy

Sean

Platform Writer

Jul 05, 2026
6 min read

SSH tunnel (port forwarding) routes TCP traffic through an encrypted SSH connection. ssh -L is local forward (expose a remote service to local), ssh -R is remote forward (expose a local service to remote), ssh -D is a SOCKS proxy. The team that uses tunnels has secure access to internal services through a bastion, without exposing them to the public internet.

SSH Tunnel: Local and Remote Port Forwarding, and SOCKS Proxy

Table of contents

Local port forwarding (-L)

Forward a remote port to local:

ssh -L 8080:internal.example.com:80 [email protected]

Now localhost:8080 connects to internal.example.com:80 through the bastion. The team that uses this accesses internal web UIs from a laptop without VPN.

Remote port forwarding (-R)

Forward a local port to remote:

ssh -R 8080:localhost:3000 [email protected]

Now public.example.com:8080 connects to the local machine’s localhost:3000. The team that uses this exposes a local dev server to a public-facing machine (for sharing a demo).

SOCKS proxy (-D)

Use SSH as a SOCKS proxy:

ssh -D 1080 [email protected]

Configure your browser to use SOCKS5 proxy localhost:1080. The team that uses this routes browser traffic through the bastion.

Database access through bastion

Common pattern:

ssh -L 5432:db.internal.example.com:5432 user@bastion
psql -h localhost -U app -d appdb

The team that uses this accesses internal databases without exposing them. The team that has the database on a public subnet has a security incident.

Background tunnels

For long-running tunnels, use -fN:

ssh -fN -L 5432:db.internal:5432 user@bastion

-f backgrounds after auth, -N doesn’t open a shell. The team that uses this has tunnels that survive shell exits.

SSH config for tunnels

Define tunnels in ~/.ssh/config:

Host bastion
    HostName bastion.example.com
    User myuser

Host db-tunnel
    HostName db.internal.example.com
    LocalForward 5432 db.internal.example.com:5432
    ProxyJump bastion

Then ssh db-tunnel opens the tunnel. The team that uses ssh-config has reusable tunnels without long CLI flags.

Security considerations

  1. Tunnels bypass network firewalls - audit them.
  2. Use -N if you don’t need a shell.
  3. Use -o ExitOnForwardFailure=yes to ensure the tunnel is actually up.
  4. Restrict who can SSH to bastion (AllowUsers).
  5. Use SSH keys, not passwords, on bastion.

FAQ

What’s the difference between -L and -R?

-L forwards a remote port to local (access remote service from local). -R forwards a local port to remote (expose local service to remote). The team that picks -L for accessing internal services; -R for sharing local dev.

Is SSH tunnel secure?

Yes - the connection is encrypted by SSH. The traffic inside is whatever you put through it. The team that uses tunnels has the same security as SSH itself.

Can I have multiple tunnels in one SSH session?

Yes - ssh -L 8080:a:80 -L 8443:b:443 user@bastion. The team that uses multiple -L flags has fewer bastion sessions.

Why is my tunnel slow?

SSH adds CPU overhead for encryption. The team that uses -c aes128-ctr (faster cipher) trades a bit of security for speed on CPU-limited clients.

Can I use SSH tunnel for Kubernetes API?

Yes - ssh -L 6443:master.internal:6443 user@bastion then kubectl --server=https://localhost:6443. The team that uses this for K8s API access without exposing the API server.

If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.

Useful related references:

#ssh#tunnel#forwarding#dev-infra