Fix Logging of Proxied IPs in Apache

Problem

When you’re using apache behind a reverse proxy, the logs on the back-end machines will typically show the IP belonging the proxy server instead of the client that made the request. This can be annoying, but is easily remedied.

Solution

Most proxies I’ve seen will add a header to the request that tells the back-end machine where the original request is coming from. In the case of apache, it sets the X-Forwarded-For header. In order to modify logging to properly use this, you can do something similar to the following.

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %V %D " proxy
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %V %D " direct

SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded

CustomLog logs/direct_access_log direct env=!forwarded
CustomLog logs/proxy_access_log proxy env=forwarded

The first two lines set custom log formats. In my example here, I’m using the typical “combined” format with a couple extra variables at the end – the host that the request was made to and the duration of the request. The SetEnvIf line checks to see if the X-Forwarded-For header has been set, and if it matches the pattern of an IP address, it sets an environment variable called “forwarded”. The two CustomLog commands tell apache where and how to log, and under which conditions. The last part of each of those lines is a condition check. In the first case, apache will log if the forwarded variable isn’t set, e.g. when traffic isn’t being proxied. The second line covers traffic which has the forwarded variable set. It’s worth noting that both CustomLog directives could have logged to the same file. I chose to make them separate for clarity.

It’s also worth noting that this can be easily modified to log other header variables if your proxy is setting something other than X-Forwarded-For. Just replace any instances of X-Forwarded-For with the appropriate header, and you should be good to go.

If you’re seeing multiple IP addresses in your logs, as shown below, you’ll need to configure your proxy box to strip off the X-Forwarded-For headers from the requests it receives before sending them through to the backend machines. It seems as though apache propagates that header from other proxies by default, so it needs to be removed if you want your logs to be tidy.

192.168.1.105, 200.40.46.54 - - [17/Apr/2012:12:50:11 -0400] "GET /favicon.ico HTTP/1.1" 200 - "-" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.152 Safari/535.19"

Thankfully, this is pretty easy to do in apache if it’s also acting as your proxy. Just stick the following line into your apache configuration in the same context in which you have the proxy configured.

RequestHeader unset X-Forwarded-For

Related reading:

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>