PHP dns_get_record 缺少子域记录

PHP dns_get_record missing records for subdomains

如果可能的话,我正在尝试在 PHP 中获取与域关联的 DNS 记录的完整列表。

找了一段时间,相关问题的答案大多是这样的代码:

$result = dns_get_record("php.net",DNS_ALL);
print_r($result);

但是,当我使用该代码检查我的一个域时,丢失了很多记录。根本没有显示子域的记录。

可以在 PHP 中获取域的 DNS 记录的完整列表以及任何子域的记录,而无需提前知道这些子域是什么?

如我所发,我建议使用 Pear Net DNS2。这是一个完整的示例:http://pastebin.com/bAriPVN9

当您进行查找时,我更喜欢检查 Google Public DNS (8.8.8.8),但您可能有其他偏好。以下是如何设置的示例:

<?php
if($_GET['showData']){
        echo "Posted: <pre>";
        print_r($_GET);
        echo "</pre>\n";
}

$host = trim($_GET['host']);
require_once 'Net/DNS2.php';

switch($_GET['ns']){
        case "google":
                $ns = array('8.8.8.8');
                break;
        default:
                if(isset($_GET['other'])){
                        $ns = array($_GET['other']);
                } else {
                        $ns = array($_GET['ns']);
                }
                break;
}

我的原始代码被设置为像 API 一样工作。用户可以发出 GET 或 POST 请求并以不同方式获取结果记录。这个项目并没有朝那个方向发展,但是你会在代码中看到一些额外的步骤。接下来您要设置或选择要查找的记录类型。

if(empty($_GET['r'])){
        // Set Default Record Types to lookup
        $_GET['r'] = array('A', 'MX', 'SRV', 'TXT', 'CNAME', 'NS');
}

我想要 A 记录、邮件交换记录、服务记录、文本、锥形记录和名称服务器记录。我从来没有用小写测试过,但没有兴趣找出是否有效。

然后我浏览并选择了所有我想查找的子域。由于我可能会使用不同的名称服务器,所以我不想碰运气。如果您要求 ALL 或 *,NS 可能会忽略该请求。求具体记录,总会给你回复的。

if(empty($_GET['s'])){
        // Set Default Dub-Domains to lookup
        $_GET['s']['a'] = array('root', 'ftp', 'list', 'mail', 'store', 'www');
        $_GET['s']['m'] = array('list');
        $_GET['s']['c'] = array('autodiscover');
        $_GET['s']['s'] = array('_sip._tls', '_sipfederationtls._tcp');
}

现在我们可以开始迭代所有这些并收集结果。结果可以以不同的方式返回,具体取决于记录类型或资源数据元素。此外,如果查找失败,可能记录不存在,我们必须处理它。因此 try{} catch() 块。

我实际上并没有查找名为 'root' 的子域。我将其用作第二级的占位符:php.net 与第三级域:www.php.net.

$record_results = array();

foreach($_GET['r'] as $record){
        // A Records
        if($record == "A"){
                if($_GET['s']['a'][0] == "root"){
                        if($_GET['showData']){
                                echo "<tr><td colspan='4'>Performing A Record lookup on $host</td></tr>\r\n";
                        }
                        try {
                                $result = $r->query($host, 'A');
                        } catch(Net_DNS2_Exception $e) {
                                //echo "::query() failed: ", $e->getMessage(), "\n";
                                if(!$suppressNoData){
                                        printf("\t<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td></tr>\n", $host, "A", "No Data", 0);
                                }
                                continue;
                        }

                        //
                        // loop through the answer, printing out the A records returned.
                        //
                        foreach($result->answer as $arr) {
                                $data = $arr->address;
                                printf("\t<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td></tr>\n", $arr->name, $arr->type, $data, $arr->ttl);
                                $record_results[] = array(
                                        'domain' => $arr->name,
                                        'type' => $arr->type,
                                        'data' => $arr->address,
                                        'ttl' => $arr->ttl
                                );
                        }
                        unset($_GET['s']['a'][0]);
                }

然后我们继续,将 $sub 附加到 $host 上,用于我们正在查找和收集详细信息的每条不同记录。

MX 和 SRV 记录可以 return 很多不同的数据。例如,一个域可能有 4 个 MX 记录。因此,您将得到一个对象数组 returned,您必须对其进行筛选。我想我 copy/pasted 那个代码不小心阻塞了两次。

当然,可能需要更多的努力,但您会得到正确的结果。我希望这能帮助你前进。