Tunneling to localhost via SSH

tunnel

Sometimes when working with a new web site I have customers who want to see the
site while it is still in development. One way of doing this
is to have alternative demo servers where all we do is just serve up our work
in progress. This works fine most of the time, but sometimes I just want to be
serve up my local machine.

Localtunnel

One easy way to do this is to use localtunnel.
localtunnel is a Ruby gem that is meant for exactly this purpose. Here's how:

$ gem install localtunnel
$ localtunnel --key ~/.ssh/id_rsa.pub 80
  This localtunnel service is brought to you by Twilio.
  Port 80 is now publicly accessible from http://4xiw.localtunnel.com ...

It is now possible to access localhost:80 via the URL
http://4xiw.localtunnel.com. Simple as pie!

But what if you don't like pie? Or Ruby, for that matter. Or, what if you don't
like to serve your secret data through another company (Twilio in this case who
graciously gives away the hosting for free).

Well you are in luck, it is easy to set up your own tunnel via SSH, provided
you have access to a server that is accessible from the Internet. And,
everybody has access to such a server via Amazon EC2 or similar service. Make
sure the server is accessible on all high ports. On Amazon this is done by
opening all incoming ports above 1024 in a security group.

Setting up a tunnel via SSH

In SSH lingo a tunnel from an external server to my local server is called a
reverse proxy. Here is how to set one up. First you need to configure the
remote ssh daemon to allow setting up remote interfaces. A remote interface is
one that can be accessed from a server other than localhost, which is what we
want.

Here is how to do it, the server called host.amazonaws.com is my AWS server.

    # Login to the remote server
    $ ssh -i ~/.ssh/id_rsa ec2-user@host.amazonaws.com

    # Edit the sshd configuration
    $ sudo vi /etc/ssh/sshd_config
    # Find the line #GatewayPorts no
    # Change it to GatewayPorts yes
    # Save and exit

    # Restart the daemon
    $ sudo /etc/init.d/sshd restart
    Stopping sshd:                                             [  OK  ]
    Starting sshd:                                             [  OK  ]

    # Exit the shell and return to your local machine
    $ exit

Now you are good to go. We assume you have a server running on port 3000 to
display to the world.

    $ ssh -i ~/.ssh/id_rsa -N -R *:0:localhost:3000 ec2-user@host.amazonaws.com
    Allocated port 34070 for remote forward to localhost:3000

Now you can surf to http://host.amazonaws.com:34070

And it will access your local machine. :)

When you stop the command (Ctrl-C) the tunneling will stop.

Command explanation

-i  identity file (private key)
-N  Do not execute a remote command, just setup the port forwarding
-R  *         All interfaces should be forwarded
    0         Open forwarding on any available port (34070 in the example)
    localhost Forward to localhost
    3000      The localport to forward too.
ec2-user      The user on the remote server
host.aws.com  The remote server

If you want to simplify it for yourself add the following script to a bin
catalog.

    ## Script tunnel
    #!/bin/bash

    set -o errexit

    # default to port 3000
    port=${1:-3000}

    ssh -i ~/.ssh/id_rsa -N -R *:0:localhost:$port ec2-user@host.amazonaws.com

Now all you have to do to enable remote access is tunnel 80, or whatever port
you want to display.

Jail

Escaping the proxy Jail

The story could have ended here, but some people, trapped behind corporate
firewalls, may not be allowed to use ssh. The traffic is blocked by a
corporate proxy server. Well, there is a happy ending for you too and it is
fittingly called corkscrew. It allows you
to screw yourself out of the corporate jail and into the world.

Here is how you do it on Ubuntu, on OS X use brew instead.

    # Install corkscrew
    $ sudo apt-get install corkscrew

    # Edit your ~/.ssh/config, add
    Host *
      ProxyCommand corkscrew http-proxy.example.com 8080 %h %p

    # If you need to authenticate to get through the proxy the line should read
    Host *
      ProxyCommand corkscrew http-proxy.example.com 8080 %h %p ~/.ssh/proxyauth

    # And you need to add username:password to ~/.ssh/proxyauth
    $ echo "proxyusername:proxypassword" > ~/.ssh/proxyauth

%h and %p is filled in by ssh with the host and port of your destination.


Freedom’s just another word for nothing left to lose,
Nothin’ don’t mean nothin’, honey, if it ain’t free.
Yeah, feeling good was easy, Lord, when he sang the blues,
You know feeling good was good enough for me,
Good enough for me and my Bobby McGee.

This Post Has 5 Comments

  1. localtunnel seems to be down.

  2. thanks, helped me a lot !!!

  3. I’m having issues using AWS EC2 as the site i’m tring to get to blocks EC2 traffic. would setting up ‘corkscrew’ or ‘reverse proxy’ on EC2 back to my local machine allow me to funnel traffic from EC2 back through my local machine?

Leave a Reply

Close Menu