我记录了对我网站的所有访问,例如日期、请求的 URL 和 IP 地址。今天我从一个格式为 10.xxx 的“内部”IP 获得了一些条目。不管是谁,访问了我网站上的几个链接,我不知道这个“连接”到底在做什么。我真的很想问,他们“如何”伪造他们的 IP,这个“连接”的意图可能是什么,如果他们使用的是内部 IP,他们“如何”从我的网站接收任何数据?我希望这些问题不是太模糊。
谢谢
答案1
由于你的服务器“通过 nginx 代理请求到 apache”您可能会看到代理服务器的内部 IP 地址(尽管您通常会在所有请求中看到该地址)而不是客户端的 IP 地址。
如果您的代理服务器添加了带有原始 IP 地址的标头,并且您的应用程序记录了该标头,则您需要确保代理服务器实际上替换了该标头中的 IP 地址(如果该标头已经存在)。
例如,在客户端也位于设置相同标头的代理之后的情况下,即
client with internal-IP
\__ client-proxy sets "X-forwarded-for: internal-IP"
\__ (internet)
\__ your nginx proxy passes unmodified "X-forwarded-for: internal-IP"
\__ PHP reads the internal-IP
你需要:
client with internal-IP
\__ client-proxy sets "X-forwarded-for: internal-IP"
\__ (internet)
\__ your nginx proxy sets a replacement "X-forwarded-for: public-IP-of-client-proxy"
\__ PHP reads the public-IP-of-client-proxy
也可能是 nginx 将附加public-IP-of-client-proxy
到现有标头,您需要检查代码以查看它如何处理多个值。
回复您的评论:
您的 PHP 代码如下:
function get_ip_address() {
foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key) {
if (array_key_exists($key, $_SERVER) === true) {
foreach (explode(',', $_SERVER[$key]) as $ip) {
if (filter_var($ip, FILTER_VALIDATE_IP) !== false) {
return $ip;
}
}
}
}
}
该代码检查多个不同的(潜在)标头,并将返回第一个包含有效 IP 地址的标头,如果不存在这样的标头,它将返回$_SERVER[REMOTE_ADDR]
包含 apache 检测到的客户端 IP 地址的服务器变量。
如果使用反向代理,则$_SERVER[REMOTE_ADDR]
始终会使用代理的 IP 地址,因此这可能无法告诉您您想知道的内容。
一个相当常见的做法是指示您的反向代理设置一个标头,其中包含代理检测到的客户端 IP 地址。
在您的 nginx 配置中,它看起来如下:
location /some/path/ {
proxy_set_header FORWARDED_FOR $remote_addr;
proxy_pass http://apache.example.com:8000/some/path;
}
带有 mod_php 的 Apache 将使其作为_SERVER[HTTP_FORWARDED_FOR]
标题可用,然后您就可以:您的代码检测到客户端的正确远程 ip 地址。
除非您的代码中已经设置了另一个优先的标头,否则您的代码就会崩溃。IE 当CLIENT_IP: <some-ip>
您的代码解析带有自定义标头的客户端请求时,您的 PHP 函数将检测到该 ip 地址,而不是实际的客户端 ip 地址。
测试一下会发生什么,例如:curl -H "CLIENT_IP: 10.0.0.0" http://yoursite.example.com/
解决方案:在您的代码中仅接受您在 nginx 中设置的实际标头,或者使用 nginx 取消设置或覆盖您的代码正在寻找的所有潜在标头。