Files
cnx-network-clan/docs/src/dns.md
T
Berwn a4fe2a7b3a Document how to pull registrar DS records from Knot on ns1
Explain that key material is auto-managed in the KASP keystore under
/var/lib/knot, and that the registrar DS is generated per zone with
`sudo -u knot keymgr <zone> ds`.
2026-06-18 12:12:10 +07:00

3.0 KiB

DNS

Authoritative DNS for three zones, served by Knot:

  • cnx.network
  • buildfor.life
  • cnx.email

Add a zone in modules/dns/domains.nix and drop a matching <domain>.zone file in modules/dns/zones/.

Primary / secondary

  • ns1 = primary (master). Loads each zone from its file, signs it, and notifies ns2. Config in machines/ns1/configuration.nix.
  • ns2 = secondary (slave). Pulls every zone from ns1 (AXFR/IXFR) and accepts its NOTIFY. Config in machines/ns2/configuration.nix.

Zone transfers run over the ZeroTier mesh, authenticated with a shared TSIG key (dns-tsig, a clan var copied to both machines).

Serial handling

ns1 uses zonefile-load = difference-no-serial with serial-policy = unixtime: edit records without touching the SOA serial — Knot diffs the file, assigns a strictly-monotonic unixtime serial, signs, and transfers. journal-content = all holds the live signed zone (required by difference-no-serial).

DNSSEC

Automatic signing on ns1 only, policy cnx: ECDSA P-256/SHA-256. The ZSK auto-rolls; the KSK is kept stable, so the DS at the registrar only changes on a manual KSK rollover.

Registrar DS records

Knot manages all key material itself on ns1 (the only signer); the KSK/ZSK private keys live in the KASP keystore under /var/lib/knot (backed up nightly — see Backups). You never touch the private keys directly.

What a registrar needs is the DS record for a zone's KSK, which anchors the zone into the parent's chain of trust. Generate it on ns1 — the keymgr wrapper is already pointed at Knot's config, and it runs as the knot user that owns the keystore:

sudo -u knot keymgr <zone> ds

e.g. sudo -u knot keymgr cnx.email ds. Paste the printed DS record (key tag, algorithm 13, digest type, digest) into the registrar's DNSSEC form for that domain. Repeat per signed zone (cnx.network, buildfor.life, cnx.email) at whichever registrar holds each delegation. After submitting, confirm the parent publishes it with dig +short DS <zone>.

The ZSK rolls automatically and needs no registrar action; only a KSK rollover requires re-submitting the DS.

Pending (manual): submit DS records for buildfor.life and cnx.email once they're at a DNSSEC-capable registrar.

ACME DNS-01

A dedicated TSIG key (acme_ddns), scoped by acl_acme to TXT updates at or under _acme-challenge.<zone> on ns1 only. Knot signs the record and transfers it to ns2, which never needs this key. Retrieve the client config with:

clan vars get ns1 dns-acme-tsig/acme.conf

Runbook: stale secondary

If ns2 serves stale records while SOA serials match (e.g. after a manual zone edit that didn't bump the serial as expected), force a fresh transfer on ns2:

knotc zone-retransfer <zone>

Watch the CNX DNS Grafana dashboard: the per-nameserver SOA serial table should agree across ns1/ns2, and "seconds until zone expiry" on the secondary should reset on each successful transfer rather than counting toward zero.