Acredito que a chave para resolver problemas de X-Forwarded-For quando vários IPs são encadeados é a opção de configuração introduzida recentemente, real_ip_recursive
(adicionada no nginx 1.2.1 e 1.3.0). A partir dos docs reais nginx :
If recursive search is enabled, an original client address that matches one of the trusted addresses is replaced by the last non-trusted address sent in the request header field.
nginx estava pegando o último endereço IP na cadeia por padrão porque era o único que era considerado confiável. Mas com as novas opções real_ip_recursive
ativadas e com vários set_real_ip_from
, você pode definir vários proxies confiáveis e buscar o último IP não confiável.
Por exemplo, com esta configuração:
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;
E um cabeçalho X-Forwarded-For, resultando em:
X-Forwarded-For: 123.123.123.123, 192.168.2.1, 127.0.0.1
O nginx agora selecionará 123.123.123.123 como o endereço IP do cliente.
Quanto ao motivo pelo qual o nginx não escolhe apenas o endereço IP mais à esquerda e exige que você defina explicitamente proxies confiáveis, é para evitar a falsificação de IP fácil.
Digamos que o endereço IP real de um cliente seja 123.123.123.123
. Digamos também que o cliente não serve para nada, e eles estão tentando imitar o endereço IP para 11.11.11.11
. Eles enviam uma solicitação para o servidor com este cabeçalho já em vigor:
X-Forwarded-For: 11.11.11.11
Como os proxies reversos simplesmente adicionam IPs a essa cadeia X-Forwarded-For, digamos que ela fique assim quando o nginx chegar a ela:
X-Forwarded-For: 11.11.11.11, 123.123.123.123, 192.168.2.1, 127.0.0.1
Se você simplesmente pegasse o endereço mais à esquerda, isso permitiria que o cliente falsificasse facilmente seu endereço IP. Mas com o exemplo acima, nginx config, o nginx confiará apenas nos dois últimos endereços como proxies. Isso significa que o nginx escolherá corretamente 123.123.123.123
como o endereço IP, apesar de o IP falso ser o mais à esquerda.