Uważam, że kluczem do rozwiązania problemów X-Forwarded-For w przypadku połączenia wielu adresów IP jest ostatnio wprowadzona opcja konfiguracji real_ip_recursive(dodana w nginx 1.2.1 i 1.3.0). Z dokumentów Nginx Realip :
Jeśli włączone jest wyszukiwanie rekurencyjne, oryginalny adres klienta pasujący do jednego z zaufanych adresów jest zastępowany ostatnim niezaufanym adresem wysłanym w polu nagłówka żądania.
nginx domyślnie pobierał ostatni adres IP w łańcuchu, ponieważ był to jedyny, który był uważany za zaufany. Ale dzięki nowej real_ip_recursivewłączonej i wielu set_real_ip_fromopcjom możesz zdefiniować wiele zaufanych serwerów proxy, a ona pobierze ostatni niezaufany adres IP.
Na przykład przy tej konfiguracji:
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;
I nagłówek X-Forwarded-For, w wyniku czego:
X-Forwarded-For: 123.123.123.123, 192.168.2.1, 127.0.0.1
nginx wybierze teraz 123.123.123.123 jako adres IP klienta.
Jeśli chodzi o to, dlaczego nginx nie wybiera tylko adresu IP znajdującego się najbardziej z lewej strony i wymaga jawnego zdefiniowania zaufanych serwerów proxy, ma to na celu zapobieganie łatwemu fałszowaniu adresów IP.
Powiedzmy, że prawdziwy adres IP klienta to 123.123.123.123. Powiedzmy też, że klient nie ma nic dobrego, a oni próbują sfałszować swój adres IP 11.11.11.11. Wysyłają żądanie do serwera z tym nagłówkiem już na miejscu:
X-Forwarded-For: 11.11.11.11
Ponieważ odwrotne serwery proxy po prostu dodają adresy IP do tego łańcucha X-Forwarded-For, powiedzmy, że wygląda to tak, gdy nginx do niego dojdzie:
X-Forwarded-For: 11.11.11.11, 123.123.123.123, 192.168.2.1, 127.0.0.1
Jeśli po prostu złapiesz adres znajdujący się najbardziej po lewej stronie, pozwoli to klientowi łatwo sfałszować swój adres IP. Ale w powyższej przykładowej konfiguracji nginx, nginx będzie ufał tylko dwóm ostatnim adresom jako proxy. Oznacza to, że nginx poprawnie wybierze 123.123.123.123jako adres IP, mimo że sfałszowany adres IP jest w rzeczywistości najbardziej lewy.