Varnish + nginx with php and REMOTE_ADDR issue using http_realip_module

Hello,

Please, I’m trying to use http_realip_module
(http://wiki.nginx.org/NginxHttpRealIpModule#real_ip_header) to get the
X-Forwarded-For IP in my .php, but I’m suspecting something is wrong,
because that looks like it should work.

My setup is:

LB > Varnish FE network pool (10.110.0.0/22) > Varnish BE - same server,
another iface - (10.214.0.0/22) > LB 10.214.0.0/22 > nginx BE pool
10.214.0.0/22

When I set:

    location ~ \.php$ {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME

/net/nfs_parceiros_1/ftorres.com.br$fastcgi_script_name;
}

I get these values from my simple php test page:

<?php echo ''; foreach($_SERVER as $k => $v) { echo ''; } echo '
'.$k.' '.$v.'
'; ?>

SERVER_SOFTWARE nginx/0.8.53
REMOTE_ADDR 10.214.3.250
SERVER_ADDR 10.214.0.56
HTTP_X_FORWARDED_FOR 10.214.0.47

When I set:

    location ~ \.php$ {

            set_real_ip_from 10.214.0.0/22;
            #set_real_ip_from 10.110.0.0/22;
            real_ip_header X-Forwarded-For;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME

/net/nfs_parceiros_1/ftorres.com.br$fastcgi_script_name;
}

I get:

REMOTE_ADDR 10.110.3.250
SERVER_ADDR 10.214.0.56
HTTP_X_FORWARDED_FOR 10.214.0.48

Oops, now I can see 10.110.0.0/22 (my front end network), but nothing
about my x-forwarded-for, now I fixed it and add the FE network :

    location ~ \.php$ {

            add_header X-Fw-For $proxy_add_x_forwarded_for;
            set_real_ip_from 10.214.0.0/22;
            set_real_ip_from 10.110.0.0/22;
            real_ip_header X-Forwarded-For;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME

/net/nfs_parceiros_1/ftorres.com.br$fastcgi_script_name;
}

Then, I get:

REMOTE_ADDR 10.110.3.250
SERVER_ADDR 10.214.0.56
HTTP_X_FORWARDED_FOR 10.214.0.46

Any of these configurations shown the X-forwarded-for at remote_addr
field, and the x-fw-for Header its working:

HTTP/1.1 200 OK
Server: nginx
Date: Fri, 10 Jun 2011 23:27:19 GMT
Content-Type: text/html
Connection: keep-alive
X-Fw-For: 200.226.123.253, 10.110.3.250, 10.110.3.250

I fixed it adding the following configuration at fastcgi_param file:

            set  $addr  $remote_addr;
            if ($proxy_add_x_forwarded_for ~

“^(?:^|,)\s*(\d+.\d+.\d+.\d+)\s*”) {
set $addr $1;
}

fastcgi_param HTTP_X_FORWARDED_FOR $addr;

So Please, I’d like to know if http_realip_module is doing the job as it
should or if these fixed issue should be ok for what I’m trying do do.

Thanks and sorry about my english

Hello!

On Fri, Jun 10, 2011 at 08:41:30PM -0300, Flavio Torres wrote:

another iface - (10.214.0.0/22) > LB 10.214.0.0/22 > nginx BE pool
}
echo ‘’;
?>

SERVER_SOFTWARE nginx/0.8.53
REMOTE_ADDR 10.214.3.250
SERVER_ADDR 10.214.0.56
HTTP_X_FORWARDED_FOR 10.214.0.47

Just a side note: HTTP_X_FORWARDED_FOR should be something like
“200.226.123.253, 10.110.3.250” here according to what you’ve
showed later, it’s unclear why you see only one address here.

            fastcgi_param SCRIPT_FILENAME

Oops, now I can see 10.110.0.0/22 (my front end network), but nothing
include fastcgi_params;
HTTP_X_FORWARDED_FOR 10.214.0.46
Realip module only uses last address from X-Forwarded-For header,
the one which was added by last (trusted) proxy. It doesn’t try
to follow X-Forwarded-For chain until non-trusted address appears
(though it probably should, at least with some configuration
option). That’s why you see the same REMOTE_ADDR here as in
previous test.

Simpliest solution would be to set X-Real-Ip header on your real
frontend and use it instead. Not sure if Varnish can do it
though.

I fixed it adding the following configuration at fastcgi_param file:

            set  $addr  $remote_addr;
            if ($proxy_add_x_forwarded_for ~

“^(?:^|,)\s*(\d+.\d+.\d+.\d+)\s*”) {
set $addr $1;
}

fastcgi_param HTTP_X_FORWARDED_FOR $addr;

This is not correct and insecure. You use first ip address from
X-Forwarded-For header which may be easily set by malicious client
(and likely will contain private ip addresses from non-malicious
clients behind real corporate proxies and so on).

Maxim D.