Reverse proxy configuration for Apache or nginx with varnish

A while ago I wrote a blog post about how you should tell your Drupal 7 site that the webserver is using a reverse proxy setup to make sure the correct ip adress of visitors gets sent to Drupal.

If you want to have the correct ip address in your Apache or nginx logs too, you need to add some configuration. Two things you need to take care of:

Varnish vcl configuration

This is an example for a varnish 3.x vcl, where you need to add the X-Forwarded-For header in the vcl_recv function:

sub vcl_recv {
 if (req.restarts == 0) {
    if (!req.http.X-Forwarded-For) {
      set req.http.X-Forwarded-For = client.ip;
    }
  }

Sidenote: If you want a fully working vcl for Drupal or WordPress, you should take a look at Mattias’ github project for varnish 3.x or varnish 4.x templates.

Apache configuration

After the X-Forwarded-For header has been added by varnish, we can tell apache to use it for logs. This is an example from an Ubuntu 12.04 LTS server and the file /etc/apache2/apache2.conf, other setups might be similar.

Our vhosts use the “combined” log method, so that’s actually the only one you need to update. But it’s nice to keep everything in line and update all the log formats that used %h before:

# The following directives define some format nicknames for use
# with a CustomLog directive (see below).
# If you are behind a reverse proxy, you might want to change %h
# into %{X-Forwarded-For}i
#
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

In the example above I already replaced the %h variable with the X-Forwarded-For variable.

Nginx configuration

Nginx has a very simple configuration option you have to change. In your vhost config you have to add this code in the server block:

server {

  ...

  # Pass the real ip from varnish/
  set_real_ip_from 127.0.0.1;/
  real_ip_header X-Forwarded-For;

  ...

This ofcourse assumes the varnish server runs on the same server as the webserver. You might need to change this to the ip of your actual varnish server if it runs on another ip.

If you’ve done all of this correctly, you should now see the actual client ip addresses appear in your webserver logs.

comments powered by Disqus