mirror of
https://github.com/getnamingo/registry.git
synced 2025-06-25 21:54:46 +02:00
Many improvements to the DNS zone writer
This commit is contained in:
parent
88edc27e45
commit
becc195149
5 changed files with 188 additions and 81 deletions
|
@ -9,7 +9,7 @@ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' -o caddy-stabl
|
||||||
gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg caddy-stable.gpg.key
|
gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg caddy-stable.gpg.key
|
||||||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
|
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
|
||||||
apt update && apt upgrade
|
apt update && apt upgrade
|
||||||
apt install -y bzip2 caddy composer curl gettext git gnupg2 net-tools php8.2 php8.2-bcmath php8.2-cli php8.2-common php8.2-curl php8.2-fpm php8.2-gd php8.2-gnupg php8.2-intl php8.2-mbstring php8.2-opcache php8.2-readline php8.2-swoole php8.2-xml unzip wget whois
|
apt install -y bzip2 caddy composer curl gettext git gnupg2 net-tools php8.2 php8.2-bcmath php8.2-cli php8.2-common php8.2-curl php8.2-fpm php8.2-gd php8.2-gmp php8.2-gnupg php8.2-intl php8.2-mbstring php8.2-opcache php8.2-readline php8.2-swoole php8.2-xml unzip wget whois
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2. Database installation (please choose one):
|
## 2. Database installation (please choose one):
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
composer require phpseclib/phpseclib
|
composer require badcow/dns phpseclib/phpseclib
|
|
@ -27,4 +27,7 @@ return [
|
||||||
'reporting_upload' => false,
|
'reporting_upload' => false,
|
||||||
'reporting_username' => 'your_username',
|
'reporting_username' => 'your_username',
|
||||||
'reporting_password' => 'your_password',
|
'reporting_password' => 'your_password',
|
||||||
|
|
||||||
|
// Zone Writer Configuration
|
||||||
|
'dns_server' => 'bind',
|
||||||
];
|
];
|
183
automation/write-zone.php
Normal file
183
automation/write-zone.php
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once 'vendor/autoload.php';
|
||||||
|
|
||||||
|
use Badcow\DNS\Zone;
|
||||||
|
use Badcow\DNS\Rdata\Factory;
|
||||||
|
use Badcow\DNS\ResourceRecord;
|
||||||
|
use Badcow\DNS\Classes;
|
||||||
|
use Badcow\DNS\AlignedBuilder;
|
||||||
|
|
||||||
|
$c = require_once 'config.php';
|
||||||
|
require_once 'helpers.php';
|
||||||
|
|
||||||
|
$dsn = "{$c['db_type']}:host={$c['db_host']};dbname={$c['db_database']};port={$c['db_port']}";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$dbh = new PDO($dsn, $c['db_username'], $c['db_password']);
|
||||||
|
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
die("Connection failed: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$timestamp = time();
|
||||||
|
$ns1 = 'ns1.namingo.org';
|
||||||
|
$ns2 = 'ns2.namingo.org';
|
||||||
|
|
||||||
|
$sth = $dbh->prepare('SELECT id, tld FROM domain_tld');
|
||||||
|
$sth->execute();
|
||||||
|
|
||||||
|
while (list($id, $tld) = $sth->fetch(PDO::FETCH_NUM)) {
|
||||||
|
$tldRE = preg_quote($tld, '/');
|
||||||
|
$cleanedTld = ltrim(strtolower($tld), '.');
|
||||||
|
$zone = new Zone($cleanedTld . '.');
|
||||||
|
$zone->setDefaultTtl(3600);
|
||||||
|
|
||||||
|
$soa = new ResourceRecord;
|
||||||
|
$soa->setName('@');
|
||||||
|
$soa->setClass(Classes::INTERNET);
|
||||||
|
$soa->setRdata(Factory::Soa(
|
||||||
|
$ns1 . '.',
|
||||||
|
'postmaster.' . $cleanedTld . '.',
|
||||||
|
$timestamp,
|
||||||
|
3600,
|
||||||
|
14400,
|
||||||
|
604800,
|
||||||
|
3600
|
||||||
|
));
|
||||||
|
$zone->addResourceRecord($soa);
|
||||||
|
|
||||||
|
$nsRecord1 = new ResourceRecord;
|
||||||
|
$nsRecord1->setName('@');
|
||||||
|
$nsRecord1->setClass(Classes::INTERNET);
|
||||||
|
$nsRecord1->setRdata(Factory::Ns($ns1 . '.'));
|
||||||
|
$zone->addResourceRecord($nsRecord1);
|
||||||
|
|
||||||
|
$nsRecord2 = new ResourceRecord;
|
||||||
|
$nsRecord2->setName('@');
|
||||||
|
$nsRecord2->setClass(Classes::INTERNET);
|
||||||
|
$nsRecord2->setRdata(Factory::Ns($ns2 . '.'));
|
||||||
|
$zone->addResourceRecord($nsRecord2);
|
||||||
|
|
||||||
|
$sth2 = $dbh->prepare('SELECT DISTINCT domain.id, domain.name, domain.rgpstatus, host.name
|
||||||
|
FROM domain
|
||||||
|
INNER JOIN domain_host_map ON domain.id = domain_host_map.domain_id
|
||||||
|
INNER JOIN host ON domain_host_map.host_id = host.id
|
||||||
|
LEFT JOIN host_addr ON host_addr.host_id = host.id
|
||||||
|
WHERE domain.tldid = :id
|
||||||
|
AND (
|
||||||
|
host.domain_id IS NULL
|
||||||
|
OR host_addr.addr IS NOT NULL
|
||||||
|
)
|
||||||
|
AND (
|
||||||
|
domain.exdate > CURRENT_TIMESTAMP
|
||||||
|
OR rgpstatus = \'pendingRestore\'
|
||||||
|
)
|
||||||
|
ORDER BY domain.name');
|
||||||
|
$sth2->execute([':id' => $id]);
|
||||||
|
|
||||||
|
while (list($did, $dname, $rgp, $hname) = $sth2->fetch(PDO::FETCH_NUM)) {
|
||||||
|
$sthStatus = $dbh->prepare("SELECT id FROM domain_status WHERE domain_id = :did AND status LIKE '%Hold' LIMIT 1");
|
||||||
|
$sthStatus->bindParam(':did', $did, PDO::PARAM_INT);
|
||||||
|
$sthStatus->execute();
|
||||||
|
$status_id = $sthStatus->fetchColumn();
|
||||||
|
|
||||||
|
if ($status_id) continue;
|
||||||
|
|
||||||
|
$dname = trim($dname, "$tldRE.");
|
||||||
|
$dname = ($dname == "$tld.") ? '@' : $dname;
|
||||||
|
|
||||||
|
$nsRecord = new ResourceRecord;
|
||||||
|
$nsRecord->setName($dname);
|
||||||
|
$nsRecord->setClass(Classes::INTERNET);
|
||||||
|
$nsRecord->setRdata(Factory::Ns($hname . '.'));
|
||||||
|
$zone->addResourceRecord($nsRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sth2 = $dbh->prepare("SELECT host.name, host.domain_id, host_addr.ip, host_addr.addr
|
||||||
|
FROM domain
|
||||||
|
INNER JOIN host ON domain.id = host.domain_id
|
||||||
|
INNER JOIN host_addr ON host.id = host_addr.host_id
|
||||||
|
WHERE domain.tldid = :id
|
||||||
|
AND (domain.exdate > CURRENT_TIMESTAMP OR rgpstatus = 'pendingRestore')
|
||||||
|
ORDER BY host.name");
|
||||||
|
$sth2->execute([':id' => $id]);
|
||||||
|
|
||||||
|
while (list($hname, $did, $type, $addr) = $sth2->fetch(PDO::FETCH_NUM)) {
|
||||||
|
$sthStatus = $dbh->prepare("SELECT id FROM domain_status WHERE domain_id = :did AND status LIKE '%Hold' LIMIT 1");
|
||||||
|
$sthStatus->bindParam(':did', $did, PDO::PARAM_INT);
|
||||||
|
$sthStatus->execute();
|
||||||
|
$status_id = $sthStatus->fetchColumn();
|
||||||
|
|
||||||
|
if ($status_id) continue;
|
||||||
|
|
||||||
|
$hname = trim($hname, "$tldRE.");
|
||||||
|
$hname = ($hname == "$tld.") ? '@' : $hname;
|
||||||
|
|
||||||
|
$record = new ResourceRecord;
|
||||||
|
$record->setName($hname);
|
||||||
|
$record->setClass(Classes::INTERNET);
|
||||||
|
|
||||||
|
if ($type == 'v4') {
|
||||||
|
$record->setRdata(Factory::A($addr));
|
||||||
|
} else {
|
||||||
|
$record->setRdata(Factory::AAAA($addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
$zone->addResourceRecord($record);
|
||||||
|
}
|
||||||
|
|
||||||
|
$builder = new AlignedBuilder();
|
||||||
|
$completed_zone = $builder->build($zone);
|
||||||
|
|
||||||
|
if ($c['dns_server'] == 'bind') {
|
||||||
|
$basePath = '/etc/bind/zones';
|
||||||
|
} elseif ($c['dns_server'] == 'nsd') {
|
||||||
|
$basePath = '/etc/nsd';
|
||||||
|
} elseif ($c['dns_server'] == 'knot') {
|
||||||
|
$basePath = '/etc/knot';
|
||||||
|
} else {
|
||||||
|
// Default path
|
||||||
|
$basePath = '/etc/bind/zones';
|
||||||
|
}
|
||||||
|
|
||||||
|
file_put_contents("{$basePath}/{$cleanedTld}.zone", $completed_zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($c['dns_server'] == 'bind') {
|
||||||
|
exec("rndc reload .{$cleanedTld}", $output, $return_var);
|
||||||
|
if ($return_var != 0) {
|
||||||
|
print "Failed to reload BIND. $return_var \n";
|
||||||
|
}
|
||||||
|
|
||||||
|
exec("rndc notify .{$cleanedTld}", $output, $return_var);
|
||||||
|
if ($return_var != 0) {
|
||||||
|
print "Failed to notify secondary servers. $return_var \n";
|
||||||
|
}
|
||||||
|
} elseif ($c['dns_server'] == 'nsd') {
|
||||||
|
exec("nsd-control reload", $output, $return_var);
|
||||||
|
if ($return_var != 0) {
|
||||||
|
print "Failed to reload NSD. $return_var \n";
|
||||||
|
}
|
||||||
|
} elseif ($c['dns_server'] == 'knot') {
|
||||||
|
exec("knotc reload", $output, $return_var);
|
||||||
|
if ($return_var != 0) {
|
||||||
|
print "Failed to reload Knot DNS. $return_var \n";
|
||||||
|
}
|
||||||
|
|
||||||
|
exec("knotc zone-notify .{$cleanedTld}", $output, $return_var);
|
||||||
|
if ($return_var != 0) {
|
||||||
|
print "Failed to notify secondary servers. $return_var \n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Default
|
||||||
|
exec("rndc reload .{$cleanedTld}", $output, $return_var);
|
||||||
|
if ($return_var != 0) {
|
||||||
|
print "Failed to reload BIND. $return_var \n";
|
||||||
|
}
|
||||||
|
|
||||||
|
exec("rndc notify .{$cleanedTld}", $output, $return_var);
|
||||||
|
if ($return_var != 0) {
|
||||||
|
print "Failed to notify secondary servers. $return_var \n";
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,79 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
$c = require_once 'config.php';
|
|
||||||
require_once 'helpers.php';
|
|
||||||
|
|
||||||
// Connect to the database
|
|
||||||
$dsn = "{$c['db_type']}:host={$c['db_host']};dbname={$c['db_database']};port={$c['db_port']}";
|
|
||||||
|
|
||||||
try {
|
|
||||||
$dbh = new PDO($dsn, $c['db_username'], $c['db_password']);
|
|
||||||
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
} catch (PDOException $e) {
|
|
||||||
die("Connection failed: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
$timestamp = time();
|
|
||||||
$ns1 = 'ns1.namingo.org';
|
|
||||||
$ns2 = 'ns2.namingo.org';
|
|
||||||
|
|
||||||
$sth = $dbh->prepare("SELECT `id`,`tld` FROM `domain_tld`");
|
|
||||||
$sth->execute();
|
|
||||||
|
|
||||||
while (list($id, $tld) = $sth->fetch(PDO::FETCH_NUM)) {
|
|
||||||
$tldRE = preg_quote($tld, '/');
|
|
||||||
$outFile = fopen("/var/named/named{$tld}.zone", 'w') or print "Unable to open file '/var/named/named{$tld}.zone'.\n";
|
|
||||||
fwrite($outFile, "\$TTL\t1H\n@\tIN\tSOA\t{$ns1}.\tpostmaster{$tld}. (\n\t$timestamp\n\t3H\n\t1H\n\t1W\n\t1D\n\t)\n\n");
|
|
||||||
fwrite($outFile, "@\t1H\tIN\tNS\t{$ns1}.\n");
|
|
||||||
fwrite($outFile, "@\t1H\tIN\tNS\t{$ns2}.\n");
|
|
||||||
|
|
||||||
// Select all the hosts
|
|
||||||
$sth2 = $dbh->prepare("SELECT DISTINCT `domain`.`id`, `domain`.`name`, `domain`.`exdate`, `rgpstatus`, `domain`.`name`
|
|
||||||
FROM `domain`
|
|
||||||
WHERE `domain`.`tldid` = :id
|
|
||||||
AND (
|
|
||||||
`domain`.`exdate` > NOW()
|
|
||||||
OR `rgpstatus` = 'pendingRestore'
|
|
||||||
)
|
|
||||||
ORDER BY `domain`.`name`");
|
|
||||||
$sth2->execute([':id' => $id]);
|
|
||||||
|
|
||||||
while (list($did, $dname, $hname) = $sth2->fetch(PDO::FETCH_NUM)) {
|
|
||||||
$status_id = $dbh->query("SELECT `id` FROM `domain_status` WHERE `domain_id` = '$did' AND `status` LIKE '%Hold' LIMIT 1")->fetchColumn();
|
|
||||||
if ($status_id) continue;
|
|
||||||
$dname = trim($dname, "$tldRE.");
|
|
||||||
$dname = ($dname == "$tld.") ? '@' : $dname;
|
|
||||||
$hname = trim($hname, "$tldRE.");
|
|
||||||
fwrite($outFile, "$dname\tIN\tNS\t$hname\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select the A and AAAA records
|
|
||||||
$sth2 = $dbh->prepare("SELECT `host`.`name`,`host`.`domain_id`,`host_addr`.`ip`,`host_addr`.`addr`
|
|
||||||
FROM `domain`,`host`,`host_addr`
|
|
||||||
WHERE `domain`.`tldid` = :id
|
|
||||||
AND `domain`.`id` = `host`.`domain_id`
|
|
||||||
AND `host`.`id` = `host_addr`.`host_id`
|
|
||||||
AND (`domain`.`exdate` > NOW() OR `rgpstatus` = 'pendingRestore')
|
|
||||||
ORDER BY `host`.`name`");
|
|
||||||
$sth2->execute([':id' => $id]);
|
|
||||||
|
|
||||||
while (list($hname, $did, $type, $addr) = $sth2->fetch(PDO::FETCH_NUM)) {
|
|
||||||
$status_id = $dbh->query("SELECT `id` FROM `domain_status` WHERE `domain_id` = '$did' AND `status` LIKE '%Hold' LIMIT 1")->fetchColumn();
|
|
||||||
if ($status_id) continue;
|
|
||||||
$hname = trim($hname, "$tldRE.");
|
|
||||||
$hname = ($hname == "$tld.") ? '@' : $hname;
|
|
||||||
if ($type == 'v4') {
|
|
||||||
fwrite($outFile, "$hname\tIN\tA\t$addr\n");
|
|
||||||
} else {
|
|
||||||
fwrite($outFile, "$hname\tIN\tAAAA\t$addr\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fwrite($outFile, "\n; EOF\n");
|
|
||||||
fclose($outFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
exec("systemctl reload named.service", $output, $return_var);
|
|
||||||
if ($return_var != 0) {
|
|
||||||
print "Failed to reload named. $return_var \n";
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue