This was all stolen from Hacktivate – Reversing an ssh connection. (I only pasted the contents here in case the site goes down)
Just brilliant…
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:
TCPKeepAlive yes
ClientAliveInterval 30
ClientAliveCountMax 99999
GatewayPorts yes
I think you have to restart sshd to make these changes. I am not sure how to do this elegantly. Rebooting is one option.
Then from the firewalled machine run:
nohup ssh -f -N -R 10000:localhost:22 username@middleman
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:
ssh usernameAtMiddleman@middleman
ssh usernameAtFirewalledMachine@localhost -p 10000
Applications and Implications
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.