A recent upgrade of Windows Azure Web Sites enabled the Dynamic IP Restrictions module for IIS8. Developers can now enable and configure the Dynamic IP Restrictions feature (or DIPR as short-hand) for their websites.
There is a good overview of the IIS8 feature available here:http://www.iis.net/learn/get-started/whats-new-in-iis-8/iis-80-dynamic-ip-address-restrictions
The DIPR feature provides two main protections for developers:
- Blocking of IP addresses based on number of concurrent requests
- Blocking of IP addresses based on number of requests over a period of time
Developers can additionally configure DIPR behavior such as the type of failure HTTP status code sent back on blocked requests.
In Azure Web Sites a developer configures DIPR using configuration sections added to the web.config file located in the root folder of the website.
If you want to block connections based on the number of concurrent requests (i.e. active requests currently in flight at any moment in time), add the following configuration snippet to a website’s web.config file.
By setting the enabled attribute to true in the denyByConcurrentRequests element, IIS will automatically start blocking requests from IP addresses when the maximum number of concurrent requests exceeds the value set in the maxConcurrentRequests attribute (set to 10 in the example above).
Alternatively if you want to block connections based on the total number of requests made within a specific time window you could use the following configuration snippet:
In the above example, setting the enabled attribute to true in the denyByRequestRate element tells IIS to block requests from IP addresses when the total number of requests observed within the time window defined by requestIntervalInMilliseconds (set to 2000 ms. in the example) exceeds the value set in the maxRequests attribute (set to 10 in the example). So a client making more than 10 requests within a 2 second period will be blocked.
And lastly developers can also choose to enable both blocking mechanisms simultaneously. The snippet below tells DIPR to block clients that either have more than 10 concurrent requests in-flight, or that have made more than 20 total requests within a 5 second time window:
After DIPR blocks an IP address, the address stays blocked until the end of the current time window, after which the IP address is once again able to make requests to the website. For example, if requestIntervalInMilliseconds is set to 5000 (5 seconds), and an IP address is blocked at the 2 second mark – the address will remain blocked for another 3 seconds which is the time remaining in the current time window.
Developer can customize the error returned when a client is blocked by configuring the denyAction attribute on the dynamicIpSecurity element itself. The allowable values for denyAction are:
- AbortRequest (returns an HTTP status code of 0)
- Unauthorized (returns an HTTP status code of 401)
- Forbidden (returns an HTTP status code of 403). Note this is the default setting.
- NotFound (returns an HTTP status code of 404)
For example, if you wanted to send a 404 status code instead of the default (which is Forbidden 403), you could use the following configuration:
One question that comes up is: what IP address will DIPR see when running in Azure Web Sites? Running in Windows Azure means that a web application is sitting behind various load balancers. That could potentially mean that the client IP address presented to a website is the address of an upstream load balancer instead of the actual client out on the Internet. However Azure Web Sites automatically handles the necessary translation on your behalf and ensures that the client IP address “seen” by the DIPR module is the real IP address of Internet clients making HTTP requests.