Imagine you’re developing a web application using a framework like Rails. You’ve got your development server fired up and are regularly reloading http://localhost:3000 to see your changes. All is going well until you want to integrate with some 3rd party service that needs to talk to your application. You’re not really going to deploy to staging on every change, are you?

If you have control over the router, then you can simply forward an external port to your local machine. Bu you’re obviously a cool startup hacker, so of course you’re working in a coffee shop or co-work space. You’ve got no time for outdated ideas like “offices”. What are you to do?

Enter reverse SSH tunneling. The overall idea is simple:

  1. SSH into a remote Linux machine (if you don’t have one available, you can rent a server at http://prgmr.com for as little as $5 a month).
  2. Open a port on the remote machine that redirects all traffic back to your local machine.
  3. Point any outside service at the remote machine.

Here’s the nitty-gritty details:

  1. ssh into the remote machine
  2. Edit /etc/ssh/sshd_config and add the line:
    GatewayPorts clientspecified
  3. Restart sshd:
    sudo /etc/init.d/ssh restart
  4. Determine the public IP address of your remote machine using /sbin/ifconfig
  5. On your local machine, run:
    ssh -R x.x.x.x:3000:localhost:3000 your.remote.machine
    where x.x.x.x is the IP address you discovered in the last step
  6. Point any external service at http://your.remote.machine:3000 and viola! it will be talking to your local development Rails application 

Enjoy the freedom of hacking wherever you choose while still allowing any traffic you need to go directly to your local machine!

Note: Sometimes, when a SSH connection dies (as it will if you shut your laptop to move to another location), the port on the remote machine will stay open. If this happens, you’ll see this error when you try to create the reverse tunnel:

Warning: remote port forwarding failed for listen port 3000

If this happens, you can either use a new port or do the following:

  1. Find the process that is using port 3000 (look for the PID - you’ll need to run the command with sudo to see the PIDs):
    sudo netstat -anp 
  2. Kill the stale process:
    kill PID
  1. bbrinck posted this