Я вважаю, що ключ до вирішення неприємностей X-Forwarded-For, коли кілька IP-адрес пов'язані ланцюгом, - це нещодавно введений варіант конфігурації real_ip_recursive
(доданий у nginx 1.2.1 та 1.3.0). З документів nginx realip :
Якщо ввімкнено рекурсивний пошук, оригінальна адреса клієнта, яка відповідає одній із довірених адрес, замінюється останньою недовіреною адресою, надісланою в полі заголовка запиту.
nginx хапав останню IP-адресу в ланцюзі за замовчуванням, тому що це був єдиний, якому вважали, що йому довіряють. Але з новим real_ip_recursive
увімкненим і з кількома set_real_ip_from
параметрами ви можете визначити кілька надійних проксі-серверів, і він отримає останній недовірений IP-адресу.
Наприклад, за допомогою цього конфігурації:
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 вибере 123.123.123.123 як IP-адресу клієнта.
Що стосується того, чому nginx не просто вибирає найбільшу ліву IP-адресу і вимагає чітко визначити надійні проксі-сервери, це запобігти простому підробленню IP-адреси.
Скажімо, справжня IP-адреса клієнта така 123.123.123.123
. Скажімо також, що клієнту нічого поганого, і вони намагаються підробити свою IP-адресу 11.11.11.11
. Вони надсилають запит на сервер із уже встановленим заголовком:
X-Forwarded-For: 11.11.11.11
Оскільки зворотні проксі-сервери просто додають IP-адреси до цього ланцюга X-Forwarded-For, скажімо, він закінчується таким чином, коли nginx потрапляє на нього:
X-Forwarded-For: 11.11.11.11, 123.123.123.123, 192.168.2.1, 127.0.0.1
Якщо ви просто схопили найбільшу ліву адресу, це дозволить клієнту легко підробити свою IP-адресу. Але з наведеним вище прикладом nginx config, nginx буде довіряти останнім двом адресам лише проксі. Це означає, що nginx буде правильно обраний 123.123.123.123
як IP-адреса, незважаючи на те, що підроблений IP-код насправді є самим лівим.