Browse Source

feat: dnssec field of IANA database

master
Dnomd343 3 years ago
parent
commit
bc35ee9469
  1. 122
      src/dnssec.php
  2. 10
      src/iana.php
  3. 48
      src/main.php

122
src/dnssec.php

@ -0,0 +1,122 @@
<?php
class DNSSEC {
public function getDnssecStatus($html_contant) {
$html = explode('<table', $html_contant);
if (count($html) !== 4) {
die('error -> dnssec page');
}
$html = explode('</table>', $html[3]);
if (count($html) !== 2) {
die('error -> dnssec page');
}
$html = explode('</tr>' . PHP_EOL . '<tr', $html[0]);
unset($html[0]);
foreach ($html as $row) {
$row = trim($row);
preg_match('/^bgcolor=#[0-9A-F]{6}/', $row, $match);
if (count($match) !== 1) {
die('error -> dnssec list');
}
$color = substr($match[0], -6);
preg_match('/href=http:\/\/www.iana.org\/domains\/root\/db\/[a-z0-9-]+.html>/', $row, $match);
if (count($match) !== 1) {
die('error -> dnssec list');
}
$tld = str_replace('.html>', '', $match[0]);
$tld = '.' . str_replace('href=http://www.iana.org/domains/root/db/', '', $tld);
$row = str_replace('<td align=left>YES</td>', '|YES|', $row);
$row = str_replace('<td>NO</td>', '|NO|', $row);
preg_match('/\|(YES|NO)\|\|(YES|NO)\|\|(YES|NO)\|/', $row, $match);
if (count($match) !== 4) {
die('error -> dnssec list');
}
if ($match[0] === '|YES||YES||NO|') {
$type = 1; // 正常DNSSEC
if ($color !== '00CC00') {
die('error -> dnssec list');
}
} else if ($match[0] === '|NO||NO||NO|') {
$type = 2; // 未启用DNSSEC
if ($color !== 'F2F2F2') {
die('error -> dnssec list');
}
} else if ($match[0] === '|YES||NO||NO|') {
$type = 3; // 启用DNSSEC 但未部署DS记录
if ($color !== '3399CC') {
die('error -> dnssec list');
}
} else {
die('error -> dnssec list');
}
$dnssec[$tld] = array(
'type' => $type
);
}
return $dnssec;
}
public function getDsRecord($tld) { // 获取DS记录
$tld = substr($tld, 1, strlen($tld) - 1); // 去除前面的.
$raw = shell_exec('dig DS +short @' . chr(mt_rand(97, 109)) . '.root-servers.net ' . $tld . '.');
if ($raw == '') {
return array();
}
$dsRecords = explode(PHP_EOL, $raw);
foreach ($dsRecords as $dsRecord) {
if ($dsRecord == '') { continue; }
$ds = explode(' ', $dsRecord);
if (count($ds) !== 4 && count($ds) !== 5) {
return 'error';
}
$temp['tag'] = $ds[0];
$temp['algorithm'] = $ds[1];
$temp['digest'] = $ds[2];
$temp['hash'] = $ds[3];
if (count($ds) === 5) {
$temp['hash'] .= $ds[4];
}
$dnssec[] = $temp;
}
foreach ($dnssec as $row) {
if ($row['digest'] === '1') { // SHA-1
preg_match('/^[0-9A-Z]{40}$/', $row['hash'], $match);
if (count($match) !== 1) {
return 'error';
}
} else if ($row['digest'] === '2') { // SHA-256
preg_match('/^[0-9A-Z]{64}$/', $row['hash'], $match);
if (count($match) !== 1) {
return 'error';
}
} else { // 3 -> GOST R 34.11-94 / 4 -> SHA-384
return 'error';
}
}
foreach ($dnssec as &$row) { // 计算权重
$row['weight'] = $row['tag'] * 1000 + $row['algorithm'] * 10 + $row['digest'];
}
$temp = array(); // 排序算法
foreach ($dnssec as $val){
$temp[] = $val['weight'];
}
sort($temp);
$temp = array_flip($temp);
$sort = array();
foreach ($dnssec as $val) {
$temp_1 = $val['weight'];
$temp_2 = $temp[$temp_1];
$sort[$temp_2] = $val;
}
asort($sort);
$dnssec = $sort;
foreach ($dnssec as &$record) {
unset($record['weight']);
}
return $dnssec;
}
}
?>

10
src/iana.php

@ -271,10 +271,7 @@ class IANA { // 获取IANA顶级域名信息
private function getHtmlManager($str) { // 提取TLD所有者信息
if ($str == '') {
return array(
'name' => array(),
'addr' => array()
);
return array();
}
$temp = explode('</b><br/>', $str);
if (count($temp) !== 2) {
@ -284,10 +281,7 @@ class IANA { // 获取IANA顶级域名信息
preg_match('/\\\u[0-9a-f]{4}/', $manager, $match);
$manager = substr($manager, 3 - strlen($manager));
if ($manager === 'Not assigned') {
return array(
'name' => array(),
'addr' => array()
);
return array();
}
$manager = explode('<br>', $manager);
if ($temp[1] == '') {

48
src/main.php

@ -2,6 +2,7 @@
require_once './icp.php';
require_once './iana.php';
require_once './dnssec.php';
require_once './tld-list.php';
require_once './punycode.php';
require_once './interface.php';
@ -20,6 +21,24 @@ $icpInfo = (new ICP)->getIcpTld($csv_content);
$html_content = file_get_contents('../data/tld-list.html');
$tldList = (new TldList)->getTlds($html_content);
// Get DNSSEC Info
$html_contant = curl('http://stats.research.icann.org/dns/tld_report/');
$dnssecObj = new DNSSEC;
$dnssecList = $dnssecObj->getDnssecStatus($html_contant);
foreach ($dnssecList as $tld => $content) {
echo $tld;
$content = $dnssecObj->getDsRecord($tld);
if ($content === 'error') {
sleep(5); // 延迟5s
$content = $dnssecObj->getDsRecord($tld);
if ($content === 'error') {
die('error -> ds query fail');
}
}
$dnssecList[$tld]['ds'] = $content;
echo PHP_EOL;
}
// Get TLD list from IANA website
$html_content = curl('https://www.iana.org/domains/root/db');
if (!$html_content) {
@ -44,6 +63,22 @@ foreach ($tlds as $index => $tld) {
echo PHP_EOL;
}
// Add DNSSEC field for tldInfo
foreach ($dnssecList as $tld => $dnssec) {
if (!isset($tldInfo[$tld])) {
die('error -> wrong match');
}
}
foreach ($tldInfo as $tld => $info) {
if (isset($dnssecList[$tld])) {
$tldInfo[$tld]['active'] = 'yes';
$tldInfo[$tld]['dnssec'] = $dnssecList[$tld];
} else {
$tldInfo[$tld]['active'] = 'no';
$tldInfo[$tld]['dnssec'] = array();
}
}
// Remove the TLD which not exist in IANA
foreach ($icpInfo as $index => $row) {
$tld = explode('.', $index);
@ -114,6 +149,7 @@ $init_iana_sql =<<<EOF
CREATE TABLE iana (
tld TEXT NOT NULL,
type TEXT NOT NULL,
active TEXT NOT NULL,
manager TEXT NOT NULL,
admin_contact TEXT NOT NULL,
tech_contact TEXT NOT NULL,
@ -121,7 +157,8 @@ CREATE TABLE iana (
website TEXT NOT NULL,
whois TEXT NOT NULL,
last_updated TEXT NOT NULL,
regist_date TEXT NOT NULL
regist_date TEXT NOT NULL,
dnssec TEXT NOT NULL
);
EOF;
$init_list_sql =<<<EOF
@ -144,16 +181,19 @@ $db->exec($init_list_sql);
$db->exec($init_icp_sql);
$insert_sql = 'INSERT INTO iana ';
$insert_sql .= '(tld,type,manager,admin_contact,tech_contact,nameserver,website,whois,last_updated,regist_date) ';
$insert_sql .= '(tld,type,active,manager,admin_contact,tech_contact,nameserver,website,whois,last_updated,regist_date,dnssec) ';
$insert_sql .= 'VALUES (';
foreach ($tldInfo as $tld => $info) {
$sql = $insert_sql . '\'' . $tld . '\',';
$sql .= '\'' . $info['type'] . '\',';
$sql .= '\'' . $info['active'] . '\',';
foreach ($info as $index => $field) {
if ($index === 'manager' || $index === 'admin_contact' || $index === 'tech_contact' || $index === 'nameserver') {
if ($index === 'active' || $index === 'type') { continue; }
if ($index === 'manager' || $index === 'admin_contact' || $index === 'tech_contact' || $index === 'nameserver' || $index === 'dnssec') {
$field = base64_encode(json_encode($field));
}
$sql .= '\'' . $field . '\'';
if ($index !== 'regist_date') {
if ($index !== 'dnssec') {
$sql .= ',';
}
}

Loading…
Cancel
Save