I'm using nginx as a reverse proxy that handles port 80 -> 443 redirect and then onto a varnish cache (port 8181) that talks to an Apache2.4 backend (port 8182) serving a drupal (7.69) site.
I've configured nginx to forward the client IP as:
proxy_pass http://127.0.0.1:8181;
proxy_read_timeout 90;
proxy_connect_timeout 90;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header X-Forwarded-Host $remote_addr;
proxy_set_header Host $host;
In varnish vcl_recv I'm adding:
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;
}
}
In apache I have installed remoteip module and set the following config:
RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 127.0.0.1
In drupal's settings.php I have
$conf['reverse_proxy'] = True;
$conf['reverse_proxy_header'] = 'X-Forwarded-For';
$conf['reverse_proxy_addresses'] = array('127.0.0.1');
...But drupal seems to be nonetheless seeing and loggin only the localhost (127.0.0.1) ip rather than the genuine client IP. So forms are being logged as submitted not from the genuine user but the server itself.
I'm wondering if my varnish config is off, because I'm also proxying from nginx and bypassing varnish to go directly to a forum which bypasses drupal (it's SMF) but runs on the same apache config; the forum is logging the client IPs sent from nginx (using the same header changes and apache remoteip config) just fine.
I'd be grateful for guidance / suggestions.
Your Varnish configuration for X-Forwarded-For
is correct, in theory.
In practice you don't even need to set X-Forwarded-For
in Varnish, because Varnish will do this automatically.
As far as Drupal configuration goes, it may have something to do with the reverse_proxy_header
. I stumbled upon this piece of Drupal 7 documentation: https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/ip_address/7.x.
The crucial part of the code on that page is the following:
$reverse_proxy_header = variable_get('reverse_proxy_header', 'HTTP_X_FORWARDED_FOR');
Apparently this ip_address()
function can be made aware of the X-Forwarded-For
header through a configuration parameter.
However, the header format is not the official HTTP format, but rather the way that the PHP $_SERVER
superglobal stores it. In this case the format would be HTTP_X_FORWARDED_FOR
.
So please try replacing $conf['reverse_proxy_header'] = 'X-Forwarded-For';
with $conf['reverse_proxy_header'] = 'HTTP_X_FORWARDED_FOR';
.