reg: sync DS/NS using CDS/CSYNC from child zone
This commit is contained in:
parent
b05653d16f
commit
3ddbc7cf1a
6 changed files with 175 additions and 4 deletions
57
jobs/reg-cds.php
Normal file
57
jobs/reg-cds.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
/*
|
||||
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');
|
||||
}
|
||||
}
|
61
jobs/reg-csync.php
Normal file
61
jobs/reg-csync.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
/*
|
||||
RFC 7477: Child-to-Parent Synchronization in DNS
|
||||
*/
|
||||
require __DIR__ . '/../init.php';
|
||||
|
||||
foreach (query('select', 'registry') as $entry) {
|
||||
$suffix = regParseDomain($entry['domain'])['suffix'];
|
||||
|
||||
// Get child/distant CSYNC records
|
||||
try {
|
||||
$results = kdig(name: $entry['domain'], type: 'CSYNC');
|
||||
} catch (KdigException) {
|
||||
fwrite(STDERR, $entry['domain'] . ' CSYNC resolution failed.' . LF);
|
||||
continue;
|
||||
}
|
||||
if ($results['AD'] !== 1)
|
||||
continue;
|
||||
if (count($results['answerRRs'] ?? []) !== 1) // Parental agents MUST ignore a child's CSYNC RDATA set if multiple CSYNC resource records are found; only a single CSYNC record should ever be present.
|
||||
continue;
|
||||
list($serial, $flags, $types) = explode(' ', $results['answerRRs'][0]['rdataCSYNC'], 3);
|
||||
if ($flags !== '1')
|
||||
continue; // Skip unsupported flags
|
||||
if ($types !== 'NS')
|
||||
continue; // Skip unsupported types
|
||||
|
||||
// Get child/distant NS records
|
||||
try {
|
||||
$results = kdig(name: $entry['domain'], type: 'NS');
|
||||
} catch (KdigException) {
|
||||
fwrite(STDERR, $entry['domain'] . ' NS resolution failed.' . LF);
|
||||
continue;
|
||||
}
|
||||
if ($results['AD'] !== 1)
|
||||
continue;
|
||||
$child_ns_records = array_column($results['answerRRs'] ?? [], 'rdataNS');
|
||||
if (count($child_ns_records) === []) // Parental agents MUST NOT perform NS updates if there are no NS records returned in a query, as verified by DNSSEC denial-of-existence protection.
|
||||
continue;
|
||||
|
||||
// Get parent/local NS records
|
||||
$zone_raw = file_get_contents(CONF['reg']['suffixes_path'] . '/' . $suffix . 'zone');
|
||||
if ($zone_raw === false)
|
||||
output(403, 'Unable to read zone file.');
|
||||
$parent_ns_records = array_column(parseZoneFile($zone_raw, ['NS'], $entry['domain'], false), 3);
|
||||
|
||||
// Add child NS records that are not yet in parent
|
||||
foreach (array_diff($child_ns_records, $parent_ns_records) as $value_to_add)
|
||||
knotcZoneExec($suffix, [
|
||||
$entry['domain'],
|
||||
CONF['reg']['ttl'],
|
||||
'NS',
|
||||
$value_to_add,
|
||||
], 'add');
|
||||
// Delete parent NS records that are not part of child anymore
|
||||
foreach (array_diff($parent_ns_records, $child_ns_records) as $value_to_delete)
|
||||
knotcZoneExec($suffix, [
|
||||
$entry['domain'],
|
||||
'NS',
|
||||
$value_to_delete,
|
||||
], 'delete');
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-06-26 02:14+0200\n"
|
||||
"POT-Creation-Date: 2023-07-16 20:50+0200\n"
|
||||
"Language: fr\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
|
@ -528,7 +528,7 @@ msgstr "Serveurs de nom de la zone parente introuvables."
|
|||
msgid "NS authentication record not found."
|
||||
msgstr "Enregistrement d'authentification NS introuvable."
|
||||
|
||||
#: pg-act/ns/zone-add.php:66
|
||||
#: pg-act/ns/zone-add.php:67
|
||||
msgid "Zone created."
|
||||
msgstr "Zone créée."
|
||||
|
||||
|
@ -1230,6 +1230,26 @@ msgstr "Seuls les comptes <span aria-hidden=\"true\">👤 </span><em>approuvés<
|
|||
msgid "Nobody can register a domain under these suffixes:"
|
||||
msgstr "Personne ne peut enregistrer un domain sous ces suffixes :"
|
||||
|
||||
#: pg-view/reg/index.php:63
|
||||
msgid "Automatic updates from child zone"
|
||||
msgstr "Mises à jour automatiques depuis la zone enfant"
|
||||
|
||||
#: pg-view/reg/index.php:64
|
||||
msgid "CSYNC records"
|
||||
msgstr "Enregistrements CSYNC"
|
||||
|
||||
#: pg-view/reg/index.php:66
|
||||
msgid "The registry can synchronize NS records from the child zone if a CSYNC record is present at the apex of the child zone, has flags <code>1</code> and type bit map <code>NS</code>, and can be DNSSEC-validated. Others values are not supported."
|
||||
msgstr "Le registre peut synchroniser les enregistrements NS depuis la zone enfant si un enregistrement CSYNC est présent à l'apex de la zone enfant, a les drapeaux <code>1</code> et le type bit map <code>NS</code>, et peut être validé par DNSSEC. Les autres valeurs ne sont pas supportées."
|
||||
|
||||
#: pg-view/reg/index.php:68
|
||||
msgid "DNSSEC and DS records"
|
||||
msgstr "DNSSEC et enregistrements DS"
|
||||
|
||||
#: pg-view/reg/index.php:70
|
||||
msgid "Once DNSSEC has been manually enabled through the current interface, the delegated zone can publish a CDS record in order to update the DS record in the registry. A single CDS record with value <code>0 0 0 0</code> tells the registry to disable DNSSEC. Using a CDS record to enable DNSSEC is not supported."
|
||||
msgstr "Une fois que DNSSEC a été manuellement activé en utilisant l'interface actuelle, la zone déléguée peut publier un enregistrement CDS afin de mettre à jour l'enregistrement DS dans le registre. Un unique enregistrement CDS avec pour valeur <code>0 0 0 0</code> indique au registre de désactiver DNSSEC. Utiliser un enregistrement CDS pour activer DNSSEC n'est pas supporté."
|
||||
|
||||
#: pg-view/reg/register.php:2
|
||||
msgid "Register a new domain on your account."
|
||||
msgstr "Enregistrer un nouveau domaine sur son compte."
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-06-26 02:14+0200\n"
|
||||
"POT-Creation-Date: 2023-07-16 20:50+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -540,7 +540,7 @@ msgstr ""
|
|||
msgid "NS authentication record not found."
|
||||
msgstr ""
|
||||
|
||||
#: pg-act/ns/zone-add.php:66
|
||||
#: pg-act/ns/zone-add.php:67
|
||||
msgid "Zone created."
|
||||
msgstr ""
|
||||
|
||||
|
@ -1242,6 +1242,26 @@ msgstr ""
|
|||
msgid "Nobody can register a domain under these suffixes:"
|
||||
msgstr ""
|
||||
|
||||
#: pg-view/reg/index.php:63
|
||||
msgid "Automatic updates from child zone"
|
||||
msgstr ""
|
||||
|
||||
#: pg-view/reg/index.php:64
|
||||
msgid "CSYNC records"
|
||||
msgstr ""
|
||||
|
||||
#: pg-view/reg/index.php:66
|
||||
msgid "The registry can synchronize NS records from the child zone if a CSYNC record is present at the apex of the child zone, has flags <code>1</code> and type bit map <code>NS</code>, and can be DNSSEC-validated. Others values are not supported."
|
||||
msgstr ""
|
||||
|
||||
#: pg-view/reg/index.php:68
|
||||
msgid "DNSSEC and DS records"
|
||||
msgstr ""
|
||||
|
||||
#: pg-view/reg/index.php:70
|
||||
msgid "Once DNSSEC has been manually enabled through the current interface, the delegated zone can publish a CDS record in order to update the DS record in the registry. A single CDS record with value <code>0 0 0 0</code> tells the registry to disable DNSSEC. Using a CDS record to enable DNSSEC is not supported."
|
||||
msgstr ""
|
||||
|
||||
#: pg-view/reg/register.php:2
|
||||
msgid "Register a new domain on your account."
|
||||
msgstr ""
|
||||
|
|
|
@ -53,6 +53,7 @@ $knotZone = implode(' ', [
|
|||
]) . LF;
|
||||
foreach (CONF['ns']['servers'] as $server)
|
||||
$knotZone .= $_POST['domain'] . ' 86400 NS ' . $server . LF;
|
||||
$knotZone .= $_POST['domain'] . ' 86400 CSYNC 0 1 NS' . LF;
|
||||
if (is_int(file_put_contents($knotZonePath, $knotZone)) !== true)
|
||||
output(500, 'Failed to write new zone file.');
|
||||
if (chmod($knotZonePath, 0660) !== true)
|
||||
|
|
|
@ -58,3 +58,15 @@ foreach (CONF['reg']['suffixes'] as $suffix => $condition)
|
|||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2><?= _('Automatic updates from child zone') ?></h2>
|
||||
<h3><?= _('CSYNC records') ?></h3>
|
||||
<p>
|
||||
<?= _('The registry can synchronize NS records from the child zone if a CSYNC record is present at the apex of the child zone, has flags <code>1</code> and type bit map <code>NS</code>, and can be DNSSEC-validated. Others values are not supported.') ?>
|
||||
</p>
|
||||
<h3><?= _('DNSSEC and DS records') ?></h3>
|
||||
<p>
|
||||
<?= _('Once DNSSEC has been manually enabled through the current interface, the delegated zone can publish a CDS record in order to update the DS record in the registry. A single CDS record with value <code>0 0 0 0</code> tells the registry to disable DNSSEC. Using a CDS record to enable DNSSEC is not supported.') ?>
|
||||
</p>
|
||||
</section>
|
||||
|
|
Loading…
Reference in a new issue