IIS IP Restrictions on AWS
The idea is not to block every shot. The idea is to make your opponent believe that you might block every shot.Bill Russell
When testing it's important to replicate your live environment as closely as possible but equally we don't always want to make our test environments publicly accessible. In this article we will look at how we can use IIS Dynamic IP Restrictions to block unwanted visitors to a site even when using CloudFront or Elastic Load Balancing (ELB).
In our case the environment we are replicating consists of two servers behind an Elastic Load Balancer which is fronted by a CloudFront distribution. We will be using the Dynamic IP Restrictions built into IIS 8 or available on IIS7 and IIS7.5 via the Web platform Installer.
Following the links above we can see that the IP restriction module uses the X-ForwardedFor header which is set by both CloudFront and ELB. We start by setting the IP restrictions module to "Deny" unspecified clients and enable proxy mode.
Next we add ALLOW entries for the IP addresses we want to be able to access the web site. These entries are stored in the applicationHost.config file located at C:\Windows\System32\inetsrv\config. Looking at this file we can see that the entry is stored as an XML fragment like:
<add ipAddress="127.0.0.1" allowed="true" />
We now need to add the IP addresses of the ELB and CloudFront proxies. The ELB IP addresses are defined as having any IP from the private range as defined in RFC 1918. We can add these directly into the applicationHost.config with the following XML fragments.
<!-- 10.0.0.1 - 10.255.255.254 (ELB - RFC1918 Private IP) --> <add ipAddress="10.0.0.0" subnetMask="255.0.0.0" allowed="true" /> <!-- 172.16.0.1 - 172.31.255.254 (ELB - RFC1918 Private IP) --> <add ipAddress="172.16.0.0" subnetMask="255.240.0.0" allowed="true" /> <!-- 192.168.0.1 - 192.168.255.254 (ELB - RFC1918 Private IP) --> <add ipAddress="192.168.0.0" subnetMask="255.255.0.0" allowed="true" />
Adding the cloudfront IP addresses is slightly more involved. Amazon publish a machine readable listing of all possible IP addresses at https://ip-ranges.amazonaws.com/ip-ranges.json. We want to add all of the "CloudFront" entries from the GLOBAL region. Doing this manually can be quite a chore so I've created a LINQPad query which you can use to generate the XML fragment required at will.
It's also important to note that Amazon publish the IP list in a machine readable format because they may change frequently. As such if you are relying on this functionality for a live system you may want to automate the updating of the applicationHost.config at regular intervals.
Find this post useful? Follow us on Twitter