HAProxy – IIS and X-Forward-For Header
So, you’re using IIS and you want to track your clients by IP address in your IIS logs. Unfortunately, out of the tin, this is not directly supported. The X-Forwarded-For (XFF) HTTP header is an industry standard method to find the IP address of a client machine that is connecting to your web server via an HTTP proxy, load balancer etc. Fortunately, depending on the version of IIS being used, there are a number of ways to enable this.
A – IIS 7 & later :
Microsoft do now have a solution – it’s called IIS Advanced Logging. This is an installable IIS feature and can be downloaded here. Once installed on the IIS server, you’ll see an extra option called ‘Advanced Logging’ for the sites in IIS.
Once installed, follow the steps below to add the X-Forwarded-For log field to IIS:
1. From your Windows Server 2008 or Windows Server 2008 R2 device, open IIS Manager
2. From the Connections navigation pane, click the appropriate server, web site, or directory on which you are configuring Advanced Logging. The Home page appears in the main panel
3. From the Home page, under IIS, double-click Advanced Logging
4. From the Actions pane on the right, click Edit Logging Fields
5. From the Edit Logging Fields dialog box, click the Add Field button, and then complete the following:
-in the Field ID box, type X-Forwarded-For
-from the Category list, select Default
-from the Source Type list, select Request Header
-in the Source Name box, type X-Forwarded-For
-click the OK button in the Add Logging Field box, and then click the OK button in the Edit Logging Fields box
6. Click a Log Definition to select it. By default, there is only one: %COMPUTERNAME%-Server. The log definition you select must have a status of Enabled
7. From the Actions pane on the right, click Edit Log Definition
8. Click the Select Fields button, and then check the box for the X-Forwarded-For logging field
9. Click the OK button
10. From the Actions pane, click Apply
11. Click Return To Advanced Logging
12. In the Actions pane, click Enable Advanced Logging
Now, when you look at the logs the client IP address is included.
B – IIS 6 :
Unfortunatey the Microsoft solution mentioned above is not available for IIS 6. luckily there are a number of solutions available to address this limitation – some that cost money and others that have been released as open source. One excellent example that we’ve tested with our products is F5′s X-Forwarded-For ISAPI filter. It’s avaialable in both in 32 & 64 bit versions.
1. Download the zipped archive from here and extract to an appropriate folder
2. Navigate to the relevant version (32 or 64 bit)
3. Copy F5XForwardedFor.dll to a suitable location on your server, e.g. C:ISAPIfilters
4. Make sure you have ISAPI Filters enabled on your IIS server
5. Open IIS Manager, right-click the site and select Properties
6. Select the ISAPI Filters tab
7. Click ‘add’, then in the popup enter a suitable name and select the DLL file stored in step 3
8. Restart your website
That’s it – you should now start seeing the IP address of the client PC’s in your IIS logs rather than the IP of the load balancer.
A recent customer issue came up where they were load balancing servers but we unable to get the true client address logged in their IIS logs. They had their servers fronted by a BIG-IP and when clients would make requests the address passed to the server was the internal address of the BIG-IP and not that of the client.
This is a common issue with proxies and fortunately there is a standard for forwarding client information. It is the HTTP X-Forwarded-For header which is handled by most proxies. So, I set out to find an existing ISAPI filter to replace the c-ip (client ip) log value in IIS with the contents of the X-Forwarded-For header (if it exists). I was amazed to find that I couldn’t find a single instance of any open source (or even commercial) filter that would do this.
So, I dug out Visual Studio and whipped up a filter that does just that. It’s very basic and contains no user configuration so all you need to do is plug it into your Web Applications list of ISAPI Filters within the IIS Administration and you’re set to go.
We’ve released the source under the iControl End User License Agreement (available in any iControl SDK download). You can download it in the CodeShare section of DevCentral. If you find a way to optimize this filter, please let me know and I’ll update the sources here.
After 24-hours of posting, a customer already returned some performance testing on the filter indicating that it only effected the traffic by less than 1 percent. I’m sure there are ways to optimize the memory allocation in the filter to speed this up a bit more, but I’ll leave that for the community to work on.
Oh, and it should be noted that the X-Forwarded-For header isn’t supported the same way across all proxy products so you’ll want to make sure you test this out before using it. It is expecting the header to only contain an IP Address as it does a straight substitution on the value in the c-ip section of the log entry.