{ ... }: let domains = import ../../modules/dns/domains.nix; in { imports = [ ../../modules/dns/authoritative.nix ]; time.timeZone = "Etc/GMT-1"; # UTC+1 (fixed offset, no DST) services.timesyncd.enable = true; # Automatic DNSSEC signing policy (primary only). ECDSA P-256/SHA-256 with # Knot's default key management: the ZSK auto-rolls and the KSK is kept stable, # so the DS at the registrar only changes on a manual KSK rollover. services.knot.settings.policy = [ { id = "cnx"; algorithm = "ecdsap256sha256"; } ]; # ns1 = primary (master): loads each zone from its file and serves it to ns2. # zonefile-load = difference-no-serial lets us edit records without touching the # SOA serial; Knot diffs the file, assigns a date-based serial, signs the zone, # then notifies ns2 and lets it pull the signed zone via AXFR/IXFR. services.knot.settings.zone = map (d: { domain = d; file = ../../modules/dns/zones + "/${d}.zone"; "zonefile-load" = "difference-no-serial"; "zonefile-sync" = "-1"; "journal-content" = "all"; # required by difference-no-serial; holds the live signed zone "serial-policy" = "dateserial"; "dnssec-signing" = true; "dnssec-policy" = "cnx"; notify = [ "ns2" ]; acl = [ "acl_ns2" ]; }) domains; }