Продвинутое получение IP-адреса посетителя и проверка по белому списку
При разработке веб-приложений часто требуется ограничить доступ к определённым разделам сайта по IP-адресу. Например, для служебных страниц, панели администратора или временного доступа тестировщикам. В этой статье разберём надёжный способ получить реальный IP-адрес посетителя с учётом прокси и балансировщиков, а также проверим его по белому списку.
Проблема получения реального IP
Если сайт работает за обратным прокси (например, Cloudflare, Nginx, HAProxy) или за балансировщиком, переменная $_SERVER['REMOTE_ADDR'] будет содержать IP-адрес прокси-сервера, а не реального посетителя. Реальный IP обычно передаётся в заголовках:
HTTP_CLIENT_IP
HTTP_X_FORWARDED_FOR
HTTP_X_FORWARDED
HTTP_FORWARDED
HTTP_CF_CONNECTING_IP (для Cloudflare)
Однако эти заголовки могут быть подделаны. Поэтому важно не только получить их, но и отфильтровать потенциально ложные значения.
Улучшенная функция определения IP
Представленная ниже функция собирает IP из всех доступных заголовков, проверяет их валидность и возвращает первый достоверный. В качестве резервного варианта используется REMOTE_ADDR.
<?php
/**
* Определяет реальный IP-адрес посетителя с учётом прокси.
* @return string IP-адрес или '0.0.0.0', если не удалось определить.
*/
function getRealIp() {
$headers = [
'HTTP_CF_CONNECTING_IP', // Cloudflare
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'HTTP_CLIENT_IP'
];
foreach ($headers as $header) {
if (isset($_SERVER[$header])) {
$ipList = explode(',', $_SERVER[$header]);
foreach ($ipList as $ip) {
$ip = trim($ip);
if (filter_var($ip, FILTER_VALIDATE_IP)) {
return $ip;
}
}
}
}
// Если ничего не нашли, используем REMOTE_ADDR
return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}
/**
* Проверяет, находится ли текущий IP в белом списке.
* @param string|array $ipList Один IP или массив разрешённых IP.
* @return bool
*/
function checkIpAgainst($ipList) {
$currentIp = getRealIp();
if (is_array($ipList)) {
return in_array($currentIp, $ipList);
} else {
return $currentIp === $ipList;
}
}
?>
Пример использования
<?php
$whiteListIp = '192.168.1.1'; // или массив: ['192.168.1.1', '10.0.0.1']
if (checkIpAgainst($whiteListIp)) {
// IP в белом списке – разрешаем доступ
echo "Доступ разрешён";
// здесь может быть код административной панели или служебного раздела
} else {
// IP не в списке – запрещаем
header('HTTP/1.0 403 Forbidden');
echo "Доступ запрещён";
exit;
}
?>
Важные замечания
- Безопасность: заголовки вида
X-Forwarded-For могут быть подделаны, если клиент обращается напрямую к вашему серверу, минуя доверенный прокси. Рекомендуется использовать эту функцию только при доверии к прокси (например, настроить веб-сервер так, чтобы он удалял эти заголовки, если запрос пришёл не от доверенного IP).
- Производительность: функция
filter_var с FILTER_VALIDATE_IP достаточно быстра, но при огромном количестве вызовов можно использовать регулярное выражение или другие методы.
- Cloudflare: для корректной работы с Cloudflare необходимо также проверять, что запрос действительно идёт от Cloudflare (по IP их прокси-серверов).
Этот подход позволяет гибко управлять доступом по IP и учитывать особенности работы сайта за прокси.
Продвинутое получение IP-адреса посетителя и проверка по белому списку
При разработке веб-приложений часто требуется ограничить доступ к определённым разделам сайта по IP-адресу. Например, для служебных страниц, панели администратора или временного доступа тестировщикам. В этой статье разберём надёжный способ получить реальный IP-адрес посетителя с учётом прокси и балансировщиков, а также проверим его по белому списку.
Проблема получения реального IP
Если сайт работает за обратным прокси (например, Cloudflare, Nginx, HAProxy) или за балансировщиком, переменная
$_SERVER['REMOTE_ADDR']будет содержать IP-адрес прокси-сервера, а не реального посетителя. Реальный IP обычно передаётся в заголовках:HTTP_CLIENT_IPHTTP_X_FORWARDED_FORHTTP_X_FORWARDEDHTTP_FORWARDEDHTTP_CF_CONNECTING_IP(для Cloudflare)Однако эти заголовки могут быть подделаны. Поэтому важно не только получить их, но и отфильтровать потенциально ложные значения.
Улучшенная функция определения IP
Представленная ниже функция собирает IP из всех доступных заголовков, проверяет их валидность и возвращает первый достоверный. В качестве резервного варианта используется
REMOTE_ADDR.Пример использования
Важные замечания
X-Forwarded-Forмогут быть подделаны, если клиент обращается напрямую к вашему серверу, минуя доверенный прокси. Рекомендуется использовать эту функцию только при доверии к прокси (например, настроить веб-сервер так, чтобы он удалял эти заголовки, если запрос пришёл не от доверенного IP).filter_varсFILTER_VALIDATE_IPдостаточно быстра, но при огромном количестве вызовов можно использовать регулярное выражение или другие методы.Этот подход позволяет гибко управлять доступом по IP и учитывать особенности работы сайта за прокси.