Remote (-R) and dynamic (-D) forwarding

SSH · Advanced · 10 min

Reverse tunnels and SOCKS proxies solve 'show my local app to a remote host' and 'browse as if I were inside that network'.

Remote forwarding is the mirror of -L: the server listens and forwards connections back to a destination as seen from your machine.

ssh -R 8080:localhost:3000 demo makes port 8080 on demo reach the dev server on your laptop's port 3000. By default the remote listener binds to the server's loopback only; making it reachable from other machines needs GatewayPorts yes (or clientspecified) in the server's sshd_config. Remote forwarding is also how a machine behind NAT can offer a "phone home" tunnel, often kept alive with autossh or a systemd unit.

Dynamic forwarding -D 1080 starts a local SOCKS5 proxy. Each connection an application makes through it is forwarded to whatever destination it asks for, resolved and connected from the server. Point a browser or curl --socks5-hostname localhost:1080 at it to reach internal dashboards as if you were on the server's network. --socks5-hostname (rather than --socks5) makes DNS resolution happen remotely, which internal names need.

Both appear in ~/.ssh/config as RemoteForward and DynamicForward. Server admins control these features with AllowTcpForwarding (and PermitListen / PermitOpen for fine-grained limits).

Example

# share local dev server (port 3000) as port 8080 on the server's loopback
ssh -N -R 8080:localhost:3000 demo.example.com
#   on demo:  curl localhost:8080   -> served by your laptop

# SOCKS proxy through the bastion
ssh -N -D 1080 bastion
curl --socks5-hostname localhost:1080 http://grafana.internal:3000/api/health

# ~/.ssh/config
# Host bastion-proxy
#     HostName bastion.example.com
#     DynamicForward 1080

Remember

  • -R remote_port:dest:port listens on the server, forwards to your side
  • -D port runs a SOCKS5 proxy; use remote DNS resolution
  • GatewayPorts and AllowTcpForwarding control these on the server

Watch out for

  • Expecting -R ports to be reachable from outside the server without GatewayPorts.

Check yourself

  1. You run `ssh -D 1080 bastion` and want curl to resolve internal hostnames on the bastion side. Which option?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: man.openbsd.org/ssh#R

Builds on

Unlocks

Nothing builds on this yet.