我们在ELB后面的EC2上有一些PHP服务器。我们希望通过连接到我们服务器的客户端的IP地址来确定区域设置/区域。问题是PHP服务器只能看到ELB的IP地址。我们希望看到通过ELB传递的客户端的IP地址。
答案 0 :(得分:21)
根据AWS docs,ELB应设置'X-Forwarded-For'HTTP标头,该标头保留原始客户端IP地址:
X-Forwarded-For请求标头可帮助您识别客户端的IP地址。由于负载均衡器拦截客户端和服务器之间的流量,因此服务器访问日志仅包含负载均衡器的IP地址。要查看客户端的IP地址,请使用X-Forwarded-For请求标头。
您可以使用以下PHP代码(假设apache)访问它:
$http_headers = apache_request_headers();
$original_ip = $http_headers["X-Forwarded-For"];
答案 1 :(得分:8)
如果您使用Apache,请查看mod_remoteip模块。它包含在Apache 2.4及更新版本中,但也可以找到2.2的后向端口。
模块使用RemoteIPHeader指令配置的请求标头中覆盖的用户IP地址覆盖连接的客户端IP地址。
根据指示更换后,此覆盖的useragent IP地址随后用于mod_authz_host Require ip功能,由mod_status报告,并由mod_log_config%a和core%a格式字符串记录。连接的基础客户端IP以%{c} a格式字符串提供。
换句话说,您可以设置要使用的标头(例如X-Forwarded-For)以及哪些IP是受信任的(例如您的负载均衡器)。从标头中删除可信IP,并将第一个不受信任的IP用作始发客户端。然后,Apache在其他模块中内部使用此IP,例如用于日志记录,主机验证等。
这比仅处理PHP中的X-F-F头更有用,因为mod_remoteip负责整个堆栈,确保访问日志正确等等。
注意:还有一个mod_rpaf模块,它是这个模块的前身。它受到的限制更多。例如,它无法处理可信的ip范围。你需要这个,因为你事先并不了解ELB的IP。它也不能在Apache之前处理多个跃点,例如Varnish之前的ELB。我建议跳过rpaf模块并改用remoteip。
答案 2 :(得分:2)
这是一个大问题,所以试试这个:D
<?php
if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
$real_client_ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
} else {
$real_client_ip = $_SERVER["REMOTE_ADDR"];
}
答案 3 :(得分:1)
对某些人来说似乎mod_cloudflare可能是更好的选择 - 特别是v2.2用户 阅读本篇博客的更多内容: http://knowledgevoid.com/blog/2012/01/13/logging-the-correct-ip-address-using-apache-2-2-x-and-amazons-elastic-load-balancer/
答案 4 :(得分:0)
AWS ELB背后的PHP应用程序的最佳解决方案:
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可以是以逗号空间分隔的代理列表,列表中的 last 是连接到AWS&#39; ELB,因此也是唯一一个我们可以信任的不被欺骗的人。
答案 5 :(得分:-3)
您可以让客户端明确报告其IP地址吗? 请检查此post。