← Back to all notes

SSH Flags for Tunneling

#ssh #bash

-L

Creates an ssh tunnel between the local and remote hosts that binds to the local port and forwards TCP connections through the remote to the port specified.

Here's an example in action.

ssh -L 0.0.0.0:9000:10.0.0.100:5432 tony@remoteHost

How I like to think of this is...

  • First section: what interface/port to listen on
  • Second section: what host/port to forward to

We are locally binding to all interfaces 0.0.0.0 on port 9000 and any TCP connections that hit that port are forwarded through our SSH connection to the address 10.0.0.100 on port 5432.

This is really useful if you need access to something that your remote host can reach, without opening up ports to the outside world. Or having to setup a VPN between the two networks.


-R

Same concept as -L but instead of binding locally, we are binding on the remote end and sending connections back through our local host.

ssh -R 0.0.0.0:9000:localhost:8080 tony@remoteHost

Remote bind on all remote interfaces on port 8080 and any TCP connections that hit that remote port are forwarded through our SSH connection to our localhost port 8080.


-D

This sets up a SOCKS proxy (aka dynamic port forwarding).

What I like to use this for is to quickly route traffic from a web browser like Firefox through a remote host via an SSH connection.

ssh -D 9000 tony@remoteHost

SSH locally will bind on port 9000 and forward any SOCKS requests through the connection and out the remote host's network connection. In this example I omit an interface, so by default ssh will only bind on localhost (aka local-loopback).

Using Firefox you can adjust your proxy settings to use a SOCKS proxy. Enter localhost and port 9000 (in my example) and also enable sending DNS requests through the SOCKS proxy as well.

Note: you will need to set GatewayPorts clientspecified on your remote host to allow dynamic proxies like SOCKS.


-J (ProxyJump)

Using the -J flag tells ssh to ProxyJump by first making a connection through the "jump host" and then connecting to the target host from there.

I've used this many times while setting up persistent SSH tunnels and only having them listen on the local-loopback address. Securing my tunnels this way means I don't need to have them listen on all interfaces 0.0.0.0, requiring connections to come only from the sshd daemon they are connected to.

ssh -J tony@proxyHost tony@127.0.0.1:9000

SSH will first connect to proxyHost and then to port 9000 on the local-loopback interface inside of proxyHost. I would already have a persistent SSH tunnel setup inside of proxyHost on port 9000 before running a command like this.