Получение client_ip в PHP-приложении с сервером Apache

Я новичок в PHP, и мне дано задание по геолокации.

Я хочу получить client_ip в моем приложении php. Приложение развернуто на AWS и имеет 2 балансировщика нагрузки и веб-сервер apache.

Я пробовал следующее:

    if (array_key_exists('HTTP_CLIENT_IP', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_CLIENT_IP'];
} elseif (array_key_exists('HTTP_X_FORWARDED', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_X_FORWARDED'];
} elseif (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (array_key_exists('HTTP_FORWARDED_FOR', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_FORWARDED_FOR'];
} elseif (array_key_exists('HTTP_FORWARDED', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_FORWARDED'];
} elseif (array_key_exists('REMOTE_ADDR', $_SERVER)) {
$ipAddress = $_SERVER['REMOTE_ADDR'];
} else {
$ipAddress = '';
}

Я думал, что это будет работать, но это не так. Затем я посмотрел в phpinfo и обнаружил следующее:

В Headers, X-Forwarded-For установлен на 10.1.29.16,

$_SERVER['HTTP_X_FORWARDED_FOR'] установлен на 10.1.29.16 и

$_SERVER['REMOTE_ADDR'] 172.17.7.173.

Все это внутренние IP-адреса.

Может кто-нибудь, пожалуйста, направьте меня, как я могу найти IP-адрес реального клиента?

PS:
Это приложение Symfony 4.

2

Решение

Вы проверяете заголовки в неправильном порядке. Сначала проверьте типы FORWARDED_FOR. Вы должны проверить документацию для серверов (балансировщиков нагрузки и т. Д.) Перед вашим экземпляром, чтобы узнать, какой заголовок ссылаться. HTTP_X_FORWARDED_FOR вероятно, самый распространенный. Вы слепо что-то проверяете.

Вы предполагаете, что заголовки содержат одно значение. Если существует цепочка серверов, то каждый из них добавит свой адрес. Примером может служить Cloudfront с ALB.

Заголовок $_SERVER['REMOTE_ADDR'] не является надежным и не следует доверять. На самом деле ни один из заголовков не должен быть доверенным, если вы не контролируете всю цепочку (кэширование, распределение нагрузки и т. Д.). Подделать эти значения очень легко.

1

Другие решения

Других решений пока нет …