Date Category tech

Sometimes you want to allow someone access to your development server (e.g. a Django or Rails dev server) running on port 8000 on your laptop. Unless the other person is on the same subnet as you, it’s very likely there’s a firewall between you. (Whether you’re at home, on a company LAN, or at Starbucks.)

Assuming you have access to a Linux host that is publicly accessible, this is easy to work around. I personally have a tiny virtual host that gives me remote ssh access and runs a few little services for me, so I use this host.

This is a quick and dirty way to open up access to your dev server by using ssh and a publicly accessible remote server as your proxy.

Here’s the entirety of my script:

echo "Opening tunnel to $REMOTE..."
ssh -nNT -o ServerAliveInterval=30 \
    -R $REMOTE:8000:localhost:8000 $REMOTE

Here’s what it looks like in action:

Opening tunnel to

As long as this ssh process is around, the tunnel will continue to exist. It’s essentially a one-liner, but a little complicated, so I’ll explain the options:

  • -n: Redirect stdin from /dev/null, mainly useful if you plan on putting the ssh session in the background (with -f).
  • -N: Do not actually execute a remote shell, just connect and establish the requested port forwards.
  • -T: Don’t allocate a pseudo-TTY, since this is not intended to be an interactive shell.
  • -o ServerAliveInterval=30: Send a keepalive ping every 30 seconds. This will keep the TCP connection from being shut down due to inactivity if it is unused for several minutes.
  • -R $REMOTE:8000:localhost:8000: The key bit of magic, establish a reverse tunnel from the remote host, port 8000, to your local host, port 8000. Any incoming connection to the remote server on port 8000 will be transparently routed to your local development server.

As I hinted above, you can optionally pass -f to tell ssh to fork into the background after successfully connecting. I like to have it in the foreground, occupying a screen terminal, so that I don’t forget it’s open and I can kill it with CTRL-C whenever I want.