NGinx $proxy_add_x_forwarded_for и real_ip_header
У меня есть webapp под NGinx и другим лобовым балансиром нагрузки, что-то вроде ниже (x.x.x.x = IP-адрес):
Клиент (a.a.a.a) → LB (b.b.b.b) → NGX (c.c.c.c) → WEBAPP (d.d.d.d)
Вот фрагмент моей конфигурации NGinx:
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
real_ip_header X-Forwarded-For;
set_real_ip_from b.b.b.b;
real_ip_recursive on;
}
- Балансировщик нагрузки добавляет поле
X-Forwarded-For
с клиентом IP
X-Forwarded-For
= a.a.a.a
- NGinx ищет реальный IP-адрес клиента в заголовке
X-Forwarded-For
, опустив LB IP (b.b.b.b
) и изменив $remote_addr
с b.b.b.b
на a.a.a.a
, поэтому proxy_set_header X-Real-IP $remote_addr
станет true (OK, что я хочу!)
НО, NGinx также завершает заголовок X-Forwarded-For
с a.a.a.a
IP вместо b.b.b.b
- WEBAPP получает следующие заголовки:
X-Forwarded-For
= a.a.a.a, a.a.a.a
X-Real-IP
= a.a.a.a
- > X-Forwarded-For
должно быть a.a.a.a, b.b.b.b
Мне нужна возможность установки первого proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
, а затем поиск реального IP и замена значения $remote_addr
.
Кто-нибудь может помочь мне решить эту проблему?
Ответы
Ответ 1
$proxy_add_x_forwarded_for
равен $http_x_forwarded_for,$remote_addr
, и переменная $remote_addr
будет изменена при использовании http_realip_module
. Таким образом, вы не получите последний адрес прокси в этом заголовке. Изменение порядка директив не будет иметь эффекта, потому что конфигурация nginx
декларативна.
Когда используется $realip_remote_addr
переменная $realip_remote_addr
(nginx >= 1.9.7
) может использоваться в качестве исходного $remote_addr
. Таким образом, вы можете установить свой заголовок X-Forwarded-For
следующим образом:
proxy_set_header X-Forwarded-For "$http_x_forwarded_for, $realip_remote_addr";
Ответ 2
Такая же проблема. Это раздражает, и я не уверен, что это особенность или ошибка:)
Я знаю, что это не решение, но я удалил real_ip_header и просто использовал первый ipaddress X-Forwarded-For, чтобы получить IP-адрес клиента, где мне это нужно. (например, журналы).
Ответ 3
Недавно я столкнулся с одной и той же "проблемой" и пришел к выводу, что это поведение вызвано директивой real_ip_recursive on;
.
Из nginx realip docs:
Если рекурсивный поиск включен, исходный адрес клиента, соответствующий одному из доверенных адресов, заменяется последним недоверенным адресом, отправленным в поле заголовка запроса.
Вы указали, что хотите доверять b.b.b.b
(из-за вашего set_real_ip_from b.b.b.b;
Итак, что вы ожидаете, т.е. a.a.a.a, b.b.b.b
будет заменено на a.a.a.a, a.a.a.a
.
Источник, который дал мне это понять: https://serverfault.com/info/314574/nginx-real-ip-header-and-x-forwarded-for-seems-wrong