Making a local web server public with localtunnel

May 11, 2010

These days it’s fairly common to run a local environment for web development. Whether you’re running Apache, Mongrel, or the App Engine SDK, we’re all starting to see the benefits of having a production-like environment right there on your laptop so you can iteratively code and debug your app without deploying live, or even needing the Internet.

However, with the growing popularity of callbacks and webhooks, you can only really debug if your script is live and on the Internet. There are also other cases where you need to make what are normally private and/or local web servers public, such as various kinds of testing or quick public demos. Demos are a surprisingly common case, especially for multi-user systems (“Man, I wish I could have you join this chat room app I’m working on, but it’s only running on my laptop”).

The solution is obvious, right? SSH remote forwarding, or reverse tunneling. Use a magical set of options with SSH with a public server you have SSH access to, and set up a tunnel from that machine to your local machine. When people connect to a port on your public machine, it gets forwarded to a local port on your machine, looking as if that port was on a public IP.

The idea is great, but it’s a hassle to set up. You need to make sure sshd is set up properly in order to make a public tunnel on the remote machine, or you need to set up two tunnels, one from your machine to a private port on the remote machine, and then another on the remote machine from a public port to the private port (that forwards to your machine).

In short, it’s too much of a hassle to consider it a quick and easy option. Here is the quick and easy option:

$ localtunnel 8080

And you’re done! With localtunnel, it’s so simple to set this up, it’s almost fun to do. What’s more is that the publicly accessible URL has a nice hostname and uses port 80, no matter what port its on locally. And it tells you what this URL is when you start localtunnel:

$ localtunnel 8080
Port 8080 is now publicly accessible from http://8bv2.localtunnel.com

What’s going on behind the scenes is a web server component running on localtunnel.com. It serves two purposes: a virtual host reverse proxy to the port forward, and a tunnel register API (try going to http://open.localtunnel.com). This simple API allocates a port to tunnel on, and gives the localtunnel client command the information it needs to set up an SSH tunnel for you. The localtunnel command just wraps an SSH library and does this register call.

Of course, there’s also the authentication part. As a free, public service, we don’t want to just give everybody SSH access to this machine (as it may seem). The user localtunnel on that box is made just for this service. It has no shell. It only has a home directory with an authorized_keys file. We require you to upload a public key for authentication, and we also mark that key with options that say you can only do port forwarding. Although, it can’t be used for arbitrary port forwarding… because it’s only a private port on the remote side, it can only be used with the special reverse proxy.

So there it is. And the code is on GitHub. You might notice the server is in Python and the client in Ruby. Why? It just made sense. Python has Twisted, which I like for server stuff. And Ruby is great for command line scripts, and has a nice SSH library. In the end, it doesn’t matter what it’s written in. Ultimately it’s a Unix program.

Enjoy!

41 Responses to “Making a local web server public with localtunnel”

  1. Will Tran Says:

    Props

  2. tamberg Says:

    Hi,

    interesting post. We’re working on a similar project focused on Web services (or Web servers, if you want) running on small devices. Yaler aims to provide a simple, open and scalable relay infrastructure and is implemented with Java non-blocking sockets and hierarchical state machines. For more information, please visit http://yaler.org/

    Kind regards,
    tamberg

  3. skx Says:

    > In short, it’s too much of a hassle to consider it a
    > quick and easy option.

    SSH reverse tunnel is quick, simple and safe. I would say much simpler than setting up another service on your server and safer than using a 3rd party tunnel. Try this
    screen -dmS shinynewtunneltoapache ssh -Nvv -o TCPKeepAlive=yes -R [remote port]:[local IP]:[local port] user@remotemachine

    for example
    screen -dmS shinynewtunneltoapache ssh -Nvv -o TCPKeepAlive=yes -R 10080:192.168.13.2:80 user@remotemachine
    Create an alias if you use it often.

    Just make sure you have
    GatewayPorts yes
    in your sshd config on remotemachine.

    Then put http://remotemachine:10443 in the browser. You can even reattach the screen and get some readable output.

    Still, localtunnel seems like a nice piece of software. Especially if someone preconfigures it on team’s computers.

    • Jeff Lindsay Says:

      Yes, really this is just wrapping SSH reverse tunneling and providing a 3rd party host for you. Since we weren’t optimizing for safety/security of transmitted contents, a 3rd party host makes it much easier, on top of eliminating all the options of SSH to do this. If you were worried about the 3rd party bit, the server is available. Again, it’s just wrapping SSH and everything you’re describing (thanks for sharing btw), so it’s not really different, just more convenient.

  4. Kevin Says:

    does it work with wi-fi routers? do i need access to the router to send port 80 to my laptop, or does this just happen magically?

  5. Don Says:

    Are you concerned about people setting this up with a permanent server on their private networks and pointing a CNAME at their blah.localtunnel.com host?

    • Jeff Lindsay Says:

      No, in fact, I’d like to come up with a good solution for maintaining a persistent tunnel hostname (whether the tunnel is persistent or not). If this turns out to be resource intensive, we’d start limiting it.

  6. Jonas Says:

    Yeah… because they can’t just connect to your laptop? Because this would be .. to obvious? Uncool?

    • Jeff Lindsay Says:

      Depending on network topologies this might prove difficult. Especially if you’re talking about a webhook scenario where a web app needs to access a script that you only have (or want to have while developing) on your laptop. If you’re behind a NAT, directly connecting would require port forwarding on whatever network you’re on at the time, which may not be possible. Nor is it portable — if I want to go from Starbucks to home to work and use it all three places, that’s three networks I’d have to talk to the network admin to get port forwarding, which is probably not even possible at Starbucks.

  7. herupriadi Says:

    thanks awesome articles

  8. Alex Le Says:

    Jeff,
    I’m using localtunnel to test PayPal IPN stuff but so far I haven’t been able to get the localtunnel URL to work with PayPal IPN. Here’s a screenshot of the error

    http://cl.ly/0b7d23ee6ce79ec43d39

    I keep running to the error “We were unable to validate the URL you have entered. Please check your entry and try again.”

    It seems like if the url is a sub-domain, then the IPN verification would bark (I’ve tried http://localtunnel.com, http://google.com, and my site’s url, http://marrily.com) and the sandbox takes it. But as soon as I put in the Localtunnel URL, then it refused.

    Any idea?

    THanks

  9. Andrew Says:

    Does Local Tunnel work with Python? If not, does anyone have suggestions for the following problem:

    I’m working on an app that uses Yahoo OAuth. The OAuth had been working fine but I just registered my domain with Yahoo and now it will not let me use the OAuth when I develop locally because
    “Custom port is not allowed or the host is not registered with this consumer key.”

    The issue is because my call back URL is to a domain that is not registered with Yahoo (http://localhost:8080/welcome).

    Any help is greatly appreciated.

    • Jeff Lindsay Says:

      Hmm. Well it works with any language because it’s not a library. It’s a network gateway.

      Obviously, Yahoo can’t reach localhost because that’s your local machine. That’s more the issue than the custom port issue (8080) I imagine. If you run localtunnel 8080, it’ll give you a temporary URL that you can give Yahoo that will be on port 80 and should satisfy their requirements.

  10. steliosm Says:

    Hello Jeff.

    Just wanted to say that this is a very helpful service.

    I also wanted to share my thoughts about the SSH server and the number of concurrent connections in can accept. Couldn’t Twsted be used to do the port forwarding?

  11. aini Ssatra Says:

    Thank’s For this Article. I Like It’s

  12. app Says:

    Hello mates, fastidious piece of writing and pleasant arguments commented here, I am in fact enjoying by these.


  13. Hi, I think your blog might be having browser compatibility issues.
    When I look at your blog site in Opera, it looks fine
    but when opening in Internet Explorer, it has
    some overlapping. I just wanted to give you a quick heads up!
    Other then that, superb blog!


  14. Hello, just wanted to mention, I loved this
    blog post. It was inspiring. Keep on posting!

  15. faqo.ru Says:

    I have fun with, cause I found exactly what I used to be looking
    for. You’ve ended my 4 day long hunt! God Bless you man. Have a great day. Bye


  16. I’m not sure where you are getting your info, but good topic. I needs to spend some time learning more or understanding more. Thanks for excellent info I was looking for this information for my mission.


  17. Hi there, i read your blog from time to time and i own a similar one and i was just wondering if you get a
    lot of spam comments? If so how do you protect
    against it, any plugin or anything you can advise?
    I get so much lately it’s driving me insane so any help is very much appreciated.


  18. Hello, its fastidious paragraph concerning media print, we all understand media is a fantastic source of information.

  19. Emory Says:

    I got this web site from my friend who shared with me about this site
    and at the moment this time I am browsing this web site and reading very informative articles or reviews at this time.

  20. Teena Says:

    We are a gaggle of volunteers and starting a new scheme in our community.

    Your web site provided us with useful info to work on.
    You’ve done a formidable activity and our entire community will likely be thankful to you.


  21. What’s up, after reading this amazing post i am also happy to share my know-how here with colleagues.


  22. It’s going to be finish of mine day, except before ending I am reading this fantastic article to increase my knowledge.


  23. Yes! Finally something about fr飠pron.

  24. Sidney Says:

    You really make it appear really easy along with your presentation however I find this matter to be actually something which I feel I would never understand.

    It seems too complicated and very vast for me. I’m looking ahead on your subsequent post, I will attempt to get the grasp of it!


  25. Admiring the persistence you put into your blog and in depth information you provide.
    It’s great to come across a blog every once in a while that isn’t the same outdated rehashed information.
    Fantastic read! I’ve saved your site and I’m including your RSS feeds to my Google account.

  26. Stepanie Says:

    For newest information you have to go to see world wide web
    and on internet I found this web page as a most excellent site for newest updates.

  27. Kristofer Says:

    This paragraph gives clear idea designed for the new users of
    blogging, that in fact how to do blogging and site-building.


  28. Just desire to say your article is as astonishing.
    The clarity on your submit is simply excellent and i could assume
    you are a professional on this subject. Fine together with your permission let me to
    clutch your RSS feed to stay up to date with drawing close post.
    Thanks 1,000,000 and please continue the rewarding work.


  29. I do believe all of the concepts you have presented in your post.

    They’re very convincing and can definitely work. Nonetheless, the posts are very brief for newbies. May you please prolong them a bit from next time? Thank you for the post.


  30. Thanks for ones marvelous posting! I genuinely
    enjoyed reading it, you can be a great author. I will be
    sure to bookmark your blog and definitely will come back down the road.
    I want to encourage you to continue your great job,
    have a nice weekend!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 25 other followers

%d bloggers like this: