IIS X-Forward-For ISAPI Filter
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 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 here. 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.
Enjoy!
-Joe
- John,
- Good points - I'm sold. I'll incorporate the check for internal networks and bypass replacement of the X-Forwarded-For header if the source address is from the ranges specified above.
- Thanks.
- If the status is Unknown, that means that you haven't sent any traffic through it. Try accessing one of the pages on that website and the status will either be an up arrow (good) or a red arrow (bad) but shouldn't be Unknown.
- Glad you like it! As far as I know there is no way to add headers to the IIS log facility. So, this filter will replace the C-IP value with the contents of the X-Forwarded-For header (if it exists).
- Not sure what's different with a SSL configured server. As far as I'm aware, the SSL decryption is performed before the content gets to the ISAPI filters. I see no reason why one would work and the other wouldn't.
- It's nothing that complicated. All it does is read the X-Forwarded-For HTTP header sent to the webserver from the firewall (or other intermediary) and replaces the c-ip field in the IIS logs with that value for that request. Otherwise, there is no other way with IIS to show the true identity of a client if a firewall changes the source ip address.
- Kazu, can you post your code changes or send them to me and I'll get them integrated into the download?
- Thanks for the link Mike. I believe the code in that blog post is very similar to my filter. I've also got support for an ini-file override of the header name.
- This filter does not do anything with the headers. It looks for a header (X-Forwarded-For by default, but overridable by a ini file). If that header is found, it replaces the contents of the IIS C-IP value with the contents of that header.