如果 $_SERVER 不包含 IPv4 ip 怎么办?
What if the $_SERVER does not contain the IPv4 ip?
我正在尝试编写 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.org and api.ipify.org.
也就是说,即使无法将IPv6转换为IPv4,也有一种方法可以实现获取IPv4,即使访问者使用的是IPv6!
我的问题:
- 如果这两个版本之间无法转换,这些 IP 地理定位服务如何检索访问者的 IPv4?
- 如果他们没有将 IPv6 转换为 IPv4。因此,他们在不接触 IPv6 的情况下直接检索 IPv4。但是,如果 $_SERVER 不包含 IPv4,他们是怎么做到的?
除此之外,我注意到当我访问 whatismyipaddress.com 时,他们首先检索了 IPv6,然后在 IPv4 字段旁边开始加载,然后他们检索了它!
注意:所有这些站点都检索到相同的 IPv4。
谢谢。
只需从您的 DNS 名称中删除 AAAA 记录(或在您的 webservrr 中禁用 ipv6 - 这可能会导致延迟,因为浏览器应该更喜欢 ipv6),然后,人们 w/o ipv4 无法访问您的服务任何更多。正如@MagnusEriksson 所说:“与其为未来而战,修复您的应用程序使其也适用于 IPv6 不是更好吗?”
此外,请注意,如果 IP 地址对您来说非常重要,那么 http headers 很容易被客户端欺骗(即不要相信用户提供的数据)或代理服务器可能会提供RFC1918 中定义的私有 ips。您应该只 consider/use headers 您知道服务器前面使用的受信任代理 - 在所有其他情况下,您不能信任提供 headers.
的用户
如果您使用的是 apache,您可能需要检查是否有任何 IPv6 Bindings or VirtualHosts。其他网络服务器也会有类似的设置
如果您无权访问网络服务器配置,您可以在您的虚拟主机面板中查看是否有禁用 IPv6 的选项
此外,这可能是客户端控制的,即当您使用 VPN 连接时,该网络接口(或隧道)会启用 IPv6。在这种情况下,您不能强迫访问者在他们的设备/路由器上禁用 IPv6,但您可以尝试在您这边禁用它。不像 HTTPS Everywhere 只接受端口 443 或什么都不接受,我不认为 IP 地址处于只能接受 IPv6 而不能回退到 IPv4 的阶段,所以这个建议应该是安全的
我正在尝试编写 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.org and api.ipify.org.
也就是说,即使无法将IPv6转换为IPv4,也有一种方法可以实现获取IPv4,即使访问者使用的是IPv6!
我的问题:
- 如果这两个版本之间无法转换,这些 IP 地理定位服务如何检索访问者的 IPv4?
- 如果他们没有将 IPv6 转换为 IPv4。因此,他们在不接触 IPv6 的情况下直接检索 IPv4。但是,如果 $_SERVER 不包含 IPv4,他们是怎么做到的?
除此之外,我注意到当我访问 whatismyipaddress.com 时,他们首先检索了 IPv6,然后在 IPv4 字段旁边开始加载,然后他们检索了它!
注意:所有这些站点都检索到相同的 IPv4。
谢谢。
只需从您的 DNS 名称中删除 AAAA 记录(或在您的 webservrr 中禁用 ipv6 - 这可能会导致延迟,因为浏览器应该更喜欢 ipv6),然后,人们 w/o ipv4 无法访问您的服务任何更多。正如@MagnusEriksson 所说:“与其为未来而战,修复您的应用程序使其也适用于 IPv6 不是更好吗?”
此外,请注意,如果 IP 地址对您来说非常重要,那么 http headers 很容易被客户端欺骗(即不要相信用户提供的数据)或代理服务器可能会提供RFC1918 中定义的私有 ips。您应该只 consider/use headers 您知道服务器前面使用的受信任代理 - 在所有其他情况下,您不能信任提供 headers.
的用户如果您使用的是 apache,您可能需要检查是否有任何 IPv6 Bindings or VirtualHosts。其他网络服务器也会有类似的设置
如果您无权访问网络服务器配置,您可以在您的虚拟主机面板中查看是否有禁用 IPv6 的选项
此外,这可能是客户端控制的,即当您使用 VPN 连接时,该网络接口(或隧道)会启用 IPv6。在这种情况下,您不能强迫访问者在他们的设备/路由器上禁用 IPv6,但您可以尝试在您这边禁用它。不像 HTTPS Everywhere 只接受端口 443 或什么都不接受,我不认为 IP 地址处于只能接受 IPv6 而不能回退到 IPv4 的阶段,所以这个建议应该是安全的