![如何强制服务器以 IPv4 而不是 IPv6 返回我的 IP 地址?](https://linux22.com/image/792196/%E5%A6%82%E4%BD%95%E5%BC%BA%E5%88%B6%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%BB%A5%20IPv4%20%E8%80%8C%E4%B8%8D%E6%98%AF%20IPv6%20%E8%BF%94%E5%9B%9E%E6%88%91%E7%9A%84%20IP%20%E5%9C%B0%E5%9D%80%EF%BC%9F.png)
设想
我在服务器上有一个很小的 PHP 脚本,它可以回显任何访问它的客户端的 IP 地址,因此可以通过 API 将该地址添加到 cpanel MySQL 远程主机表中。我使用 IdHTTP1.Get() 调用此脚本并传递脚本的 url。我通过使用 Bitdefender VPN 来测试这一点,每次在我运行 delphi 代码获取当前 IP 地址之前,它都会给我一个新的 IP 地址。PHP 脚本和 delphi 调用代码的代码如下。
问题
如果我打开 VPN 为自己设置一个新的 IP 地址,然后运行代码,它会返回一个 IPv6 地址。如果我再次运行代码,而不断开 VPN,即我仍然拥有相同的地址,那么在第二次调用时我会得到一个 IPv4 地址。每次我运行代码时,我都会得到相同的 IPv4 地址,正如我所期望的那样。
如果我关闭 VPN 并再次打开它以获取不同的 IP 地址,也会发生同样的事情。例如,第一次运行代码时,我获得一个 IPv6 地址,随后我获得一个 IPv4 地址
例如第一次:2a02:2498:e000:2001:8418:7195:9f43:a0f 第二次及后续时间:88.202.181.53
这个帖子解释说两种地址格式都可能被返回,但我得到的模式似乎相当一致。
问题
有没有办法强制代码始终返回 IPv4 地址?(我的代码不需要反复询问地址,直到得到 IPv4 地址为止)
附加信息
这个帖子似乎暗示了一个解决方案,但我真的不太了解所接受的答案,无法将其应用于我的情况。
这一页,https://www.ipify.org/在 API 使用下,展示了如何使用获取我的 IPv4 或 IPv6 地址https://api.ipify.org或者https://api64.ipify.org所以应该可以在我的脚本中说出我想要的
myip.php代码
<?php
$ip=$_SERVER['REMOTE_ADDR'];
echo $ip;
?>
调用 PHP 脚本的 Delphi 函数(IdHTTP1 是表单上的 Indy TIdHTTP 组件)
function TFrmMain.getmyipaddress: string;
var url : string;
begin
url := 'https://Thedomain.com/myip.php';
Result := '';
try
try
theip := IdHTTP1.Get(url);
Result := Trim(theip);
if result = '' then showmessage( 'Failed to get a sensible IP address from myip.php on server:');
finally
end;
except
on E: Exception do
ShowMessage('Failed to get IP address from myip.php on server:' +slinebreak +
e.Message);
end;
end;
答案1
ipify.org 只能告诉您您的 IPv4 和 IPv6 地址,因为它为 IPv6 和 IPv4 提供了不同的域名。网站https://www.ipify.org/将使用 javascript 向不同的域发出请求。
可以使用 IPv4 或 IPv6 发出 http 请求,并且 Web 服务器自然会从 TCP 标头中知道您的连接 IP 地址 —— 毕竟,这是它发送响应的地方。客户端可以决定是通过 IPv4 还是 IPv6 发出 http 请求,但如果域只有 A(IPv4)或 AAAA(IPv6)记录,那么客户端实际上别无选择。
域名 api6.ipify.org 仅解析为 IPv6 地址,api4.ipify.org 仅解析为 IPv4 地址,因此客户端永远无法通过 IPv6 连接到 api4.ipify.org,反之亦然。
如果您希望 php 脚本始终返回客户端的 IPv4 地址,请确保将其托管在只能解析为 IPv4 地址的域上,从而无法通过 IPv6 连接。
答案2
PHP$_SERVER['REMOTE_ADDR']
包含用于发出请求的开放套接字的远程地址。它可以是 IPv4 或 IPv6 地址,具体取决于客户端选择使用哪个地址。
客户端连接到域时选择 IPv4 或 IPv6 有几个标准:
- 如果客户端没有合适的 IPv6 地址,则使用 IPv4 进行通信
- 如果域名在DNS中没有AAAA记录,客户端会使用A记录,也就是IPv4
- 如果客户端确定 IPv6 存在问题,它将回退到 IPv4
所以,如果要确保REMOTE_ADDR
始终有IPv4地址,则需要使用仅具有A记录的域名。
如果您可以控制客户端的网络,那么您可以在客户端中禁用 IPv6。