servnest/jobs/reg-cds.php

58 lines
1.6 KiB
PHP

<?php declare(strict_types=1);
/*
RFC 7344: Automating DNSSEC Delegation Trust Maintenance
RFC 8078: Managing DS Records from the Parent via CDS/CDNSKEY
*/
require __DIR__ . '/../init.php';
foreach (query('select', 'registry') as $entry) {
$suffix = regParseDomain($entry['domain'])['suffix'];
// Get child/distant records
try {
$results = kdig(name: $entry['domain'], type: 'CDS');
} catch (KdigException) {
fwrite(STDERR, $entry['domain'] . ' resolution failed.' . LF);
continue;
}
if ($results['AD'] !== 1) // No DNSSEC
continue;
$cds_records = array_column($results['answerRRs'] ?? [], 'rdataCDS');
// Skip if no updates
if ($cds_records === [])
continue;
// Get parent/local CDS records
$zone_raw = file_get_contents(CONF['reg']['suffixes_path'] . '/' . $suffix . 'zone');
if ($zone_raw === false)
output(403, 'Unable to read zone file.');
$pds_records = array_column(parseZoneFile($zone_raw, ['DS'], $entry['domain'], false), 3);
if ($cds_records === ['0 0 0 0'])
// Delete every parent DS records
foreach ($pds_records as $value_to_delete)
knotcZoneExec($suffix, [
$entry['domain'],
'DS',
$value_to_delete,
], 'delete');
else {
// Add child DS records that are not yet in parent
foreach (array_diff($cds_records, $pds_records) as $value_to_add)
knotcZoneExec($suffix, [
$entry['domain'],
CONF['reg']['ttl'],
'DS',
$value_to_add,
], 'add');
// Delete parent DS records that are not part of child anymore
foreach (array_diff($pds_records, $cds_records) as $value_to_delete)
knotcZoneExec($suffix, [
$entry['domain'],
'DS',
$value_to_delete,
], 'delete');
}
}