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