Является ли переменная веб-сервера $_SERVER ['REMOTE_ADDR'] надежной?

Я обычно предполагал, что в PHP script я могу протестировать $_SERVER['REMOTE_ADDR'], чтобы установить IP-адрес, с которого возник запрос. Тем не менее, я начинаю задаваться вопросом, не слишком ли сложнее. Вот сценарий

  • Я запустил несколько серверов, назовите их A, B и C - на которых пользователи должны быть "зарегистрированы" li >
  • Я запустил отдельный сервер регистрации, назовите его S, где учетные данные пользователей и т.д. сначала проверяются до отправки полного запроса на регистрацию на серверы A, B и C

Запрос отправляется как

file_get_contents('https://url?data=value')

На серверах A, B и C я довольно наивно тестировал $_SERVER['REMOTE_ADDR'], чтобы установить, что запрос действительно поступал с сервера S. К моему удивлению, результаты оказались неоднородными и переменными

  • Значение в REMOTE_ADDR было IP-адресом пользователя, взаимодействующего с сервером регистрации, S
  • Значение в REMOTE_ADDR - это IP-адрес сервера регистрации, S - то, что я ожидал увидеть все время
  • Значение в REMOTE_ADDR было другим IP-адресом из пула IP-адресов на виртуальном сервере, на котором я размещаю сервер S

Мне не нужно выполнять этот дополнительный проверочный тест, чтобы полностью отказаться от него. Тем не менее этот результат заставил меня врасплох, поэтому мне интересно узнать, может ли кто-то здесь пролить свет на то, что происходит.

Я должен упомянуть, что я запускаю PHP 5.5 на Lighttpd на серверах A, B и C и PHP 5.3 на Apache 2 на сервере S.

Ответ 1

REMOTE_ADDR - это переменная, которая заполняется Apache (или любым другим веб-контейнером), она содержит IP-адрес терминала на другом конце сообщения.

Является ли он надежным? Да.

Это безопасно? Зависит, если вы используете его, думая, что он представляет вам IP-адрес пользователя, делающего вызов, вы ошибаетесь, любой прокси-сервер, который стоит на пути, испортит информацию.

В вашем случае сервер, испускающий HTTP-вызов, должен предоставить свой IP-адрес, поэтому сценарий 2 должен выполняться все время. Я не знаю, что пошло не так в тот момент, но его странно.

Чтобы ответить на Dany Caissy, не полагайтесь на HTTP_X_FORWARDED_FOR, его можно легко модифицировать как заголовок HTTP, а не свойство TCP/IP.

Ответ 2

REMOTE_ADDR - это не единственный способ получить IP-адрес, есть также:

HTTP_CLIENT_IP
HTTP_X_FORWARDED_FOR
HTTP_X_FORWARDED
HTTP_X_CLUSTER_CLIENT_IP
HTTP_FORWARDED_FOR
HTTP_FORWARDED

Они устанавливаются по-разному и могут означать разные вещи, в конечном счете, очень сложно получить IP-адрес, который вы хотите иметь.

EDIT: только один из них, который является надежным и не может быть изменен пользователем, является REMOTE_ADDR, но он не всегда будет делать то, что вы хотите, поэтому вы должны использовать другие, независимо от того, как "небезопасно" все говорят, что они есть.