【发布时间】:2014-08-14 20:10:02
【问题描述】:
我通常假设在 PHP 脚本中我可以测试 $_SERVER['REMOTE_ADDR'] 来确定发起请求的 IP 地址。然而,我开始怀疑事情是不是有点复杂。这是场景
- 我运行许多服务器,分别称为 A、B 和 C - 用户必须在这些服务器上“注册”李>
- 我运行一个单独的注册服务器,称为 S,在向服务器 A、B 和 C 发送完整的注册请求之前首先验证用户的凭据等强>
请求发出为
file_get_contents('https://url?data=value')
在服务器 A、B 和 C 上,我非常天真地测试 $_SERVER['REMOTE_ADDR'] 以确定请求实际上来自服务器 S。令我惊讶的是,结果结果是不完整且多变的
-
REMOTE_ADDR中的值是与注册服务器交互的人类用户的 IP 地址,S -
REMOTE_ADDR中的值是注册服务器的 IP 地址,S - 这是我希望看到的一直 -
REMOTE_ADDR中的值是我托管服务器 S 的虚拟服务器上 IP 地址池中的另一个 IP 地址
我真的不需要执行这个额外的验证测试,所以我可以完全放弃它。尽管如此,这个结果还是让我感到意外,所以我很想知道这里是否有人可以对正在发生的事情有所了解。
我应该提到的是,我在服务器 A、B 和 C 上的 Lighttpd 上运行 PHP 5.5,在服务器 S 上的 Apache 2 上运行 PHP 5.3。强>
【问题讨论】:
-
您使用 PHP 作为
module还是fcgi/fpm?请同时检查变量$_SERVER['HTTP_CLIENT_IP']和$_SERVER['HTTP_X_FORWARDED_FOR'],因为在使用不同的服务器、(反向)代理和配置时,所有三个变量的填充方式都不同。 -
IP 地址
$_SERVER['REMOTE_ADDR']是直接响应的公共 IP 地址 - 不可能伪造它(除非攻击者不关心接收响应)。从问题的内容来看:您的测试方式存在缺陷,因为它不是这样工作的。 -
如果你在做服务器到服务器的通信(服务器S到服务器A),不可能在
REMOTE_ADDR中有人类访问者的IP。 -
@AD7six REMOTE_ADDR 可以指向防火墙、代理、VPN 端点或其他东西。对于我正在使用的这台计算机,我可以选择我想要的任何代理,因此告诉我正在使用什么计算机是不可靠的。这与服务器向客户端发送响应的能力无关。
标签: php superglobals