Can nginx handle duplicate X-Forwarded-For headers?

When a user uses a proxy (Google data saver, etc.), the browser adds X-Forwarded-For to the real IP address of the clients on the server. Our load balancer sends all the headers + client IP address as the X-Forwarded-For header to the nginx server. Examples of request headers:

X-Forwarded-For: 1.2.3.4
X-Forwarded-Port: 80
X-Forwarded-Proto: http
Host: *.*.*.*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,tr;q=0.6
Save-Data: on
Scheme: http
Via: 1.1 Chrome-Compression-Proxy
X-Forwarded-For: 1.2.3.5
Connection: Keep-alive

Is there a way to pass both X-Forwarded-For headers to php, respectively?

+4
source share
4 answers

TL DR

  • nginx: fastcgi_param HTTP_MERGED_X_FORWARDED_FOR $http_x_forwarded_for
  • php: $_SERVER['HTTP_MERGED_X_FORWARDED_FOR']

Description

You can access all http headers with a variable$http_<header_name> . When using this variable, nginx will even do header merging for you, therefore

CustomHeader: foo
CustomHeader: bar

Returns value:

foo, bar

, , , php fastcgi_param

fastcgi_param HTTP_MERGED_X_FORWARDED_FOR $http_x_forwarded_for

:

nginx:

location ~ \.php$ {
    fastcgi_pass unix:run/php/php5.6-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param HTTP_MERGED_X_FORWARDED_FOR $http_x_forwarded_for;
    include fastcgi_params;
}

test.php

<?php
die($_SERVER['HTTP_MERGED_X_FORWARDED_FOR']);

, , , curl:

curl -v -H 'X-Forwarded-For: 127.0.0.1' -H 'X-Forwarded-For: 8.8.8.8' http://localhost/test.php

:

* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /test.php HTTP/1.1
> Host: localhost
> User-Agent: curl/7.47.0
> X-Forwarded-For: 127.0.0.1
> X-Forwarded-For: 8.8.8.8
> 
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Wed, 01 Nov 2017 09:07:51 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< 
* Connection #0 to host localhost left intact
127.0.0.1, 8.8.8.8

Boom! , X-FORWARDED-FOR, - $_SERVER['HTTP_MERGED_X_FORWARDED_FOR']

, , , HTTP_MERGED_X_FORWARDED_FOR.

+5

, , -. , apache, - nginx.

curl -H "X: Y" -H "X: Z"  http://localhost:8088/router.php | jq

Apache

apache

{
  "HEADERS": {
    "Host": "localhost:8088",
    "User-Agent": "curl/7.47.0",
    "Accept": "*/*",
    "X": "Y, Z"
  }
}

, apache, apache ,. , ,,

$ curl -H "X: Y, A" -H "X: Z"  http://localhost:8088/router.php | jq
{
  "HEADERS": {
    "Host": "localhost:8088",
    "User-Agent": "curl/7.47.0",
    "Accept": "*/*",
    "X": "Y, A, Z"
  }
}

Nginx

nginx

{
  "HEADERS": {
    "X": "Z",
    "Accept": "*/*",
    "User-Agent": "curl/7.47.0",
    "Host": "localhost"
  }
}

, Nginx PHP-FPM, . PHP-FPM . , script .

-1: fastcgi_param

@AronCederholm , , FASTCGI_PARAM

, .

fastcgi_param X-Forwarded-For $http_x_forwarder_for;

, .

fastcgi_param X-Forwarded-For $http_x_forwarded_for;

. getallheaders(). $_SERVER[], :

$ curl -v -H 'X-Forwarded-For: 127.0.0.1' -H 'X-Forwarded-For: 8.8.8.8' http://localhost/router.php | jq
{
  "HEADERS": {
    "X-Forwarded-For": "8.8.8.8",
    "Accept": "*/*",
    "User-Agent": "curl/7.47.0",
    "Host": "localhost"
  },
  "SERVER": {
    "USER": "vagrant",
    "HOME": "/home/vagrant",
    "HTTP_X_FORWARDED_FOR": "8.8.8.8",
    "HTTP_ACCEPT": "*/*",
    "HTTP_USER_AGENT": "curl/7.47.0",
    "HTTP_HOST": "localhost",
    "X-Forwarded-For": "127.0.0.1, 8.8.8.8",

, Nginx PHP-FPM, . PHP, .

  • apache Nginx. nginx unix- apache - nginx
  • Nginx Apache
  • Nginx . .

https://github.com/giom/nginx_accept_language_module

https://github.com/openresty/headers-more-nginx-module

+1

ELB $realip_remote_addr, , ​​ nginx 1.9.7, nginx.

. ngx_http_realip_module

, :

set_real_ip_from 127.0.0.1;
set_real_ip_from 192.168.2.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

X-Forwarded-For, :

X-Forwarded-For: 123.123.123.123, 192.168.2.1, 127.0.0.1

nginx IP 123.123.123.123 IP- , .

$realip_remote_addr

0

X-Forwarded-For - . . , ip , . ip , X-Real-IP -, .

0

Source: https://habr.com/ru/post/1652034/


All Articles