標準ゾーン(localhost等)や RBL ゾーンを除外し、必要なドメインだけを抽出せよ。
# [CentOS 6 側] 再帰検索とノイズ除去 grep -r "^zone" /etc/named* | awk -F\" '{print $2}' | \ grep -vE "^\.|\.\.|localhost|localdomain|^0\.|^127\.|^255\.|rbl\.dazoo" | \ sort -u > /root/all_domains.txt # [Ubuntu(227) 側] 転送先でviを使い不要なドメインを最終清掃 vi /root/all_domains.txt
リストを元に 226番(1st DNS) から dig axfr を実行し、全データを保存せよ。
# [Ubuntu(227) 側]
mkdir -p /root/zones
while read dom; do
echo "Fetching: $dom"
dig axfr $dom @192.168.200.226 > /root/zones/$dom.zone
done < /root/all_domains.txt
以下の PHP スクリプトを /root/bulk_dns_import_final.php として作成・実行せよ。変数の初期化、TXTレコードの完全取得、SQLエスケープ処理を実装済みである。
#!/bin/bash
# 依存パッケージの導入
sudo apt install -y php-cli php-mysql
# スクリプトの実行
sudo php /root/bulk_dns_import_final.php
<?php
require_once '/usr/local/ispconfig/interface/lib/config.inc.php';
require_once '/usr/local/ispconfig/interface/lib/app.inc.php';
if (posix_getuid() !== 0) die("Error: Run as root.\n");
function format_dns_name($name, $origin) {
$name = trim($name);
if ($name == '@' || $name == '') return $origin;
if (substr($name, -1) != '.') $name .= '.';
return $name;
}
$zone_dir = '/root/zones/';
$server_id = 1;
$sys_userid = 1; $sys_groupid = 1;
$app->uses('functions');
// 1. 重複防止のための物理初期化
$app->db->query("TRUNCATE TABLE dns_soa");
$app->db->query("TRUNCATE TABLE dns_rr");
$app->db->query("TRUNCATE TABLE sys_datalog");
$files = glob($zone_dir . "*.zone");
foreach ($files as $file) {
$domain = basename($file, ".zone");
$origin = $domain . '.';
$dns_soa_id = 0; // ループごとにリセット
$dns_rr_list = array();
echo "Importing $domain: ";
$lines = file($file);
foreach($lines as $line) {
$line = trim($line); if ($line == '' || $line[0] == ';') continue;
$parts = preg_split('/\s+/', $line);
$type_idx = -1;
foreach($parts as $idx => $p) {
$u = strtoupper($p);
if (in_array($u, ['SOA','A','AAAA','MX','NS','CNAME','TXT','PTR'])) {
$type_idx = $idx; $resource_type = $u; break;
}
}
if ($type_idx == -1) continue;
if ($resource_type == 'SOA') {
$ns = $app->db->escape(trim($parts[$type_idx+1]));
$mbox = $app->db->escape(trim($parts[$type_idx+2]));
$sql = "INSERT INTO dns_soa SET " .
"sys_userid=$sys_userid, sys_groupid=$sys_groupid, sys_perm_user='riud', sys_perm_group='riud', " .
"server_id=$server_id, origin='$origin', ns='$ns', mbox='$mbox', " .
"serial=".intval($parts[$type_idx+3]).", refresh=".intval($parts[$type_idx+4]).", " .
"retry=".intval($parts[$type_idx+5]).", expire=".intval($parts[$type_idx+6]).", " .
"minimum=".intval($parts[$type_idx+7]).", ttl=3600, active='Y'";
if($app->db->query($sql)) { $dns_soa_id = $app->db->insert_id(); }
} else {
$data_all = implode(' ', array_slice($parts, $type_idx + 1));
$aux = 0; $data = $data_all;
if ($resource_type == 'MX') { $aux = intval($parts[$type_idx+1]); $data = trim($parts[$type_idx+2]); }
elseif ($resource_type == 'TXT') { $data = preg_replace('/^"|"$/', '', trim($data_all)); }
$dns_rr_list[] = ["name" => format_dns_name($parts[0], $origin), "type" => $resource_type, "data" => $data, "aux" => $aux];
}
}
if ($dns_soa_id > 0) {
$rr_count = 0;
foreach($dns_rr_list as $rr) {
$name_esc = $app->db->escape($rr['name']);
$data_esc = $app->db->escape($rr['data']);
$sql = "INSERT INTO dns_rr SET " .
"sys_userid=$sys_userid, sys_groupid=$sys_groupid, sys_perm_user='riud', sys_perm_group='riud', " .
"server_id=$server_id, zone=$dns_soa_id, name='$name_esc', type='{$rr['type']}', " .
"data='$data_esc', aux={$rr['aux']}, ttl=3600, active='Y'";
if($app->db->query($sql)) $rr_count++;
}
echo "SUCCESS (ID: $dns_soa_id, Records: $rr_count)\n";
} else { echo "FAILED (SOA parse error)\n"; }
}
?>
UIの Tools > Resync 実行後、BIND設定が /etc/bind/pri.* に反映されているか確認せよ。
ls -l /etc/bind/pri.*