簡體   English   中英

如何在 PHP 中驗證 DNSSEC?

[英]How to validate DNSSEC in PHP?

我一直在嘗試找出一種方法來驗證 PHP ( oa1 ) 中的 DNS 記錄,但沒有找到。

我可以使用這個庫驗證整個域,但不能驗證單個記錄: https : //github.com/metaregistrar/php-dnssec-validator

此外,該庫僅允許驗證非常小的 TLD 集。

是否有另一個圖書館可以為我處理這個問題,或者我應該研究其他什么?

我也發現了這個: http : //www.phpclasses.org/package/9031-PHP-Validate-DNSSEC-keys-and-calculate-the-DS-record.html

但我不知道如何獲取密鑰以在其驗證功能中使用。

請幫忙!

更新

所以,我最終使用了這個......

exec('host -t RRSIG ' . $domain, $output);

以最小的麻煩返回 RRSIG 或缺少 RRSIG。

PHP 引擎有一組它支持的固定 DNS 記錄類型,所有這些type dns_get_recordtype參數定義。 您可以通過查看實現 DNS 查詢的引擎代碼來仔細檢查此列表。

不幸的是,該預定義列表中沒有任何 DNSSEC 記錄。 因此,您需要依賴庫或外部工具。

我會使用Net_DNS2 ,因為它支持許多DNSSEC RR 例子:

$google = new \Net_DNS2_Resolver(['nameservers' => ['8.8.8.8', '8.8.4.4']]);
$google->dnssec = true;
try {
    $result = $google->query('kyhwana.org', 'SSHFP');
} catch(\Net_DNS2_Exception $ex) {
    die($ex->getMessage());
}

foreach ($result->answer as $answer) {
    if ($answer instanceof \Net_DNS2_RR_SSHFP) {
        printf(
            '%s %d %s %s %d %d %s' . PHP_EOL,
            $answer->name,
            $answer->ttl,
            $answer->class,
            $answer->type,
            $answer->algorithm,
            $answer->fp_type,
            $answer->fingerprint
        );
    } else if ($answer instanceof \Net_DNS2_RR_RRSIG) {
        printf('Signed by %s: %s' . PHP_EOL, $answer->signname, $answer->signature);
    }
}

另外:如果您的域使用 ECDSA 算法或 SHA-256 指紋(如上面的示例),那么您需要最新的 Net_DNS2 代碼來修復問題 #39

我還沒有實現代碼,但在我看來,使用 php 來驗證簽名本身是一個錯誤。 在強制執行 DNSSEC 的本地服務器上使用本地遞歸解析器,如 unbound。

然后在帶有 PEAR 模塊 Net_DNS2 的 php 中查找感興趣域的 RRSIG 記錄。 結果應該告訴您負責該記錄的區域。

在該區域中查找 DNSKEY 記錄。 如果存在,則查找 DS 記錄。

DS 記錄將來自父區域(例如,deviant.email 的 .email),如果存在則表明該區域存在 DNSSEC。

如果該區域存在 DNSSEC,那么如果您的本地遞歸名稱服務器強制執行 DNSSEC,則該區域的所有結果都是有效的。

我相信 Net_DNS2 使用

r = new Net_DNS2_Resolver(array('nameservers' => array('127.0.0,1')));
r->dnssec = true;

如果 DNSSEC 處於活動狀態,也會導致 Net_DNS2 也驗證結果 - 這由來自父區域的 DS 記錄指示。 但是使用強制執行 DNSSEC 的遞歸解析器(最好在網絡服務器上)可能是最安全的。

確保遞歸解析器沒有監聽公共接口,這樣它就不會被用於反射放大攻擊。

有相同的目標(在 PHP 中驗證 DNSSEC),我最終得到:

exec("drill -k root.keys -TDQ $domain SOA | grep -v '^;;'", $output);

這是一個完整的自上而下的 DNSSEC 驗證。

您需要可以檢索的根密鑰:

unbound-anchor # NB: on FreeBSD, use local-unbound-anchor for "base" version

或“手動”:

dig . dnskey > root.keys

要確認記錄完全經過 DNSSEC 驗證,請檢查 exec 輸出的最后一行:

  • [S] self sig OK這不令人滿意,可能區域密鑰尚未填充到父區域
  • [B] 假的
  • [T] 信任這意味着一切正常!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM