+
82
-

回答

以下是几种获取域名在不同地区 DNS 解析 IP 的方法:

使用系统 DNS 解析:
function getDnsRecords($domain) {
    $records = dns_get_record($domain, DNS_A + DNS_AAAA);
    $ips = [];

    foreach ($records as $record) {
        if (isset($record['ip'])) {
            $ips[] = $record['ip'];
        } elseif (isset($record['ipv6'])) {
            $ips[] = $record['ipv6'];
        }
    }

    return $ips;
}
使用特定 DNS 服务器查询:
function getIpFromDns($domain, $dnsServer) {
    $cmd = "dig @{$dnsServer} {$domain} +short";
    exec($cmd, $output, $return_var);
    return $output;
}

// 使用不同地区的 DNS 服务器
$dnsServers = [
    'us' => '8.8.8.8',        // Google DNS (美国)
    'cn' => '119.29.29.29',   // 腾讯 DNS (中国)
    'jp' => '1.1.1.1',        // Cloudflare DNS (亚太)
];

$results = [];
foreach ($dnsServers as $region => $server) {
    $results[$region] = getIpFromDns('example.com', $server);
}
使用 Socket 直接查询 DNS 服务器:
function queryDns($domain, $dnsServer, $port = 53, $timeout = 3) {
    try {
        // 创建 UDP socket
        $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
        socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, ['sec' => $timeout, 'usec' => 0]);

        // 构建 DNS 查询包
        $header = "\xAA\xAA\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00";
        $question = "";
        foreach (explode(".", $domain) as $part) {
            $question .= chr(strlen($part)) . $part;
        }
        $question .= "\x00\x00\x01\x00\x01";
        $query = $header . $question;

        // 发送查询
        socket_sendto($sock, $query, strlen($query), 0, $dnsServer, $port);

        // 接收响应
        $response = '';
        socket_recvfrom($sock, $response, 1024, 0, $from, $port);

        // 解析响应
        $ips = [];
        if (strlen($response) > 0) {
            // 简单解析响应中的 IP 地址
            $pos = strpos($response, $question) + strlen($question);
            while ($pos < strlen($response)) {
                if (ord($response[$pos]) == 0xC0) {
                    $pos += 2;
                    continue;
                }
                if (ord($response[$pos + 2]) == 0x00 && ord($response[$pos + 3]) == 0x01) {
                    $ip = inet_ntop(substr($response, $pos + 10, 4));
                    $ips[] = $ip;
                }
                $pos += 16;
            }
        }

        socket_close($sock);
        return $ips;
    } catch (Exception $e) {
        return ["Error: " . $e->getMessage()];
    }
}
使用第三方 API:
function getMultiRegionIps($domain) {
    // 使用 DNSPod API
    $apiUrl = "http://119.29.29.29/d?dn=" . urlencode($domain) . "&ttl=1";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $apiUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);

    $response = curl_exec($ch);
    curl_close($ch);

    return explode(";", $response);
}
完整的实现示例:
class DnsResolver {
    private $dnsServers;

    public function __construct() {
        $this->dnsServers = [
            'global' => [
                'google' => '8.8.8.8',
                'cloudflare' => '1.1.1.1'
            ],
            'china' => [
                'dnspod' => '119.29.29.29',
                'ali' => '223.5.5.5'
            ],
            'asia' => [
                'japan' => '210.150.230.1',
                'korea' => '168.126.63.1'
            ]
        ];
    }

    public function resolveAll($domain) {
        $results = [];

        foreach ($this->dnsServers as $region => $servers) {
            $results[$region] = [];
            foreach ($servers as $provider => $ip) {
                $results[$region][$provider] = $this->resolve($domain, $ip);
            }
        }

        return $results;
    }

    private function resolve($domain, $dnsServer) {
        try {
            // 使用 dig 命令
            $cmd = "dig @{$dnsServer} {$domain} +short";
            exec($cmd, $output, $return_var);

            // 过滤并验证 IP
            $ips = array_filter($output, function($ip) {
                return filter_var($ip, FILTER_VALIDATE_IP);
            });

            return [
                'status' => 'success',
                'server' => $dnsServer,
                'ips' => $ips
            ];
        } catch (Exception $e) {
            return [
                'status' => 'error',
                'server' => $dnsServer,
                'message' => $e->getMessage()
            ];
        }
    }

    public function checkAvailability($ip, $port = 80, $timeout = 1) {
        $fp = @fsockopen($ip, $port, $errno, $errstr, $timeout);
        if ($fp) {
            fclose($fp);
            return true;
        }
        return false;
    }
}

// 使用示例
$resolver = new DnsResolver();
$domain = 'example.com';

// 获取所有地区的解析结果
$results = $resolver->resolveAll($domain);

// 输出结果
foreach ($results as $region => $providers) {
    echo "Region: {$region}\n";
    foreach ($providers as $provider => $result) {
        echo "  Provider: {$provider}\n";
        if ($result['status'] === 'success') {
            foreach ($result['ips'] as $ip) {
                echo "    IP: {$ip}\n";
            }
        } else {
            echo "    Error: {$result['message']}\n";
        }
    }
}

使用注意事项:

确保服务器有足够权限执行相关命令设置合适的超时时间考虑缓存机制减少查询负担处理查询失败的情况注意不同 DNS 服务器的查询限制考虑并发查询提高效率验证返回的 IP 地址有效性

网友回复

我知道答案,我要回答