IP и сети

REMOTE_ADDR vs CF-Connecting-IP: как получить реальный IP посетителя за Cloudflare

Если плагин безопасности WordPress или PHP-приложение за Cloudflare логирует неверный IP — вот почему, и как безопасно читать реальный IP через CF-Connecting-IP вместо REMOTE_ADDR.

6 мин чтения·

Если плагин безопасности WordPress предупреждает вас о "настройках определения IP", или ваше PHP-приложение вдруг начинает логировать для каждого посетителя одну и ту же горстку IP-адресов, причина почти всегда одна и та же: между посетителями и вашим сервером стоит обратный прокси вроде Cloudflare. Если коротко — оставляйте REMOTE_ADDR по умолчанию, никогда не доверяйте HTTP_CLIENT_IP вслепую и читайте CF-Connecting-IP только тогда, когда вы убедились, что запрос действительно прошёл через Cloudflare. Дальше — почему всё устроено именно так.

Что на самом деле означает каждое из этих значений

В PHP они приходят как записи $_SERVER. Они не взаимозаменяемы — они берутся из совершенно разных источников, и в этой разнице вся суть:

  • REMOTE_ADDR — IP-адрес того, кто открыл TCP-соединение с вашим сервером. Веб-сервер подставляет его из самого сокета, поэтому клиент не может его подделать. Это единственное значение, которому можно доверять.
  • HTTP_CLIENT_IP и HTTP_X_FORWARDED_FOR — обычные HTTP-заголовки запроса. Любая запись HTTP_* в $_SERVER — это всего лишь заголовок, отправленный клиентом, а значит, кто угодно может выставить ему любое значение одной строкой curl.
  • HTTP_CF_CONNECTING_IP — заголовок CF-Connecting-IP, который добавляет Cloudflare, содержащий реальный IP посетителя. Заслуживает доверия только тогда, когда вы можете гарантировать, что запрос прошёл через Cloudflare.

Почему за Cloudflare REMOTE_ADDR "неправильный"

Когда Cloudflare проксирует ваш домен, посетители подключаются к edge-узлам Cloudflare, а Cloudflare открывает новое соединение с вашим origin-сервером. С точки зрения вашего сервера посетитель и есть Cloudflare — поэтому REMOTE_ADDR оказывается IP-адресом edge-узла Cloudflare, одинаковым для тысяч разных людей. Ничего не сломано; прокси просто делает свою работу.

Чтобы передать вам исходного посетителя, Cloudflare прикрепляет заголовок CF-Connecting-IP к каждому запросу. Так что за Cloudflare правильный источник — это $_SERVER['HTTP_CF_CONNECTING_IP'], с откатом к REMOTE_ADDR, когда этого заголовка нет.

Ловушка безопасности: почему нельзя просто доверять заголовку

Соблазнительно написать "читай HTTP_CLIENT_IP или X-Forwarded-For, иначе REMOTE_ADDR" и забыть об этом. Именно этот паттерн и приводит к компрометации сайтов. Поскольку это заголовки, передаваемые клиентом, злоумышленник может отправить:

curl https://your-site.example/wp-login.php \
  -H "X-Forwarded-For: 8.8.8.8" \
  -H "Client-IP: 1.1.1.1"

Если ваше ограничение попыток входа, файрвол или журнал аудита читают эти заголовки, злоумышленник может подставлять фальшивый IP на каждом запросе — обходя лимиты частоты, уклоняясь от блокировок по IP и отравляя ваши логи. Вот почему хороший плагин безопасности предупреждает вас перед сменой метода определения: "более удобная" настройка часто оказывается небезопасной.

CF-Connecting-IP защищён от этого лишь благодаря одному дополнительному условию: ваш origin должен принимать трафик исключительно от Cloudflare. Если ваш сервер доступен напрямую по своему публичному IP, злоумышленник может обойти Cloudflare и сам подделать CF-Connecting-IP. Закройте origin с помощью Authenticated Origin Pulls или файрвола, разрешающего только диапазоны IP Cloudflare, и заголовок станет надёжным.

Правильная настройка, простыми словами

  • Обычный сервер, без прокси: используйте REMOTE_ADDR. Готово.
  • За Cloudflare: используйте CF-Connecting-IP (HTTP_CF_CONNECTING_IP) и ограничьте origin только Cloudflare, чтобы заголовок нельзя было подделать.
  • За другим прокси/CDN или балансировщиком нагрузки: используйте тот заголовок, который документирует этот прокси (часто X-Forwarded-For, беря крайний справа доверенный узел), и снова убедитесь, что origin принимает трафик только от этого прокси.

В плагинах безопасности WordPress, таких как All-In-One Security, именно этот выбор и контролирует настройка "определение IP". Оставляйте её на REMOTE_ADDR, если только вы не за Cloudflare — в этом случае переключите на CF-Connecting-IP.

Как проверить, что всё настроено правильно

Самая быстрая проверка — сравнить то, что определяет ваш сервер, с вашим реальным публичным IP. Откройте whatsmy.fyi с той же машины: он показывает ровно тот публичный IP, под которым вас видит внешний мир. Если IP, который ваш плагин или приложение логирует для вашего собственного визита, совпадает с ним — определение работает. (whatsmy.fyi сам работает на Cloudflare, поэтому он читает ваш адрес из CF-Connecting-IP точно так же, как это делал бы правильно настроенный origin — и ничего не хранит.)

Если вы отлаживаете программно, эндпоинт без ключа возвращает то же значение для скриптов:

curl https://whatsmy.fyi/ip
# → ваш реальный публичный IP, каким его видит edge

Два совпадающих IP означают, что ваше определение корректно. Если ваш сервер логирует IP Cloudflare, в то время как whatsmy.fyi показывает ваш реальный, значит, вы всё ещё читаете REMOTE_ADDR за прокси — переключитесь на CF-Connecting-IP. Если они различаются как-то иначе, значит, в пути есть VPN, разделение IPv4/IPv6 или второй прокси — наша заметка о том, почему IP может показывать неправильное местоположение разбирает эти случаи.

Вывод в одну строку

REMOTE_ADDR — это истина, насчёт которой вашему серверу нельзя солгать; HTTP_CLIENT_IP — это заявление, которое может сделать кто угодно. За Cloudflare предпочитайте CF-Connecting-IP и закройте origin, чтобы он оставался надёжным, — а затем сверьте результат со своим реальным адресом на whatsmy.fyi.

Проверьте свой IP-адрес, местоположение и оценку конфиденциальности — мгновенно.

Без логов. Без слежки. Без внешних API.

Запустить проверку →

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

REMOTE_ADDR vs CF-Connecting-IP: как получить реальный IP посетителя за Cloudflare | whatsmy.fyi