Кто-то спрашивает, почему пользователь VPN появляется в журнале приложения с адресом, который принадлежит шлюзу, или с адресом, который изменился после обеда. Ответ начинается с того, что это за значение: запись, которую веб-сервер поместил в окружение запроса. Это не запрос внутрь туннеля, не идентичность сертификата и не обещание, что номер принадлежит одному человеку. Если читать его как любую из этих трёх вещей, получаются уверенные ответы, которые ошибочны по-разному.

Значение приходит от сервера, а не из туннеля

PHP получает окружение запроса от того, что выполнило скрипт. Справочник серверных переменных PHP описывает эти записи как созданные веб-сервером, а их доступность зависит от того, как пришёл запрос.

Скрипт, запущенный как hook командной строки VPN, — совершенно иной контекст выполнения. У него нет веб-запроса, нет клиентского сокета и нет REMOTE_ADDR, поэтому скопированный веб-код в hook даёт пустые значения, а не неверные. У hook есть собственное окружение, которое заполняет демон, и оно документировано отдельно. Тянуться там к REMOTE_ADDR — значит тянуться к переменной, которую никогда не задавали.

Держите это различие в голове, прежде чем сравнивать два журнала. Возможно, вы сравниваете запрос страницы с hook, а это вовсе не сравнение. Сначала проверьте контекст выполнения, а потом адрес.

Пройдите путь запроса, прежде чем доверять номеру

Сообщённый адрес — это peer того соединения, которое видел веб-сервер. Поместите что угодно между клиентом и этим сервером, и peer изменится. Трансляция, терминация и балансировка каждая сдвигают наблюдение на один шаг дальше от пользователя.

Четыре обычных пути дают четыре разных наблюдения.

Path to the listenerWhat can be reported
Client routed straight to the private listener, no translationThe client's tunnel address
Gateway translates the source before forwardingThe gateway's translated address
Reverse proxy terminates the client and opens its own backend connectionThe proxy's backend address
Load balancer in front of two proxiesWhichever hop the server treats as its peer

Запишите путь с именем назначения, семейством адресов и каждой точкой трансляции. Без этой карты правильное и неправильное значения выглядят в строке журнала одинаково. Две строки схемы экономят полдня споров.

Замена происходит только там, где она настроена

Сервер или фреймворк может намеренно подменить адрес клиента. Модуль remote-IP в Apache и модуль real-IP в NGINX делают именно это, а значение, которое получает PHP, зависит от этой конфигурации и параметров, переданных обработчику скрипта.

Значит, REMOTE_ADDR — не всегда нетронутый TCP-peer. Это peer в том виде, в каком сервер решил его сообщить, применив собственную политику. Это различие решает, является ли значение доказательством или украшением.

Спросите владельца сервера, какое поле авторитетно в этом развёртывании и как сохраняется исходный peer при подмене. Если никто не может ответить, журнал пока ничего не доказывает.

Не читайте заголовки пересылки на веру

Вызывающая сторона может сама отправить заголовки пересылки. Считать первую запись через запятую проверенным адресом пользователя — значит решить верить любому, кто подключился, то есть сделать обратное тому, для чего нужен заголовок. Заголовок описывает цепочку, и только доверенный слой может за неё поручиться.

Используйте поддержку доверенных прокси сервера или фреймворка с настроенной реальной цепочкой прокси и позвольте ей отбрасывать значения из источников вне этой цепочки. Разбор, написанный вручную, — место, где живёт большинство интересных отказов.

Адрес, сообщённый прокси, также не меняет источник пакетов, который видит вышестоящий межсетевой экран. Держите метаданные HTTP и сетевую фильтрацию как отдельные наблюдения, потому что они отвечают на разные вопросы.

Для решений используйте идентичность приложения

Для доступа к записям пользователя полагайтесь на аутентифицированный субъект и правила авторизации приложения. Внутренний адрес может быть переназначен, а один транслированный адрес может представлять сотни одновременных пользователей. Ни одно из этих свойств проверка адреса не исправит.

Если эксплуатации нужно связать запрос с сессией VPN, соедините наблюдаемый адрес и метку времени с авторитетными записями сессий по задокументированной модели трансляции. Это даёт связь, которую можно защитить; один адрес — нет.

Для диагностики заносите в журнал те несколько нужных полей вместо всего массива сервера, который может нести заголовки и материал аутентификации. Полезный вывод говорит, что это значение значит в этом развёртывании, а не какое значение больше всего похоже на клиента.

Похожие статьи