Exchange Original Client IP on IIS Logs


Today I'm going to write about a project I was recently involved with that involves Microsoft Exchange server and Citrix NetScaler.

One on the most common scenario when load balancing Exchange servers - and any other website as a matter of fact - is that on the web server logs, the IP of the client is not the IP of the machine that makes the requests but the IP of the load balancer instead. This is normal since the connections from the clients are terminated on the load balancer and not the web server. The load balancer opens new connections towards the web servers in order to serve the request. Lets take the following architecture for example.

The connection from Client1 will be terminated on the Load Balancer and then the Load Balance will create a new connection to the Server2 server. Since the connection to the web server is initiated from the load balancer, the load balancer's IP will be the client IP as far as the web server is concerned.

There are two possible solution to this. Fist, we can add an extra field on the log using the advanced logging feature of IIS. Second, we can use an ISAPI filter that will replace the IP of the client with the client's real IP. To be honest, I prefer the first approach since is can be enabled out of the box and does not require any custom code.

Let's see how we can accomplish that with the necessary configuration on the load balancer and the web server.

First, in order for the web server to log the original client IP, we have to pass that IP to it. So we have to configure the load balancer. Most load balancers - if not all - have the ability to forward the client IP in a field call X-Forwarded-For in the request to the web server for this purpose. So first of all, enable that feature on the load balancer.

Next, we have to configure the web server logging feature. I'm only going to talk about IIS but I'm sure you can find your way for other web servers. Open up the IIS Manager and click on the web site you want to configure and then open logging. In my case it's the Default Web Site since this is the front end for the Exchange server.

Click "Select Fields" and then click "Add Field". On the Add Custom Field form, select the name of the field as you want it to appear in the log, "Request Header" as the source type and "X-Forwarded-For" as the source and click OK. The new filed will be listed under the custom fields pane.

One caveat though, this will restart the web site so you probably have to disable each server in the load balancer in order to avoid failed requests.

Moreover, from the time you add a custom field in IIS logging, the names of the log files change because the string "_x" is added to the file name.

In case you have multiple servers, it would be much easier to use Powershell to add the custom field, wouldn't it?

The following command will configure the field, but Powershell has to run with elevated privileges.

Import-Module WebAdministration
New-ItemProperty 'IIS:\Sites\Default Web Site' -Name logfile.customFields.collection -Value @{logFieldName='OriginalClientIP';sourceType='RequestHeader';sourceName='X-Forwarded-For'}

And remember: Always test the changes you are going to perform on a lab environment first!

Popular posts from this blog

Domain Controller Machine Password Reset

Configuring a Certificate on Exchange Receive Connector

Verbose Parameter Passing to cmdlet inside Function