PHP在2017年获得真实用户IP地址的最准确/最安全的方式

2022-08-30 21:35:27

通过PHP获取2017年用户IP地址的最准确方法是什么?

我已经阅读了很多关于它的SO问题和答案,但大多数答案都是旧的,并且用户评论说这些方式是不安全的。

例如,看看这个问题(2011):如何获取PHP中的客户端IP地址?

蒂姆·肯尼迪(Tim Kennedy)的回答包含了一个建议,即使用如下内容:

if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}

但是,正如我阅读了很多东西一样,我已经看到使用是不安全的,正如下面的评论所强调的那样:X_FORWARDED_FOR

不要使用上面的代码,除非你确切地知道它的作用!由于这个原因,我看到了巨大的安全漏洞。客户端可以将 X 转发的 For 或 Client-IP 标头设置为它所需的任何值。除非您具有受信任的反向代理,否则不应使用这些值中的任何一个。

由于我不知道它到底做了什么,我不想冒险。他说这是不安全的,但没有提供一种安全的方法来获得用户的IP地址。

我已经尝试了简单的,但这返回了错误的IP。我已经测试了这个,我的真实IP遵循以下模式:,但我得到一个IP地址,如:$_SERVER['REMOTE_ADDR'];78.57.xxx.xxx81.7.xxx.xxx

那么你有什么想法吗?


答案 1

简短的回答:

$ip = $_SERVER['REMOTE_ADDR'];


截至2021年(现在仍然是)是获取用户IP地址的唯一可靠方法,但如果在代理服务器后面,它可能会显示错误的结果。
所有其他解决方案都意味着安全风险很容易伪造$_SERVER['REMOTE_ADDR'];


答案 2

从安全POV来看,没有什么是可靠的 - 不幸的是,这只是一个简单的事实。$_SERVER['REMOTE_ADDR']

所有前缀为前缀的变量实际上都是客户端发送的HTTP标头,当请求通过不同的服务器时,没有其他方法可以传输该信息。
但这当然会自动意味着客户端可以欺骗这些标头。HTTP_

永远不能信任客户。

除非是你...如果控制代理或负载均衡器,则可以对其进行配置,以便从原始请求中删除此类标头。
然后,只有到那时,你才能信任一个例如 标题,但实际上,没有必要在这一点上...您的Web服务器也可以配置为替换为该值,整个过程对您来说是透明的。X-Client-IPREMOTE_ADDR

无论我们在哪一年,情况总是如此...对于与安全性相关的任何内容 - 只有信任。
最好的情况是出于统计目的读取数据,即使这样 - 确保输入至少是有效的IP地址。REMOTE_ADDRHTTP_


推荐