How do I add client IP to HTTP logs for Azure App Service sitting behind an Application Gateway

Chris Zielin 20 Reputation points
2023-02-17T23:24:50.16+00:00

I have an App Service sitting behind an Application Gateway. It is configured to write web logs to both Storage and Analytics. However, the CIp field in these logs only appears to show the internal IPs of the gateway. Not the real client IPs.

This makes the logs of limited use when trying to determine the requests a particular client made.

I see others have asked this going back a few years, but don't see a solid answer on how to fix this. Is this configuration possible?

I managed to get this ISAPI filter from F5 working. When I stream the log output from the App Service I can see the real client IP now. However, when writing to Storage or Analytics it still only shows the internal IP.

https://github.com/yokawasa/azure-webapps-logging-original-clientip

Is there a way to configure Analytics to use the same output that the log stream is using?

If this simply isn't possible is there another way to correlate HTTP requests to actual client IPs?

Azure Application Gateway
Azure Application Gateway
An Azure service that provides a platform-managed, scalable, and highly available application delivery controller as a service.
1,098 questions
Azure App Service
Azure App Service
Azure App Service is a service used to create and deploy scalable, mission-critical web apps.
8,092 questions
{count} votes

Accepted answer
  1. Chris Zielin 85 Reputation points
    2023-02-24T20:30:54.2566667+00:00

    Elevating @ajkuma's solution from the comments so it can be marked as the accepted answer.

    1. Create an ApplicationHost.xdt file with the following content:
         <?xml version="1.0"?> 
         <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
             <system.webServer> 
                 <arrHelper> 
                     <trustedProxies xdt:Transform="SetAttributes(trustUnlisted)" trustUnlisted="true" /> 
                 </arrHelper> 
             </system.webServer> 
         </configuration> 
      
    2. Make sure your App Service is configured so that it does not allow direct access in order to avoid X-Forwarded-For spoofing attacks.
    3. Upload the file to c:\home\site within your App Service.
    4. Restart the App Service.
    5. Make a request against your site and verify that the AppServicesHTTPLogs.CIp field contains your IP.
    1 person found this answer helpful.

3 additional answers

Sort by: Most helpful
  1. ajkuma 27,851 Reputation points Microsoft Employee
    2023-02-26T19:19:49.7666667+00:00

    On Windows clients, we have the ARR Helper, which does some magic plumbing of IIS Request sever variables.  One of which is the REMOTE_ADDR / REMOTE_HOST, and the ARR Helper sets this based on the XFF.

    We have a way/approach to override that behavior, by using an ApplicationHost.xdt transform: 

      

    <?xml version="1.0"?> 

    <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 

      <system.webServer> 

        <arrHelper> 

          <trustedProxies xdt:Transform="SetAttributes(trustUnlisted)" trustUnlisted="true" /> 

        </arrHelper> 

      </system.webServer> 

    </configuration> 

      

    This will override the existing (secure) behavior, and let you trust the last entry on the list.  And that's what will get logged.  As an important note, if you opt this route, the app is open to XFF spoofing attacks, so you must implement mitigations on your side to counter this. Please check this 3rd party blog article from one of our engineer.

    See: https://github.com/projectkudu/kudu/wiki/Xdt-transform-samples

    2 people found this answer helpful.
    0 comments No comments

  2. Tchimwa Sougang 946 Reputation points Microsoft Employee
    2023-02-21T13:21:15.4633333+00:00

    Hi @Chris Zielin thank you for your question. The AppGW usually adds 6 headers to every requests before routing it to the backend. Look for the header x-forward-for which is composed of and IP and port used by the customers. The IP is your client IP.

    https://github.com/MicrosoftDocs/azure-docs/blob/main/articles/application-gateway/how-application-gateway-works.md

    Please do not Forget to Accept the Answer if it is helpful so others can benefit from it.


  3. ajkuma 27,851 Reputation points Microsoft Employee
    2023-03-03T08:50:05.3633333+00:00

    Based on the discussions ( in comments + answers), copying the elevated summarized answer from @Chris Zielin @Chris Zielin , to benefit the community find the right accepted answer.
    Q&A platform doc: Accept an answer on Microsoft Q&A

      1. Create an ApplicationHost.xdt file with the following content:
           <?xml version="1.0"?> 
           <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 
               <system.webServer> 
                   <arrHelper> 
                       <trustedProxies xdt:Transform="SetAttributes(trustUnlisted)" trustUnlisted="true" /> 
                   </arrHelper> 
               </system.webServer> 
           </configuration> 
    
      1. Make sure your App Service is configured so that it does not allow direct access in order to avoid X-Forwarded-For spoofing attacks.
    • 3.Upload the file to c:\home\site within your App Service.
      1. Restart the App Service.
      1. Make a request against your site and verify that the AppServicesHTTPLogs.CIp field contains your IP.

    Much appreciate your feedback and collaboration on this, @Chris Zielin

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.