Wednesday, January 17, 2018

SSH tunneling for dummies

Somehow, every time I need to set up an SSH tunnel -- or even figure out whether it's applicable to my problem -- I have to re-learn the concept. And every time, I have to read multiple tutorials, none of which seem to explain very clearly what they are or what they do.

The author of this blog seems to feel the same way, and he does a great job explaining it. I'd like to summarize it here, through examples.

The first thing to understand is that it's a way to open a TCP connection that you normally cannot (because the server or port is blocked by a firewall, for example). Remarkably, almost none of the guides online explain this clearly.

Next: it requires an SSH daemon to be running on a remote machine that you can connect to (which we'll call remote). The local machine will be called local.

There are two modes of use: local (-L) and reverse (-R). Let's look at some examples.

Local mode

This is for when your local machine cannot access something that the remote machine can. So we create a tunnel where a local port can be used to access that something.

ssh -L 9001:yahoo.com:80 remote

This is instructing remote to connect to yahoo.com:80, and make it available via localhost:9001.

ssh -L 2000:localhost:5900 remote

This one is a bit confusing. Here, remote connects to its own localhost:5900, and make that connection available via our localhost:2000. Remember that the bolded TCP address is relative to remote in this mode.

Port 5900 is used for VNC (a way to share desktops). Normally, instead of using port 2000, we'd use 5900. But having two 5900s in the command makes it more confusing, so I've avoided this.

Reverse mode

This is for when your local machine can access something that the remote cannot. This flips around the meaning of the parameters.

For example, if my local machine is on my work intranet, and the remote (at home, say) can access my local machine, I might do this:

ssh -R 9001:intra-site.com:80 remote

Now intra-site.com:80 is relative to the local machine, and 9001 is the port on remote that people will connect to to access it.

Under the hood

What's going on under the hood in the local and reverse cases? Here's my understanding. In both modes, there's a persistent connection between localhost and remote:22 (where its sshd is running).

Local

ssh -L 2000:yahoo.com:80 home

This creates a local process listening on port 2000. When something connects to port 2000, it instructs home to open a connection to yahoo.com:80.

Remote

ssh -R 9001:intra-site.com:80 home

Now home has a process listening on 9001, and whenever something connects there, the local machine opens up a fresh connection to intra-site.com:80.


In either case, there is one connection that remains open (the "tunnel"), and one that opens in response to incoming requests.

No comments:

Post a Comment