X-Forwarded-For HTTP Module For IIS7, Source Included!
For those who of you that are having problems with logging client addresses in their server logs because you are running your web servers behind a proxy of some sort, never fear, your solution is here. For those that don't, I already discussed in my previous posts about what the X-Forwarded-For header is so feel free to click back into those to read about it.
History
Back in September, 2005 I wrote and posted a 32-bit ISAPI filter that extracted the X-Forwarded-For header value and replaced the c-ip value (client ip) that is stored in the server logs. Lots of folks have found this useful over time and I was eventually asked for a 64-bit version which I posted about in August, 2009.
The Question
Well, it looks like it's time for the next generation for this filter… I received an email from a colleague here at F5 telling me that his customer didn't want to deploy any more ISAPI filters in their IIS7 infrastructure. IIS7 introduced the concept of IIS Modules that are more integrated into the whole pipeline and was told that Microsoft is recommending folks move in that direction. I was asked if I had plans to port my ISAPI filter into a HTTP Module.
The Answer
Well, the answer was "probably not", but now it's changed to a "yes"!
The Solution
In reading about IIS Module, I found that you can develop in managed (C#/VB) or Native (C++) code. I loaded up the test C# project to see if I could get it working. In a matter of minutes I had a working module that intercepted the event when logging occurs. The only problem was that from managed code, I could find no way to actually modify the values that were passed to the logging processor. This was a problem so I scrapped that and moved to a native C++ module. After a little while of jumping through the documentation, I found the things I needed and pretty soon I had a working HTTP module that implemented the same functionality as the ISAPI filter.
Download
The new Http Module hasn't had much testing done so please test it out before you roll it out into production. I've made the source available as well if you find an issue and care to fix it. Just make sure you pass back the fixes to me B-).
The filter will require installation into IIS in order for you to be able to add it to your applications. Both distributions include a readme.txt file with an example installation procedure. Make sure you use the Release builds for the appropriate platform (x86 or x64) unless you are in need of some troubleshooting as the Debug build will dump a lot of data to a log file. The module supports customizable headers if you are using something other than X-Forwarded-For. Instructions for using that are in the readme.txt file as well.
If you have any issues with using this, please let me know on this blog. Keep in mind that this is an unsupported product, but I'll do my best to fix any issues that come up. I'm even open to enhancements if you can think of any.
Enjoy!
-Joe
- @James - I've heard back from a few users that this is working fine. I've been using it internally on my test systems without any problem so I don't think there should be any issue with using it in prod.
- @Carl - Thanks for the pointer. My module will work with our without ARR in place so hopefully those that are using external load balancers will take a look at my module. I've also got the ISAPI filter for IIS6 and below available for folks to use. I've also made source available for all my distributions so anyone can take a look at what I've done.
- @Kyle B - not sure how to deal with that as I'd have to do some testing to try to simulate the IIS caching and I'm not sure how exactly to do that one. I'm no expert, I just patched this together and it worked for the test cases I had. Let me know if you find a solution to the server side caching and I'll get it integrated into the distribution.
- JRahmAdminDoes this only modify the X-Forwarded-For header that is stored in the IIS logs? Or if I use Request.ServerVariables["X-Forwarded-For"], will I also see the new value? What if the request is over SSL?
- Hi all, I'm still here, just have let this post go a while too long. The XFF filter was originally written for us to use with DevCentral and I chose to make the source available to the public. I wrote the IIS Module version in request to those moving to IIS7. The source is available for those that are willing to modify it if you find any problems.
- @Mac, thanks so much for contributing an update. I have no problem with you hosting it on github (I probably should have done that in the first place). I'll go ahead and update my code and issue a rebuild based on your changes after I give it a review.
- Actually, your changes were fairly simple so I went ahead and updated my sources/binaries as well with your updates!
- @Matt, unfortunately, the c-ip value in IIS is the IP of the client side connection to the LTM, it's not a header value that can be changed with an iRule. You can setup your LTM configs to pass through the origin address but in some situations that isn't possible when NAT is required. The XFF Filter, looks into the HTTP request and if a X-Forwarded-For header is found, it injects that value to the log during a log operation.
- Don_MacVittie_1Historic F5 AccountI have Microsoft Threat Management Gateway 2010 in the mix. It does not seem to support X-Forward-For as yet either. Any suggestions on how one might have it generate the XFF header?
- Those might be the latest ones. Not much was changed in this code from what I remember after the original build. I'll check it out in the morning.