Knot DNS Signing Your Zones Itself, Transfers By Key Only
Knot DNS from EPEL as an authoritative server that signs your zones with DNSSEC, keeps your zone files as written and serves a change with no serial to bump. As installed the package cannot start. The live test validates answers with delv against the zone's own key, and is refused a transfer without the TSIG key. Original role, live-tested on Rocky Linux 10.
Verification
Live-testedReally deployed to a container sandbox, proven idempotent (a second run changes nothing), verified against the role’s assertions, then torn down.
Conformance
- Static validation (yamllint · ansible-lint)
Provenance
- SHA-256 checksum
- Signature (pending)
Functional
- Live-tested - applied, verified, destroyed
Last verified 2026-10-08 · podman 4.9.3 · ansible 2.21.4 · how we verify
Cite it in your README
badge · attributionPaste this beside the module in the repository that uses it. The badge is rendered from this artifact's verification record, so it reads live-tested because the record says so, and the link lands on this page.
[](https://www.iac-bazaar.com/catalog/ansible-knot?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)
Ansible role 1.0.0, live-tested on IaC Bazaar: [Knot DNS Signing Your Zones Itself, Transfers By Key Only](https://www.iac-bazaar.com/catalog/ansible-knot?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)
```yaml
# Knot DNS Signing Your Zones Itself, Transfers By Key Only: https://www.iac-bazaar.com/catalog/ansible-knot (download from your IaC Bazaar account)
```Preview:
Documentation
knot
Knot DNS from EPEL as an authoritative server that signs your zones itself: DNSSEC with ECDSA P-256 and NSEC3 as RFC 9276 recommends, zone files you own and Knot never rewrites, a change served after a reload with no serial to bump, transfers only with a TSIG key the role makes, no recursion, and each file checked by Knot's own parser before it lands. Original role for EL 10, live-tested with podman on Rocky Linux 10.
No download, and no version to pin. EL 10 packages knot in EPEL, so the
role installs it by name and takes what the distribution ships: a security
update arrives through dnf, not through a new release of this role. What the
role owns is the configuration and the proof that the service works.
The distribution's unit, our configuration. The role installs knot and
knot-utils from EPEL, writes /etc/knot/knot.conf (root:knot 0640: it holds
the transfer key) and one zone file per entry in knot_zones under
/etc/knot/zones, and enables the package's knot.service, which runs as the
knot user. The listener is 127.0.0.1:53 (TCP and UDP) by default; an
authoritative server answers on the host's public address, so set
knot_listen_address or add knot_extra_listen_addresses. The live test reads
the TCP and UDP sockets and expects loopback only.
The package cannot start as installed. dnf prints "warning: group knot does
not exist - using root": /etc/knot and knot.conf land root:root, knotd
runs as knot, and the unit fails on "no configuration source available" with
the package's own file (measured; rpm -V knot shows the group). The role gives
/etc/knot back to the knot group.
Signed, and checked from the outside. The live test builds a trust anchor
from the zone's own key and validates with delv: a name answers "fully
validated", a missing one "negative response, fully validated". NSEC3 uses no
salt and no extra iterations (1 0 0 -), as RFC 9276 recommends. To make the
zone validate on the internet, publish the DS records keymgr <zone> ds
prints at your registrar.
Your zone file stays yours. Knot keeps the signed zone in its journal and
never tries to write into the file (zonefile-sync: -1). The file is root:knot
0640, which Knot could not write anyway: with zonefile-sync: 0 it tries after
every change and logs "failed to update zone file (operation not permitted)"
(measured). A record added to the file with no serial bump is served, signed,
after a reload, Knot raising the served serial itself - and Knot's default
zonefile-load does that too (measured). What zonefile-load: difference-no-serial adds is a journal that stays consistent: without it, Knot
says whole "not compatible with 'journal-content: all'" and warns that with
signing and outgoing transfers "'zonefile-load: difference' should be set to
avoid malformed IXFR after manual zone file update" (measured). The live test
reads Knot's journal for both.
Transfers by key only, and no recursion. A transfer without the key fails,
one with a wrong key gets BADSIG, and the key the role makes
(/etc/knot/iacbazaar-tsig, root 0600) transfers the zone. A name the server
does not hold is REFUSED, and version.bind and id.server answer nothing.
Each file checked first. knot.conf by knotc conf-check; each zone file
by Knot's own loader through a throwaway configuration that names the
candidate, which refuses a syntax error, a CNAME beside other data and a
missing SOA (a missing glue record is only a warning).
License
Commercial - IaC Bazaar EULA. (c) IaC Bazaar.
Usage code & full reference need an account
The complete copy-paste usage, the full input/output reference, and operational notes are free with an account - shown here and bundled in the download. Sign in and this section fills in.
- Variables
- Test
Related modules
ansible-unbound-resolver
Unbound on loopback: DNSSEC validated locally against the root anchor, query names minimised, version hidden, and upstream over DNS-over-TLS by default because many networks reset TCP 53 to anything but a known resolver, which breaks full recursion the moment a DNSKEY answer outgrows UDP. Recursion is one setting away. Original role, live-tested on Rocky Linux 10.
ansible-bind-authoritative
BIND as an authoritative-only server. The package is a loopback resolver; add a zone and anyone who can query can copy the whole zone, and version.bind names the 9.18 to attack. This role turns recursion off, refuses transfers to anyone not listed, hides the identity records, rate-limits responses, and renders zones from data checked before they land. Original role, live-tested on Rocky Linux 10.
ansible-coredns
CoreDNS from the upstream release (sha256-verified) as a hardened system service answering authoritatively for your zones on 127.0.0.1:53 as a system user (CAP_NET_BIND_SERVICE through the unit), forwarding only when you name upstreams. The live test digs the example zone's A record with the aa flag, an NXDOMAIN in the zone and a REFUSED outside it. Original role, live-tested on Rocky Linux 10.
ansible-nsd
NSD from EPEL: an authoritative-only server for your zones, the configuration and every zone checked by NSD's own tools first, transfers only to the addresses and TSIG keys you name, response rate limiting, and the state directory the package leaves unwritable fixed. The live test gets the zone with the key and is refused without it. Original role, live-tested on Rocky Linux 10.
ansible-pdns-recursor
PowerDNS Recursor from EPEL on loopback: DNSSEC validated, and every upstream query sent over DNS-over-TLS with each forwarder's certificate checked against the name it must carry. The live test counts every upstream query as TLS, gets SERVFAIL for a broken signature, and has a copy naming the wrong certificate answer nothing. Original role, live-tested on Rocky Linux 10.
ansible-powerdns
PowerDNS authoritative from EPEL with its SQLite backend; the live test adds a zone through the API, gets the record from dig and NXDOMAIN for an unknown name, sees the API refuse a caller with no key, and reads the query counter. The schema is recovered when a docs-stripped host lacks it. Original role, live-tested on Rocky Linux 10.