Определение 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"];
}
Ответ 4
Кажется, mod_cloudflare, возможно, лучший вариант для некоторых пользователей - especialy v2.2
Подробнее читайте в этом блоге:
http://knowledgevoid.com/blog/2012/01/13/logging-the-correct-ip-address-using-apache-2-2-x-and-amazons-elastic-load-balancer/
Ответ 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 явно?
Проверьте этот пост.