One of the nice features of VNC is that you can reverse a connection. If you are behind a firewall (or a router doing NAT) that doesn't allow incoming connections, VNC allows you to connect to a "listening server". As soon as a connection is established to the listening server, the "listener" gets a regular VNC connection back to the originating box.

Last Friday, I figured out how to do the same thing and reverse a connection with ssh.

I'll lay out the process first, and then talk about the applications and implications afterwards.

The simple approach:

Assume we have two machines. A firewalled server at work and your laptop. You can't connect to the server at work because all incoming connections are blocked by the firewall. So you ask Pete (who is at work and behind the firewall) to login to the server and then ssh to your laptop with the following command:

ssh -f -N -R 10000:localhost:22 username@ip_address_of_laptop

This creates an ssh connection from the work machine to the laptop. the -f and -N are basically cosmetic options. The -R 10000:localhost:22 option causes the laptop to listen on port 10000 and forward any requests on that port to the work machine (this is basically ssh tunneling).

So now, you can ssh to port 10000 on your laptop and you will actually be sshing to port 22 on the firewalled server:

ssh username@localhost -p 10000

(you will have to use your username and password for the server - despite it looking like you are logging onto localhost)

An ugly but effective hack to get rid of Pete:

To get rid of Pete you could setup a cron job on the server that attempts to connect to your laptop every hour. You would have to setup passwordless logins (using public_key authentication), but then you would know that if you needed to get on the server you could just make sure your laptop was on and willing to receive an ssh connection at the right time. Using www.dyndns.org would help you handle changing IP addresses on your laptop.

A better approach:

If you have access to a machine that is always on and outside of the firewall then you can use it as a middleman. The idea is to log onto middleman from behind the firewall, setup forwarded ports as above and just leave it connected all the time. Anytime you need to get behind the firewall you just go through the middleman. Here are the steps:

Setup your middleman to do gateways and stay connected without timing out. Edit /etc/sshd_config and make sure the following options are set:

The only difference from before is that this is now connecting the middleman and not the laptop to the firewalled machine, and we are using nohup to make sure the process doesn't die when the user logs out.

Then with your laptop you log onto port 10000 on the middleman which will forward your requests to the firewalled machine:

ssh usernameAtFirewalledMachine@middleman -p 10000

If you were unable to edit the sshd_config then you can still do this, you just have to jump through two hoops instead of one. First you log into middleman, then you log into the firewalled machine:

You can do a lot with this. It eliminates the need for a VPN. Ssh allows you to forward any port so you can connect to the intranet, the email server, anything that was hiding behind the firewall. This post is already too long, so I will leave it to the comments section for some examples of this sort of thing.

It also makes it pretty easy for social engineers to get behind your firewall. ("Could you run the Necessary Operation Help User Protocol for me, just type nohup...")

But I am a Windows luser!

Windows users can do this as well. Just install ssh using Cygwin. All of the ssh goodies including a client, server and scripts to set it up are there.