#Что означает проблема
В связке Nginx → Apache соединение с Apache устанавливает прокси, поэтому без дополнительной настройки в журнале может фигурировать 127.0.0.1 либо адрес Nginx. Строку X-Forwarded-For можно использовать только от доверенного прокси: при слепом доверии злоумышленник подставит в ней чужой адрес и исказит журналы, ограничения доступа и защиту.
#Как различить причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Не настроен mod_remoteipApache регистрирует IP соединения, а не реального посетителя. | Все обращения имеют одинаковый адрес локального Nginx. | Подключить модуль и объявить доверенные адреса прокси. |
| Nginx не передаёт верный заголовокВ upstream отсутствует или неверно задан X-Forwarded-For. | Данные для восстановления IP вообще не доходят до Apache. | Проверить настройки proxy_set_header на Nginx. |
| Небезопасное доверие заголовкамRemoteIPHeader задан без RemoteIPInternalProxy/TrustedProxy. | Внешний клиент может подделать IP через X-Forwarded-For. | Ограничить доверие только реальными адресами прокси. |
#Подробная диагностика и устранение
- Определите всю цепочку соединенияВыпишите путь запроса: браузер → CDN (если есть) → Nginx → Apache. Проверьте, разрешён ли прямой доступ к порту Apache из интернета. Если да, не объявляйте доверенным весь интернет: сначала ограничьте сетевой доступ к внутреннему серверу штатными средствами. Не меняйте правила брандмауэра вслепую, чтобы не потерять доступ к SSH.
- Подтвердите проблему на одном тестовом запросеОткройте страницу сайта в браузере. На Apache в приватном журнале этого сайта посмотрите строку за время запроса; если все посетители имеют адрес прокси, найдена характерная проблема. Если журналы уже показывают разные IP, убедитесь, что они соответствуют действительным адресам, а не произвольным входящим заголовкам. В примерах не публикуйте личные IP пользователей.
- Проверьте передачу заголовка на NginxНа Nginx через SSH запустите
sudo nginx -T, найдите действующийlocationс proxy_pass к Apache и параметрproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;. Эта переменная добавляет адрес непосредственного клиента Nginx к цепочке. При работе за CDN дополнительно используйте только подтверждённые адреса CDN и корректную настройку real_ip, иначе записать «адрес пользователя» надёжно нельзя. - Проверьте модуль и настройки ApacheНа Debian/Ubuntu в SSH выполните
sudo apache2ctl -Mи найдитеremoteip_module. Если модуль отсутствует, после резервной копии и согласования включите егоsudo a2enmod remoteip; в других дистрибутивах способ отличается. Проверьте, что действующая конфигурация содержитRemoteIPHeader X-Forwarded-Forи перечисляет доверенные прокси; одного RemoteIPHeader недостаточно. - Укажите точный доверенный узелЕсли Nginx подключается к Apache через 127.0.0.1, используйте для этого адреса
RemoteIPInternalProxy 127.0.0.1; если по отдельному серверному IP, укажите именно его. Для доверенного публичного прокси применяетсяRemoteIPTrustedProxyс его точным адресом или проверенным диапазоном. Не ставьте0.0.0.0/0. Важно: после mod_remoteip директива Apache Require ip тоже использует восстановленный адрес — проверьте правила доступа. - Различайте исходный IP и адрес соединения в журналеВ Apache стандартный формат
%aпосле работы mod_remoteip отображает вычисленный IP клиента, а%{c}a— IP самого TCP-соединения с прокси. На время диагностики можно добавить отдельный защищённый внутренний формат логирования, содержащий оба значения; не меняйте все форматы разом. Если адреса расходятся, проверьте, где начинается доверенная цепочка. - Проверьте синтаксис и перезагрузите службы по очередиСоздайте копии изменяемых файлов Nginx и Apache. Выполните на соответствующих серверах
sudo nginx -tиsudo apache2ctl configtest; при успехе отдельноsudo systemctl reload nginxиsudo systemctl reload apache2. Если один тест не прошёл, не применяйте эту часть изменений. Для отката восстановите соответствующий файл и выполните тот же тест и reload. - Проверьте два разных внешних адреса и подделкуОткройте публичную страницу из двух заведомо разных сетей (например, мобильной и домашней) и сравните обезличенные записи
%aи%{c}a. У второго поля должен оставаться адрес прокси, у первого — разные адреса посетителей. Отдельно проверьте, что произвольный внешний заголовок X-Forwarded-For не позволяет назначить себе чужой IP: такой тест проводите в согласованной тестовой среде. - Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
#Как проверить результат
Успех: Apache регистрирует реальный адрес посетителя в %a, соединение с Nginx остаётся видно в %{c}a; нельзя подменить адрес, послав X-Forwarded-For с недоверенной стороны. Проверены правила Require ip.
#Если проблема не устранена
Если адрес всё ещё локальный, сравните фактическое подключение Nginx → Apache, правильный location и адрес в RemoteIPInternalProxy. Если IP выглядит неверным за CDN, проверьте реальную цепочку доверенных прокси, а не расширяйте список адресов до всех.