如果 $_SERVER 不包含 IPv4 IP 怎么办?

What if the $_SERVER does not contain the IPv4 ip?

提问人:Ghadeer R. Majeed 提问时间:2/11/2021 更新时间:2/11/2021 访问量:231

问:

我正在尝试编写一个PHP脚本,以使用此函数获取客户端的IP地址:

public function getIpAddress() {
    $ipAddress = '';
    if (! empty($_SERVER['HTTP_CLIENT_IP']) && $this->isValidIpAddress($_SERVER['HTTP_CLIENT_IP'])) {
        // check for shared ISP IP
        $ipAddress = $_SERVER['HTTP_CLIENT_IP'];
    } else if (! empty($_SERVER['HTTP_X_FORWARDED_FOR']) && $this->isValidIpAddress($_SERVER['HTTP_CLIENT_IP'])) {
        // check for IPs passing through proxy servers
        // check if multiple IP addresses are set and take the first one
        $ipAddressList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        foreach ($ipAddressList as $ip) {
            if ($this->isValidIpAddress($ip)) {
                $ipAddress = $ip;
                break;
            }
        }
    } else if (! empty($_SERVER['HTTP_X_FORWARDED']) && $this->isValidIpAddress($_SERVER['HTTP_X_FORWARDED'])) {
        $ipAddress = $_SERVER['HTTP_X_FORWARDED'];
    } else if (! empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && $this->isValidIpAddress($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) {
        $ipAddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    } else if (! empty($_SERVER['HTTP_FORWARDED_FOR']) && $this->isValidIpAddress($_SERVER['HTTP_FORWARDED_FOR'])) {
        $ipAddress = $_SERVER['HTTP_FORWARDED_FOR'];
    } else if (! empty($_SERVER['HTTP_FORWARDED']) && $this->isValidIpAddress($_SERVER['HTTP_FORWARDED'])) {
        $ipAddress = $_SERVER['HTTP_FORWARDED'];
    } else if (! empty($_SERVER['REMOTE_ADDR']) && $this->isValidIpAddress($_SERVER['REMOTE_ADDR'])) {
        $ipAddress = $_SERVER['REMOTE_ADDR'];
    }else{
        $ipAddress = 'error';
    }
    return $ipAddress;
}

我尝试了很多次,它正在工作。但是我尝试连接到 VPN,它检索的是 IPv6 而不是 IPv4!

这可能是正常情况,但我需要获取该 PHP 脚本访问者的 IPv4。 我在谷歌上搜索了很多关于将 IPv6 转换为 IPv4 的信息,我知道它无法转换。

但我注意到一些 IP 地理定位服务正在为同一个 VPN(在同一设备上)检索 IPv4!例如:canyouseeme.orgapi.ipify.org

这意味着即使 IPv6 无法转换为 IPv4,即使访问者使用的是 IPv6,也可以实现一种方法来获取 IPv4!

我的问题:

  • 如果这两个版本之间无法转换,这些 IP 地理定位服务如何检索访问者的 IPv4?
  • 如果他们没有将 IPv6 转换为 IPv4。因此,他们直接检索 IPv4,而不接触 IPv6。但是,如果 _SERVER 美元不包含 IPv4,他们是如何做到的呢?

除此之外,我注意到当我访问 whatismyipaddress.com 时,他们首先检索了 IPv6,然后它开始在 IPv4 字段旁边加载,然后他们检索了它!

注意:所有这些站点都检索了相同的IPv4。

谢谢。

php ip-geolocation(php ip-地理定位)

评论

1赞 tkausl 2/11/2021
他们可能使用某种仅 IPv4 的 Web 服务器来检索您的 IPv4。
0赞 Ghadeer R. Majeed 2/11/2021
@tkausl 那么,购买纯IPv4的Web服务器将是解决方案吗?
2赞 Tangentially Perpendicular 2/11/2021
假设客户端没有 IPV4 地址?
0赞 MrTux 2/11/2021
所有 http 标头都很容易被欺骗,所以不要依赖它们。
2赞 M. Eriksson 2/11/2021
与其与未来作斗争,不如修复您的应用程序,使其也能与 IPv6 一起使用,这不是更好吗?

答:

0赞 MrTux 2/11/2021 #1

只需从您的 DNS 名称中删除 AAAA 记录(或在您的 webservrr 中禁用 ipv6 - 这可能会引入延迟,因为浏览器应该更喜欢 ipv6),但是,没有 ipv4 的人将无法再访问您的服务。正如@MagnusEriksson所说:“与其与未来作斗争,不如修复你的应用程序,让它也能与IPv6一起工作,不是更好吗?

另外,请注意,如果 IP 地址对您来说非常重要,则 http 标头很容易被客户端欺骗(即,不信任用户提供的数据),或者代理服务器可能会提供 RFC1918 中定义的私有 IP。您应该只考虑/使用您知道服务器前面的受信任代理使用的标头 - 在所有其他情况下,您不能信任用户提供的标头。

评论

0赞 Ghadeer R. Majeed 2/11/2021
我的应用程序无法使用 IPv6。因为,我有一个“Bad-IP”数据库,我会在其中搜索客户端的IP。这些 IP 是版本 4。该列表包含大约 1300 万行。
0赞 Ghadeer R. Majeed 2/11/2021
同时,Web服务器在此期间不支持IPv6(Hostgator)。但我使用的是 Cloudflare。
0赞 pulsar 2/11/2021 #2

如果您使用的是 Apache,您可能需要检查是否有任何 IPv6 绑定VirtualHosts。其他 Web 服务器也会有类似的设置

如果您无权访问 Web 服务器配置,则可以在虚拟主机面板中查看是否有禁用 IPv6 的选项

此外,这可以由客户端控制,即当您使用 VPN 连接时,会为该网络接口(或隧道)启用 IPv6。在这种情况下,您不能强迫访问者在其设备/路由器上禁用IPv6,但您可以尝试在自己的终端上禁用它。与只接受端口 443 或什么都不接受的 HTTPS Everywhere 不同,我不认为 IP 地址处于只能接受 IPv6 而没有回退到 IPv4 的阶段,所以这个建议应该是安全的

评论

0赞 Ghadeer R. Majeed 2/11/2021
网站托管的 Web 服务器不支持 IPv6!但我使用 Cloudflare。会这样吗?