Using localtunnel to allow external access to IIS Express


Why Bother?

There are varying reasons why one might want to tunnel through the internet to allow external access to his/her development web server. It's useful in a variety of reasons (providing someone remote with access to your dev environment, testing web applications on mobile devices, etc.) and I personally find it especially handy when testing callbacks from 3rd party sites.
For instance, I recently worked on the integration of a new payment vendor into an existing ecommerce website. This involved sending a customer to the third party site and receiving a callback from that site when a payment succeeded or failed. This is easy in production, but a real pain in development, when you need to the test the 3rd party's (test system's) callback integration. Obviously passing a localhost:80 as the callpack URI won't work and, short of hosting my development environment online and having a static IP or DNS entry, this was something traditionally difficult to test.
localtunnel makes this free and easy! It basically binds a specified port on your local PC to a real (temporarily accessible) domain name over SSH. The only tough part is getting IIS express on board...

Installing localtunnel

You'll need Ruby installed and can install the localtunnel gem with the following command
gem install localtunnel
For security purposes you'll need to provide localtunnel with an SSH key upon first loading the application. This is easiest by using cygwin and running the following command:
ssh-keygen
Now that you've generated your ssh key, you can run localtunnel on the desired port (in my case port 80) with your key:
localtunnel -k ~/.ssh/id_rsa.pub 80
For subsequent calls you will not need to provide the key
localtunnel 80
You should see something like this:
Port 80 is now publicly accessible from http://xtv4.localtunnel.com ...
At this point localtunnel is working but if you navigate to an IIS Express site, you'll probably see a 503 error

Making IIS Express work with localtunnel

Modifying the ACL

You'll definitely want to modify your Access Control List if you do not plan to run Visual Studio as an administrator, as in my case
netsh http add urlacl url=http://*:80/ user=everyone
Note: I suggest deleting these entries once you have completed the development you are working on. To do so:
First enumerate the acls on your system
netsh http show urlacl
Once you've identied the acl you want to remove, do so by replacing the url in the following command with your URL
netsh http delete urlacl url=http://*:80/

Modifying applicationhost.config

You'll need to modify your applicationhost.config file (located at %userprofile%\Documents\IISExpress\config\) to allow wildcards.


<site name="testsite" id="2">

            <application path="/" applicationPool="Clr4IntegratedAppPool">

                <virtualDirectory path="/" physicalPath="C:\Users\jirwin\Documents\My Web Sites\testsite" />

            </application>

            <application path="/test">

                <virtualDirectory path="/" physicalPath="C:\Users\jirwin\Documents\Visual Studio 2010\Projects\testsite\testsite" />

            </application>

            <bindings>

                <binding protocol="http" bindingInformation="*:80:" />

            </bindings>

    </site>

The important part here is the bindingInformation section. Essentially what you are telling IIS Express here is that you do not want to limit based on IP address or host header when connecting to this site:
bindingInformation="*:80:"

Proof of the Pudding

At this point you should be able to enter the provided address (http://xtv4.localtunnel.com in the above example) in the address bar of your favorite browser and see your local website load up over the internet. Brilliant!

Further Work

The only thing I haven't played with yet is using a combination of port 80 and 443 (for SSL) through localtunnel. I'm not sure if this is possible - it looks distinctly like only a single port can be tunneled (which would obviously make sense at a conceptual level). I'm willing to bet that the best idea in this case is to use 443 exclusively when testing and to follow all the steps above using port 443 instead of 80. I'd be very interested to hear if anyone has experience with this...
Post a Comment

Popular posts from this blog

Getting Started with Mirth (Part 2)

Mirth

Visual Studio 2012–Debug in Chrome Incognito Mode