Getting Apache 2.4 access logs to show client IP instead of 127.0.0.1 with Varnish using mod_remoteip

11,797

I finally got the client IPs in the log and I found the last step here:

Here are the steps to getting it to work:

  1. Get Varnish to pass a header to Apache with the client IP. You do this by including this bit of code (found in this answer) at the very beginning of your vcl_recv:

    if (req.restarts == 0) {
      if (req.http.X-Forwarded-For) {
        set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
      } else {
        set req.http.X-Forwarded-For = client.ip;
      }
    }
    
  2. Now enable mod_remoteip in Apache.

  3. Edit your Apache config to tell mod_remoteip what header contains the client IP (from Apache docs). I'm using X-Forwarded-For, but I suppose this could be anything as long as it matches what you've configured Varnish to pass along:

    RemoteIPHeader X-Forwarded-For

  4. If you restarted Apache and Varnish right now, I bet Apache will now reference the client IP instead of 127.0.0.1 everywhere. Except in the access logs which is where I've been checking. To get the access logs to show the client IP, we need to modify the log format Apache it's using. In my case, this was the "combined" format. This was my breakthrough and I found it here which links to this excellent information for our purposes.

This is what my combined log format looked like:

LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

And I just substituted %a in where %h was and this is what it looks like:

LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

And finally, here's what a block of my Apache config file looks like (mod_remoteip loading prior to it):

# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.
# Use mod_remoteip instead.
RemoteIPHeader X-Forwarded-For

LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
Share:
11,797
curiouser
Author by

curiouser

Product-minded software engineer specializing in front-end web

Updated on June 08, 2022

Comments

  • curiouser
    curiouser almost 2 years

    For the life of me, I couldn't get mod_remoteip to get client IPs in my Apache access logs. I'm working on a Virtualmin setup with Varnish 4 installed in front of Apache 2.4.7. How do you get it working?

  • Taylor Taff
    Taylor Taff over 9 years
    Works perfectly and think it will lead me to customising my logs completely, httpd.apache.org/docs/current/mod/mod_log_config.html#format‌​s has a lot to pick from.
  • Johnny Tisdale
    Johnny Tisdale almost 3 years
    According to the documentation for mod_remoteip: "It is critical to only enable this behavior from intermediate hosts (proxies, etc) which are trusted by this server, since it is trivial for the remote useragent to impersonate another useragent." You can do this with the RemoteIPInternalProxy directive. For example: RemoteIPInternalProxy 10.0.2.0/24