One of the projects I’m currently working on is using a service that reports various events back to our system via webhooks. Since the features I’m working on aren’t ready for deployment yet I was looking for a decent way to test the integration in my development environment to ensure that I’m not only receiving the correct data but also that I’m handling it properly.
The service’s documentation recommended pointing the webhooks to another service such as RequestBin to inspect the contents. I did mess around with that approach for a bit and although I was certainly able to see the requests in the RequestBin log and push them on to the application with fiddler, it really didn’t seem like an adequate solution and I was tired so I went to bed.
It turns out that sleeping on it was exactly what I needed. Sometime overnight I subconsciously worked out a better solution; I could open up IIS Express to handle remote connections and configure NAT on my router to forward requests for that port directly to the IIS Express instance. It turns out that getting all this working was actually quite simple.
Allowing Remote Connections
Allowing remote connections to IIS Express requires a little work but it’s pretty straight-forward and is outlined in this stackoverflow post. In short we need to:
- Create an additional IP binding for the IIS Express site to allow traffic from all hosts.
- Allow connections to the port from anyone
- Create a firewall rule to allow traffic to the port on the development machine
Creating an IIS Express Binding
IIS Express sites are managed per-user. To create the IIS Express binding we simply need to create a new entry for the site in the configuration file located at %userprofile%\documents\iisexpress\config\applicationhost.config. In the file locate the site then duplicate the binding, changing the allowed host to *. For example, if the current binding is:
I’ve used port 99999 in these examples for demonstration purposes only. You’ll want to use the port listed in your configuration file.
<binding protocol="http" bindingInformation="*:99999:localhost" />
You’d create a copy and change localhost to * such that it reads like this:
<binding protocol="http" bindingInformation="*:99999:*" />
It’s very important that you leave the original binding in place. Yes, it is redundant to have a binding for all hosts and another for only localhost but Visual Studio uses the localhost binding to initialize IIS Express. If that binding isn’t present Visual Studio will create a duplicate site entry and you’ll likely start seeing errors such as the one pictured below.
URL Binding Failure
Setting Security on the Port
Once you’ve created the IIS Express binding you need to allow connections to the port. This is done by executing target=”_blank”>netsh to add a URL reservation for the new binding. In this case we’ll be using netsh http add urlacl to register the address we bound to the IIS Express site and granting permission to everyone.
netsh http add urlacl url=http://*:99999/ user=everyone
Note that “everyone” refers to the Everyone group in Windows. If you’re using a non-English version you’ll need to change that to the localized name for your language.
Creating a Firewall Rule
The final step is allowing traffic to that port through the local firewall. Accomplishing this varies according to which firewall solution you’re using. For Windows firewall you can control this through the control panel or by executing the following netsh command which changes some advanced firewall configuration settings.
netsh advfirewall firewall add rule name=”IISExpressWeb” dir=in protocol=tcp localport=99999 profile=private remoteip=any action=allow
Configuring NAT is not something I can really help with in this article because each environment will have its own instructions and restrictions. For me and my home office network it was easy because I simply had to add a custom application that referenced the configured port and host machine in my router’s firewall configuration.
Alternatively, I could have configured the IP Passthrough to route traffic to the development machine but I deemed this to be too much exposure to the outside world and left it with NAT.
Once I’d configured everything on my network to accept the webhook traffic I went to the external application’s dashboard and registered my computer as a webhook recipient using the WLAN IP address I obtained from my router’s status page and the port I bound to IIS Express for the application. I then set a breakpoint in the webhook processing logic, ran the application, made a change in the remote system to initiate sending an event, then watched in amazement as my breakpoint was hit and the watch window showed data received from the remote service.