Hello,
I would like to report a bug in Knot DNS 3.5.x where AXFR responses do not
have the Authoritative Answer (AA) bit set, which appears to violate RFC
5936 §2.2.
Affected versions tested:
- 3.5.3
- 3.5.4
Packages tested:
- cznic.1~bookworm
Summary
RFC 5936 §2.2 states:
"Each DNS message returned by the AXFR server MUST have the AA bit set to
1."
However, Knot DNS sends AXFR responses with flags set to qr only. The AA
bit is not set in any of the messages in the transfer stream.
As a result, strict secondary DNS servers, notably Windows Server DNS,
reject such responses as invalid and abort the zone transfer.
Expected behavior
AXFR response messages should have the AA bit set.
Expected flags:
qr aa
Actual behavior
AXFR response messages have only the QR bit set.
Actual flags:
qr
Possible root cause
The function axfr_process_query() in src/knot/nameserver/axfr.c does not
appear to call knot_wire_set_aa().
By contrast, the normal query path, via solve_answer() in internet.c, does
set the AA bit, so SOA, A, and other authoritative responses are returned
correctly. The AXFR code path appears to bypass this logic.
Minimal reproducer
dig @<knot-master> +tcp AXFR <zone> | head -2
Observed output:
;; flags: qr;
The AA bit is missing.
This can also be verified with tcpdump: byte 3 of each DNS message in the
AXFR stream has value 0x80 / QR only, instead of 0x84 / QR + AA.
--
Best regards,
Mateusz Masłowski
Hi all
I am having trouble forwarding a subdomain since I upgraded to the latest
knot.
For a couple of years I have been running a custom DNS server under
dynamic.estada.ch that the clients find via my regular infrastructure.
On my primary zone I have these records, but knot appears to answer weirdly:
*estada.ch.zone*
dynamic.estada.ch. 3600 A 185.194.239.135
dynamic.estada.ch. 3600 AAAA 2a0a:51c0::12b
dynamic.estada.ch. 3600 NS dynamic.estada.ch.
kdig AAAA dynamic.estada.ch @ns1.estada.ch
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 29173
;; Flags: qr rd; QUERY: 1; ANSWER: 0; AUTHORITY: 1; ADDITIONAL: 3
;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR
;; QUESTION SECTION:
;; dynamic.estada.ch. IN AAAA
;; AUTHORITY SECTION:
dynamic.estada.ch. 3600 IN NS dynamic.estada.ch.
;; ADDITIONAL SECTION:
dynamic.estada.ch. 3600 IN A 185.194.239.135
dynamic.estada.ch. 3600 IN AAAA 2a0a:51c0::12b
But public servers don't get the glue records:
kdig AAAA dynamic.estada.ch @9.9.9.9
;; ->>HEADER<<- opcode: QUERY; status: SERVFAIL; id: 63899
;; Flags: qr rd ra; QUERY: 1; ANSWER: 0; AUTHORITY: 0; ADDITIONAL: 1
;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR
;; QUESTION SECTION:
;; dynamic.estada.ch. IN AAAA
The trouble is that most resolvers are now unable to resolve the domain as
the AAAA and A queries still get answered with NS + additional A+AAAA.
Is there a configuration option to tell knot to actually respond with the A
or AAAA record when asked?
Also ANY, TXT, or CAA queries behave the same as NS queries:
kdig ANY dynamic.estada.ch @ns1.estada.ch
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 14419
;; Flags: qr rd; QUERY: 1; ANSWER: 0; AUTHORITY: 1; ADDITIONAL: 3
;; EDNS PSEUDOSECTION:
;; Version: 0; flags: ; UDP size: 1232 B; ext-rcode: NOERROR
;; QUESTION SECTION:
;; dynamic.estada.ch. IN ANY
;; AUTHORITY SECTION:
dynamic.estada.ch. 3600 IN NS dynamic.estada.ch.
;; ADDITIONAL SECTION:
dynamic.estada.ch. 3600 IN A 185.194.239.135
dynamic.estada.ch. 3600 IN AAAA 2a0a:51c0::12b
I am happy for any pointers you may have.
Cheers,
Stefan
Hi,
until now I had 3 secondaries running and a hidden primary. This ran perfectly well.
Now, I'd like to add some fallback functionality to deal with a potential longer downtime of my hidden primary. Thus I added two more hidden primaries such that now every host (3) has a hidden primary that can serve every secondary at all hosts. But: Only one should be active! Zone and database data will frequently be rsynced to both inactive primaries. If there would be a downtime I will have to start one of the others to continue.
According to my understanding of https://www.knot-dns.cz/docs/3.5/html/configuration.html#secondary-slave-zo… I have been in the naive understanding that a configuration like ...
remote:
- id: primaryMWN # MWN hidden primary (running)
address: 10.0.1.203@5333
- id: primaryKBN # KBN hidden primary (not running, standby)
address: 10.0.2.203@5333
- id: primaryEDN # EDN hidden primary (not running, standby)
address: 10.0.3.203@5333
template:
- id: default
master: [primaryMWN, primaryKBN, primaryEDN] # queried in that order
… would work, because of:
"Note that the master option accepts a list of remotes, which are queried for a zone refresh sequentially in the specified order. When the server receives a zone change notification from a listed remote, only that remote is used for a subsequent zone transfer."
But I do get error massages like:
edn.ellael.lan (ns3) knot[29856]: warning: [ellael.org.] refresh, remote primaryKBN not usable
edn.ellael.lan (ns3) knot[29856]: info: [ellael.org.] refresh, remote primaryEDN, address 10.0.3.203@5333, failed (connection reset)
edn.ellael.lan (ns3) knot[29856]: warning: [ellael.org.] refresh, remote primaryEDN not usable
edn.ellael.lan (ns3) knot[29856]: error: [ellael.org.] refresh, failed (no usable master), next retry at 2026-04-27T19:03:03+0200, expires in 1119353 seconds
edn.ellael.lan (ns3) knot[29856]: error: [ellael.org.] zone event 'refresh' failed (no usable master)
If I do use "master: primaryMWN" only, everything runs as expected.
I must have misunderstood something ...
Ok, I will have to modify all remaining secondary's knot.conf files if desaster strikes and another primary has to take over.
BTW: I wanted to omit a multi primary setup as mentioned in https://www.knot-dns.cz/docs/3.5/singlehtml/#multi-primary because I do have the feeling that this is some sort of overkill for hosting 5 domains, only ;-)
Are there other ways to achieve my goal? ;-)
Thanks and regards,
Michael
Hi,
Fastmail has been running Knot for a few years now. Thank you for such excellent software!
I'm new to this list, and new to the Knot codebase, but I'm an experienced C developer and have been working on Cyrus IMAPd (a mostly C codebase) for many years.
We have hundreds of thousands of domains, and currently they all have the same set of service IPs compiled into them. This has generally been fine - setting up a new server takes an hour or so to build all the domains, but we just wait until it's done then bring it into rotation.
Our current challenge -- we want to be able to transfer everything to a new IP range quickly for datacenter failover. Rebuilding every zone is too expensive for this. I looked at a few different issues and (along with Claude) figured that it wasn't much work to extend the ALIAS type to follow the pointer to another zone inside the same server and return the records from that. I have an initial pass at:
https://github.com/fastmail/knot-dns/tree/local-alias-synth
For now I've kept it as separate commits showing the evolution of the idea as I've tested it more and thought through how I want it to interact (basically any ALIAS get substituted with the contents of the name it points to, so you can mix and match them all sorts of ways).
I'm very happy to engage on testing and modifying this code to match what the upstream project wants; or revisit the approach if this doesn't match your vision. I just need something that has these properties, and this seemed a good way to get there.
Thanks,
Bron.
Hello,
In this other use-case, described in the thread "IXFR commit time scaling", there was a reply refering to
https://www.knot-dns.cz/docs/3.5/singlehtml/#signing-threads and
https://www.knot-dns.cz/docs/3.5/singlehtml/#adjust-threads
Which made me wonder...
a] you can have an external networked HSM, which sounds promising to speed up signing a lot...
b] nowadays you also have even 128 core processers, even mutiple CPU slots, which sounds as a immense boost for co-proccesing...
c] you could combine those...
Clinical data would propably be hard, but hypothetical/esitimated;
what would be wise/pointless/smart/insane to increase signing of large zones?
I'd expect that RAM speed is a major factor also.
What would be an ideal setup today?
--
With kind regards,
Met vriendelijke groet,
Mit freundlichen Grüß,
Leo Vandewoestijne
<***(a)dns.company>
<www.dns.company>
Hi Knot team,
I'm running Knot as an Auth secondary receiving IXFR from a BIND 9 primary.
To isolate bottlenecks I've stripped the config down as far as I know how.
Here's what I'm using.
zonefile-sync: -1
zonefile-load: none
journal-content: none
There is no DNSSEC or any downstream IXFR serving happening. Logs are
confirming that it is genuine IXFR and no signs of any AXFR fallback.
"semantic-checks" is off, and knotd is linked against jemalloc. I'm really
trying to make this as quick as possible by avoiding the disk.
The pattern:
IXFR processing time scales roughly proportionally with total zone size,
even when the changeset is small, for example, a few hundred RRs out of
several hundred thousand.
There is what appears to be a full zone walk on every IXFR commit in the
adjust logic, with single threaded execution due to parent befroe child
ordering requirements. Although I'd want your confirmation before reading
too much into it.
Questions:
1. With journal-content: none, does IXFR apply trigger a full in-memory
tree walk of the QP-trie, rather than an isolated incremental record-level
update? If so, is that a necessary consequence of running without a journal
to maintain state?
2. For a secondary with no NSEC/NSEC3, no wildcards or any downstream
IXFR'ing, could a "lightweight secondary" mode bypass post-apply
bookkeeping that might only be targetted to primaries and signers?
3. Could it rewalk only subtrees where adds or removes happen to their
ancestors, rather than the full zone? If NSEC is absent, is the prev
pointer chain actually used at query time, or can it be skipped entirely?
Our use case is secondary-only, with large zones and high frequency
updates. We're hoping there is something on the configuration or roadmap
side that might help, and ultimately not sure if we're just bumping up
against a realistic constraint.
Thanks for the great software btw, loving it.
Thanks!
Hi all,
I just set up catalog zones for the first time. I'm using a conf file
with my list of zones. After creating a catalog zone and adding member
zones to it, I executed 'knotc reload'. The catalog zone then appeared
in the output of 'zone-status', and member zones were listed with the
catalog zone name. However, 'zone-read <catalog.zone>' showed no PTR
records. I tried 'zone-reload <catalog.zone>', updated serials on the
member zones and such, but the catalog zone remained empty until knotd
was restarted. I saw this behavior on both 3.4.4 and 3.5.2. Is this
the intended behavior? Is there a way to generate the catalog without
restarting knotd?
Thanks in advance,
Bill