Рейтинг:3

Как я могу заставить nginx не переопределять x-forwarded-for при проксировании?

флаг cn

У меня есть сервер nginx за балансировщиком нагрузки, сервер nginx передает запросы различным службам, но в этом случае контейнер докеров работает с apache. Балансировщик нагрузки правильно устанавливает X-Forwarded-For, но к тому времени, когда он попадает в контейнер докера, X-Forwarded-For был установлен на IP-адрес LB.

У меня есть это в конфигурации nginx:

/etc/nginx/conf.d/real_ip.conf
set_real_ip_from {{LB IP}};
real_ip_header X-Настоящий-IP;
real_ip_recursive на;

а это виртуальный хост:

сервер {
    слушать 443 ssl;
    слушать [::]:443 ssl;
    имя_сервера *.домен домен;
    включить /etc/nginx/snippets/domain_ssl.conf;

  add_header X-Nginx-Debug «привет»;

  proxy_pass_request_headers включен;

  место расположения    / {
    proxy_pass_request_headers включен;
    proxy_pass http://container-php;
    прокси_http_версия 1.1;
    proxy_set_header Обновить $http_upgrade;
    proxy_set_header Соединение "обновление";
    proxy_set_header Хост $http_host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Remote-Addr $remote_addr;
    proxy_set_header X-Real-IP $http_x_real_ip;
    proxy_set_header X-Header-Test "Hello World - $http_x_forwarded_for";
    proxy_set_header X-Forwarded-Proto $ схема;
  }
}

Но что я получаю из контейнера:

массив (19) {
  ["Соединение"]=>
  строка(7) "обновить"
  ["Хост"]=>
  строка(19) "домен"
  ["X-Перенаправлено-Для"]=>
  строка (12) "{{LB IP}}"
  ["Тест X-заголовка"]=>
  строка (13) "Привет, мир -"
  ["X-Forwarded-Proto"]=>
  строка(5) "https"
  ["управление кешем"]=>
  строка (9) "максимальный возраст = 0"
  ["сек-ч-уа"]=>
  string(64) "" Не бренд";v="99", "Google Chrome";v="97", "Chromium";v="97""
  ["sec-ch-ua-mobile"]=>
  строка(2) "?0"
  ["sec-ch-ua-platform"]=>
  строка(9) ""Windows""
  ["обновление-небезопасные-запросы"]=>
  строка(1) "1"
  ["агент пользователя"]=>
  string(114) "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, например Gecko) Chrome/97.0.4692.71 Safari/537.36"
  ["принять"]=>
  строка(135) "текст/html,приложение/xhtml+xml,приложение/xml;q=0.9,изображение/avif,изображение/webp,изображение/apng,*/*;q=0.8,приложение/signed-exchange;v =b3;q=0,9"
  ["sec-fetch-site"]=>
  строка(4) "нет"
  ["sec-fetch-mode"]=>
  строка(8) "навигация"
  ["sec-fetch-user"]=>
  строка(2) "?1"
  ["sec-fetch-dest"]=>
  строка(8) "документ"
  ["принять кодировку"]=>
  string(17) "gzip, deflate, br"
  ["принять-язык"]=>
  string(26) "en-GB,en-US;q=0.9,en;q=0.8"
}

В частности, X-Real-IP, X-Fowarded-For, похоже, не установлены, равно как и remote_addr. Файлы, обслуживаемые непосредственно из nginx, имеют правильную настройку x-forwarded-for, поэтому LB отправляет правильный заголовок.

Я пропустил шаг?

Рейтинг:2
флаг br

Я думаю, что проблема в вашей реальной конфигурации IP.

set_real_ip_from {{LB IP}};

real_ip_header X-Настоящий-IP;

real_ip_recursive на;

Когда real_ip_header должен быть (в вашем случае) установлен на X-Forwarded-For. Я предполагаю, что ваш заголовок X-Forwarded-For из LB выглядит так:

X-Forwarded-For: {{Исходный IP-адрес клиента}}, {{LB ip}}

Поэтому, когда вы устанавливаете real_ip_header (заголовок, используемый для замены IP-адреса клиента) на X-Forwarded-For, он будет соответствовать исходному IP-адресу клиента. Исходный клиент теперь должен находиться под переменной $realip_remote_addr, которую вы можете адресовать в proxy_set_header X-Forwarded-For :

proxy_set_header X-Forwarded-для $realip_remote_addr

Пожалуйста, дайте мне знать, если я чем-то помог!

флаг cn
Это странно. С ```set_real_ip_from 49.12.23.194; real_ip_recursive на; ``` и ``` местоположение / { proxy_pass http://container-php; proxy_set_header X-Forwarded-For $realip_remote_addr; proxy_set_header X-Forwarded-Debug "Remotep $realip_remote_addr"; ``` я все еще получаю ``` ["X-Forwarded-For"]=> строка (26) ",49.12.23.194,49.12.23.194"``
Рейтинг:1
флаг my

Это оператор переопределяет заголовок X-Forwarded-For:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Предполагая, что вы хотите сохранить исходный IP-адрес клиента в этом заголовке, вы должны написать:

proxy_set_header X-Forwarded-For $remote_addr;

флаг cn
Это то, что у меня было изначально, но $remote_addr на тот момент — это IP-адрес балансировщика нагрузки.
Рейтинг:0
флаг cn

В конце концов я решил это так, как это работает, но на самом деле не решает основную проблему. Насколько я могу судить, восходящий LB устанавливает «X-Forwarded-For» на удаленный адрес, и магическая попытка nginx установить это правильно для обратного прокси-сервера всегда ошибалась и устанавливала его на адрес LB или пустой нить.

Вместо этого я переключился с протокола HTTP на протокол PROXY для бита LB->Server, установил следующее в /etc/nginx/proxy_params:

proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;

и это в conf.d:

 /etc/nginx/conf.d/real_ip.conf
set_real_ip_from {{ LB_IP }};
real_ip_header proxy_protocol;

адаптировано из этого:

https://www.x33u.org/docs/kubernetes-stuff/hetzner-loadbalancer-setup/

и теперь все работает.

Рейтинг:0
флаг cn

Судя по вашему описанию, ваша проблема напрямую связана не с nginx, а с apache.

В зависимости от вашей конфигурации поток трафика может выглядеть примерно так:

снаружи -> nginx -> apache -> php (работает как fpm)

или же

снаружи -> nginx -> модуль apache + php

Вы должны заглянуть в конфигурацию apache, чтобы убедиться, что если apache не отбрасывает x-переадресовано-для и х-реальный-ip заголовки при передаче запроса в PHP.

Если ваш поток трафика соответствует первому примеру, у вас есть проксирование запроса apache также к php, что может привести к гораздо большему количеству проблем, если nginx и apache не «синхронизированы».

Если бы вы обрабатывали проксирование php только с помощью nginx, вам просто нужно было бы добавить следующее в ваш php место расположения конфигурация:

расположение ~ \.php$ {
        #...другие правила
        fastcgi_param REMOTE_ADDR $http_x_real_ip;
        #...другие правила
}

Таким образом, PHP REMOTE_ADDR будет правильно установлен.


Что касается вашей конфигурации nginx, если ваш nginx {{фунтовый IP-адрес}} является статическим, вы можете установить его прямо в конфиге.

/etc/nginx/conf.d/real_ip.conf
set_real_ip_from {{LB IP}};
real_ip_recursive на;

Вам не нужно real_ip_header X-Настоящий-IP; в вашем конфигурационном файле. Это переопределит set_real_ip_from директива.

Имейте в виду, что вам нужно включить модуль real_ip в nginx, чтобы это работало.

флаг cn
Да, первый вариант, как это работает. Чуть более точным будет следующий поток: ```outside -> load-balancer -> nginx -> [DOCKER; апач -> php-fpm]```
флаг cn
Я не думал о том, что Apache искажает заголовки до того, как он добрался до PHP. Это хорошая вещь, чтобы проверить, я посмотрю на это.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.