Varnish + nginx with php and REMOTE_ADDR issue using http_realip_module
Maxim Dounin
mdounin at mdounin.ru
Sat Jun 11 05:13:30 MSD 2011
Hello!
On Fri, Jun 10, 2011 at 08:41:30PM -0300, Flavio Torres wrote:
> 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 '<table border="1">';
>
> foreach($_SERVER as $k => $v) {
> echo '<tr><td>'.$k.'</td><td>'.$v.'</td></tr>';
> }
> echo '</table>';
> ?>
>
>
>
> 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.
> 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
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.
> 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;
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 Dounin
More information about the nginx
mailing list