Определение IP-адреса клиента за Amazon ELB

У нас есть несколько серверов PHP на EC2 за ELB. Мы хотели бы определить локаль/регион по IP-адресу клиентов, подключающихся к нашим серверам. Проблема в том, что серверы PHP видят только IP-адрес ELB. Мы хотели бы видеть IP-адреса клиентов, прошедших через ELB.

Ответы

Ответ 1

Согласно документам AWS, ELB должен устанавливать HTTP-заголовок "X-Forwarded-For", который сохраняет исходный IP-адрес клиента:

Заголовок запроса X-Forwarded-For позволяет определить IP-адрес клиента. Поскольку балансировки нагрузки перехватывают трафик между клиентами и серверами, журналы доступа к серверу содержат только IP-адрес балансировщика нагрузки. Чтобы увидеть IP-адрес клиента, используйте заголовок запроса X-Forwarded-For.

Вы можете получить к нему доступ, используя следующий код PHP (предполагая apache):

$http_headers = apache_request_headers(); 
$original_ip = $http_headers["X-Forwarded-For"];

Ответ 2

Если вы используете Apache, просмотрите модуль mod_remoteip. Он включен в Apache 2.4 и новее, но также можно найти backports для 2.2.

Модуль переопределяет IP-адрес клиента для соединения с IP-адресом useragent, указанным в заголовке запроса, настроенном с помощью директивы RemoteIPHeader.

После замены в соответствии с инструкциями этот переопределенный IP-адрес useragent затем используется для функции mod_authz_host Require ip, сообщает mod_status и записывается mod_log_config% a и core% в строках формата. Основной IP-адрес клиента доступен в строке формата% {c}.

Другими словами, вы можете установить, какой заголовок использовать (например, X-Forwarded-For) и какой IP-адрес доверяют (например, ваш балансировщик нагрузки). Доверенные IP-адреса удаляются из заголовка, и первый ненадежный IP-адрес используется как исходный клиент. Этот IP-адрес затем используется внутри Apache в других модулях, например для ведения журнала, проверки подлинности хоста и т.д.

Это делает его более полезным, чем обработка заголовка X-F-F в PHP, поскольку mod_remoteip заботится обо всем стеке, гарантирует правильность ваших журналов доступа и т.д.

Примечание. Также есть модуль mod_rpaf, который является предшественником этого. Это гораздо более ограничено. Например, он не может обрабатывать доверенные ip-диапазоны. Вам это нужно, поскольку вы заранее не знаете ELB IP. Он также не может обрабатывать несколько переходов, таких как ELB перед лаком, перед Apache. Я бы предложил пропустить модуль rpaf и вместо этого использовать remoteip.

Ответ 3

Это большая проблема, поэтому попробуйте следующее: D

   <?php 
       if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
            $real_client_ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
        } else {
            $real_client_ip = $_SERVER["REMOTE_ADDR"];
        }

Ответ 5

Оптимальное решение для PHP-приложения за AWS ELB:

if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $commaPos = strrchr($_SERVER['HTTP_X_FORWARDED_FOR'], ',');
    if ($commaPos === FALSE) $remote_addr = $_SERVER['HTTP_X_FORWARDED_FOR'];
    else $remote_addr = trim(substr($_SERVER['HTTP_X_FORWARDED_FOR'], $commaPos + 1));
} else {
    $remote_addr = $_SERVER['REMOTE_ADDR'];
}

Примечания: X-Forwarded-For может быть разделенным запятыми списком прокси, с последним в список - тот, который связан с ELB AWS, и, следовательно, единственный, на который мы можем доверять, не будучи подделанным.

Ответ 6

можете ли вы сообщить клиенту свой адрес ip явно? Проверьте этот пост.