Change the IP HTTP Header used for geo-lookup in Application Insights

A recommendation when on DXP, or in some other ASP.NET app behind Cloudflare, to get a more exact geo-lookup logged.

If you don't change anything, it will be the edge node's IP is used by Application Insights to look up city, region and country. It's of course more truthful to use the user's IP.

When on CMS11 or other app running on .NET Framework 4.8.1 or older, you could configure this in ApplicationInsights.config and set the appropriate Cloudflare custom HTTP Header named CF-Connecting-IP which contains an IP more closer to the user.

<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
  <TelemetryInitializers>
    ..
    <Add Type="Microsoft.ApplicationInsights.Web.ClientIpHeaderTelemetryInitializer, Microsoft.AI.Web">
      <HeaderNames>
        <Add>CF-Connecting-IP</Add>
      </HeaderNames>
      <HeaderValueSeparators>;</HeaderValueSeparators>
      <UseFirstIp>false</UseFirstIp>
    </Add>
    ..

For a while I was using the custom header True-Client-IP but found out that it's mainly available to turn on to ease with migration from Akamai's products. Value is identical to CF-Connecting-IP.

For modern dotnet, Arjan Paauw's blog post on finetuning Azure Application Insights in CMS12 is a great starting point.

Changing the geo-lookup IP header, however, seems to be missing from most documentation. To accomplish the same setup as with the old config change above, I had to jump into de-compiled code to see where to insert Cloudflare's header name.

I also confirmed that the other two settings above are the current defaults.

This project still uses Startup.cs and the code example to change header sits early in the Configure() method.

var telemetryInitializers =
    app.ApplicationServices.GetServices<ITelemetryInitializer>();

foreach (var telemetryInitializer in telemetryInitializers)
{
    if (telemetryInitializer is not ClientIpHeaderTelemetryInitializer ipInitializer)
    {
        continue;
    }

    ipInitializer.HeaderNames.Clear();
    ipInitializer.HeaderNames.Add("CF-Connecting-IP");

    // If you want something to fall back on away from Cloudflare
    ipInitializer.HeaderNames.Add("X-Forwarded-For");
}

If your project uses only Program.cs this should go after services have been configured and the app has had Build() called.

Comments?

Published and tagged with these categories: Optimizely, CMS, ASP.NET, Azure