This is really neat: have you ever wanted to access your local machine or any other computer that it’s located in the local network from the outside world? I did, many times. The first and most common approach is to enable a DMZ in the router so all traffic that comes through the public IP address (for example, your modem’s IP) goes to a specific local computer. This works faily well, but you have to have access to the router’s configuration, and it is limited to a single destination machine.
If you are in an environment you don’t control, like your company, to change the router configuration is not an option, so how to we solve this problem? Using reverse tunneling through SSH.
For those new to the concept of tunneling, it is a trick that you can do with virtually any ssh client so all traffic from a local port goes to a remote server and port. It is also extremely useful to bypass corporate firewall rules and to use your remote server as a SOCKS proxy (so you can access Hulu from a blocked country). You can find more details at http://www.revsys.com/writings/quicktips/ssh-tunnel.html, http://ocaoimh.ie/2008/02/13/how-to-use-ssh-as-a-proxy-server/ and Google.
But the main question here is the opposite: how to we allow anyone to access our local machines? The answer is a reverse runnel. It is very simple to get it up and running, but it took me some good hours to find the correct approch, even because I didn’t know what to search for in the beginning. The steps are:
- Change a setting in your server’s sshd_config
- Choose a remote port to connect to
- Choose the local (destination) port to route the traffic
- Open the revere tunnel
So I have a webserver running on my localhost at port 8080, and I want that when someone calls “example.com” at port 15000, it sees my local webserver. In order to do that, first go to your remove server and add the following line to sshd_config (probably /etc/ssh/sshd_config)
This is strickly necessary, otherwise the tunnel will only work from the server to your machine (and not from any address to your machine). You can close the ssh session if you want.
Now, from your local machine, open the tunnel:
ssh -N -R "*:15000:localhost:8080" email@example.com
type the ssh password, and that’s all. The “-N” argument just hangs the ssh client, instead of opening a remote shell, “-R” is for the reverse tunnel itself, “*:” is to listen on all interfaces (strickly necessary, otherwise it will only listen in the loopback interface), “15000″ is the port at example.com that users will connect to, “localhost” is your own local machine, and “8080″ is the port in your local machine that will get the traffic.
This is very useful for development purposes, like when I had to test Amazon SNS using an HTTP endpoint.