How to make #Episerver #visitorgroups work behind a CDN

There is two way to make the IP come from the actual client instead of the CDN edge server. Here is a guide.

icon of user profile

Published 25th November 2016

Sometimes when you google or duckduckgo to find the solution, you don‘t always find the best practice way at first, or you may also find an old blog post and since you are eager to get it working, you don’t take your time to seek for alternate way.  So If you found your way here I will describe two ways to make it work.

“In Content Delivery Networks (CDNs), requests to the web server often come from an edge server and not from the actual client; therefore the HttpContext.Request.UserHostAddress property reflects the edge server’s IP address rather than the connecting client’s.” – Epi Documentation

Best practice, the Episerver way as it meant to be done:

In the CDN panel you may choose a name for the header variable that the client ip should be using, or for example Akamai is using custom header variable True-Client-IP. Then change this appsetting to make it work for visitorgroups.

<appSettings>
     <add key="episerver:ClientIPAddressHeader" value="True-Client-IP" />
</appSettings>

Header X-Forwarded-For is supported by most CDNs, this header contains a comma separated list of IP addresses, one for each CDN/proxy that a request passes through. This header is supported by using the same setting.

<appSettings>
     <add key="episerver:ClientIPAddressHeader" value="X-Forwarded-For"/>
</appSettings>

It is possible to specify the number of CDNs/proxies the header is expected to contain. Default value is 1, change this value if more than one CDN or proxy is used.

<appSettings>
    <add key="episerver:ClientIPAddressProxyCount" value="2" />
</appSettings>

 

The IIS Url Rewrite way:

Since it sometime differs how many proxies the user is going thru (or you don’t know), this is a way to change HttpContext.Request.UserHostAddress eg ServerVariables[“REMOTE_ADDR”] from the first IP in the IP list in ServerVariables[“HTTP_X_FORWARDED_FOR”].

After installing you have this icon in IIS on the site.
After installing you have this icon in IIS on the site.

First install Url Rewrite to your IIS – https://www.iis.net/downloads/microsoft/url-rewrite

URL Rewrite allows Web administrators to easily build powerful rules using rewrite providers written in .NET, regular expression pattern matching, and wildcard mapping to examine information in both URLs and other HTTP headers and IIS server variables.

urlrewrite_rules_changeheaders

manageservervariablesYou may put up rules in the IIS UI, but the most important to make it work is to “Manage Server Variables” and Allow to manipulate them, Add REMOTE_ADDR and HTTP_X_FORWARDED_FOR.

allowed-server-variables-remote_addr

Adding the variable is only done in IIS UI, but the rules are editable in the Web.config, looking like this.

  </system.webServer>     
    <rewrite>
      <rules>
        <!-- this one is a bonus, how to redirect to https -->
        <rule name="Redirect to https" enabled="true" stopProcessing="true">
          <match url="(.*)"/>
          <conditions logicalGrouping="MatchAll">
            <add input="{HTTPS}" pattern="off"/>
            <add input="{HTTP_HOST}" pattern="(www.*)"/>
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent"/>
        </rule>
        <!-- swipe headers i IP, remember to add header in IIS UI Manage Server Variables -->
        <rule name="Replace REMOTE_ADDR with X_Forwarded_For DOT" enabled="true" patternSyntax="Wildcard">
          <match url="*"/>
          <conditions>
            <add input="{HTTP_X_FORWARDED_FOR}" pattern="*.*"/>
          </conditions>
          <serverVariables>
            <set name="REMOTE_ADDR" value="{C:0}"/>
          </serverVariables>
          <action type="None"/>
        </rule>
        <!-- swipe headers if list, take the first IP only -->
        <rule name="Replace REMOTE_ADDR with X_Forwarded_For COMMA sometime many IPnos" patternSyntax="Wildcard" enabled="true">
          <match url="*"/>
          <conditions>
            <add input="{HTTP_X_FORWARDED_FOR}" pattern="*.*"/>
            <add input="{HTTP_X_FORWARDED_FOR}" pattern="*,*"/>
          </conditions>
          <serverVariables>
            <set name="REMOTE_ADDR" value="{C:1}"/>
          </serverVariables>
          <action type="None"/>
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

To test this, there is several add ons to you favorite browser to download to simulate and test this before putting it in production.

Sources: