Bypass Firewall and NAT with Reverse SSH Tunnel

Last updated: Feb 27, 2008

Recently I wanted to control my computer from a remote location. Problem was that the destination computer was behind a NAT and a firewall. Almost all large networks (corporate and universities) including home routers are now using some sort of NAT (Network Address Translation).

The problem with NAT is, that you can’t directly connect to the computers that are outside the NAT. Computers behind a NAT can only recieve packets that they request. For this reason we need to create a reverse SSH tunnel to establish a connection. If you are familiar with Hamachi or gotoypc type software this is the exact same thing they do to connect to computers behind NAT/Firewalls, only they use their severs as the middle man. We are going to have to find our middle man on our own.

Can’t I just use Hamachi gotomypc or some other software?

Well I actually forgot about reverse tunnels the other day and installed hamachi on my linux server. After trying to connect with my windows machine outside the NAT I found that it couldn’t create a connetion. After searching I found that Hamachi does not support low-speed relay (reverse tunnel) with their linux version of the program. That makes the Linux version of Hamachi useless. If you are trying to connect to a Windows machine by all means it is probably easier to just install Hamachi. But if you are dealing with a Linux machine there is a much easier way, provided that you ssh access to a computer in the middle. To establish a reverse tunnel in Linux you type in only one simple command.

So how about gotomypc? Well if you don’t have a computer in the middle to connect to and are willing to pay $19.95 a month, its not a bad service. I don’t believe gotomypc works for Linux however.

In order for you to create a reverse tunnel you must have SSH access to a middle computer that you can connect to from origin computer.

Setting it all up

On the destination computer type the following command. Replaceing middleuser with your name and replacing middle with the domain of the middle computer.

ssh -R 10002:localhost:22 middleuser@middle

This will open port 10002 for listening and forward all future connections to port 22 at destination. This connection must remain on the entire time to ensure that you can access your destination computer whenever you want.

Now if sshd is set to use GatewayPorts you should be able to connect with this:

ssh destinationuser@middle -p 10002

If you are not sure if GatewayPorts is on or you don’t have the access to change it use the following method to connect:

First connect to the middle computer how you would normally.

ssh user@middle

Then connect to the localhost of the middle computer on port 10002.

ssh user@localhost -p 10002

Note: The port 10002 is arbitrary you can use any port you want.

You should now be remotely logged into your computer behind the NAT/Firewall. Enjoy :)

For added security you could Add Port Knocking to SSH and Use Keys Instead of Passwords

FreeBSD Users

The above instructions will work for FreeBSD but for whatever reason I was unable to get the connection to stay alive for more than a few minutes. So, as a temporary work around I just do the same thing as above but I then run the program, “top” so that the connection is forced to stay alive. This isn’t the ideal solution however and I would appriceate it if someone could tell me why its closing the connection all of the time.

Need to print shipping labels on your site?

Checkout my product RocketShipIt for simple easy-to-use developer tools for UPS™ FedEx™ USPS™ and more.

Get notified on new posts or other things I'm working on