IIS 7 - Restrict Application by IP Address behind load balancer
You can use the IIS URL Rewrite module to accomplish this.
Add a new inbound rule with conditions that check to see if the IP address does not match {HTTP_X_Forwarded_For}. You can then set the rule up to redirect, rewrite, or abort the request.
You can a new condition for each IP address you wish to white-list.
Using IIS URL Rewrite module to normalize REMOTE_ADDR
and implement IP Restrictions.
With the following recipe REMOTE_ADDR
will be set to the real Client-IP regardless if there is a trusted reverse proxy in front to set HTTP_X_FORWARDED_FOR
. That means you can remove the reverse proxy from in front of IIS and these IP Restrictions will still continue to work as expected.
Normalize REMOTE_ADDR
in applicationHost.config
Set this in the global IIS applicationHost.config
:
<rewrite>
<allowedServerVariables>
<add name="REMOTE_ADDR" />
<add name="REMOTE_HOST" />
</allowedServerVariables>
<globalRules>
<rule name="Remote" patternSyntax="ECMAScript">
<match url=".*" ignoreCase="false" />
<conditions>
<add input="{REMOTE_ADDR}" pattern="^10\.1\.1\.[123]$" ignoreCase="false" />
<add input="{HTTP_X_FORWARDED_FOR}" pattern="\d+\.\d+\.\d+\.\d+$" ignoreCase="false" />
</conditions>
<serverVariables>
<set name="REMOTE_ADDR" value="{C:0}" />
<set name="REMOTE_HOST" value="{C:0}" />
</serverVariables>
<action type="None" />
</rule>
</globalRules>
</rewrite>
The recipe above copies the last IP address it finds in HTTP_X_FORWARDED_FOR
to the REMOTE_ADDR
and REMOTE_HOST
<serverVariables>
only if the original value in REMOTE_ADDR
matches the IP address of a trusted reverse proxy.
To have this recipe work, the first condition must be set to match your reverse proxy's IP address(es):
<add input="{REMOTE_ADDR}" pattern="^10\.1\.1\.[123]$" ignoreCase="false" />
In the example above, the client IP in HTTP_X_FORWARDED_FOR
is trusted only if set by a reverse proxy at one of these IP addresses:
10.1.1.1 or 10.1.1.2 or 10.1.1.3
That takes care of setting REMOTE_ADDR
to the real Client-IP.
IP Restrictions in web.config
IP Restrictions can be set with the IIS URL Rewrite module in a site's web.config
using this recipe:
<system.webServer>
<rewrite>
<rules>
<rule name="IP Restricted" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*" ignoreCase="false" />
<conditions>
<add input="{REMOTE_ADDR}" pattern="^(127\.|10\.20\.74\.|10\.25\.182\.|10\.64\.105\.10)" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="/403.html" appendQueryString="false" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
Edit the pattern=
to only match the IP addresses or blocks you need to let in.
Change the <action />
to whatever needed.
Because the web.config
recipe above filters on the standard REMOTE_ADDR
variable, it works with and without HTTP_X_FORWARDED_FOR
. The recipe in applicationHost.config
<rewrite>
<globalRules>
ensures that REMOTE_ADDR
is always set to the real Client-IP for anything that might later reference REMOTE_ADDR
.
IIS 7 and beyond include the Dynamic IP Restrictions module, which supports filtering client requests by their X-Forwarded-For
header, which is added to a request when using an AWS load balancer:
Support for web servers behind a proxy - If your web server is behind a proxy, you can configure the module to use the client IP address from an X-Forwarded-For header.
You can enable Proxy Mode support by checking the "Proxy" checkbox in the module's configuration page, then write rules to allow/deny IPs/CIDR ranges via the module.