php - 使用 apache 服务器在 PHP 应用程序中获取 client_ip
问题描述
我是 PHP 新手,我的任务是进行地理定位。
我想在我的 php 应用程序中获取 client_ip。该应用程序部署在 AWS 上,具有 2 个负载均衡器和 apache Web 服务器。
我试过以下:
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 应用程序。
解决方案
您正在以错误的顺序检查标题。首先检查 FORWARDED_FOR 类型。您需要检查实例前面的服务器(负载均衡器等)的文档,以了解要引用的标头。HTTP_X_FORWARDED_FOR
可能是最常见的。你在盲目地检查任何东西。
您假设标题包含单个值。如果有一个服务器链,那么每个服务器都会添加它的地址。一个例子是带有 ALB 的 Cloudfront。
标头$_SERVER['REMOTE_ADDR']
不可靠,不应信任。实际上,除非您控制整个链(缓存、负载平衡等),否则不应信任任何标头。伪造这些值非常容易。