Subject: kr_rule_local_data_ins + DNS64 stopped working - regression investigation
Hi Vladimír,
The kr_rule_local_data_ins + DNS64 solution from our December/January exchange has stopped
working.
Timeline:
- December 2025: You confirmed this works in 6.1.0
- January 2026: Working in production (6.1.0 → 6.2.0)
- May 2026: Broken (probably within the last month)
Current behavior:
- DNS64 detects the rule (EDE 29 "from DNS64")
- DNS64 launches the A sub-query (confirmed in debug logs)
- A records are successfully retrieved
- But DNS64 does NOT synthesize the final AAAA answer
root@lou:/home/gabriel# dig AAAA
archive.ubuntu.com @2a0b:cbc0:42::64
; <<>> DiG 9.18.39-0ubuntu0.24.04.3-Ubuntu <<>> AAAA
archive.ubuntu.com @2a0b:cbc0:42::64
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52590
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; EDE: 29: (BHD4: from DNS64)
;; QUESTION SECTION:
;archive.ubuntu.com. IN AAAA
;; AUTHORITY SECTION:
archive.ubuntu.com. 300 IN SOA localhost. nobody.invalid. 1 3600 1200
604800 10800
;; Query time: 22 msec
;; SERVER: 2a0b:cbc0:42::64#53(2a0b:cbc0:42::64) (UDP)
;; WHEN: Wed May 06 15:56:26 CEST 2026
;; MSG SIZE rcvd: 128
Verification:
- DNS64 works normally:
ipv4.google.com → 64:ff9b::acd9:10ee
- Problem occurs with or without tagset (tested with nil and 0)
Strange finding:
Downgraded to 6.1.0 and 6.2.0 (versions that worked in January) - problem persists. This
suggests something else in the system changed, but I can't identify what, it puzzles
me quite frankly.
Debug logs excerpt:
[plan] plan 'archive.ubuntu.com.' type 'AAAA'
[plan] plan 'archive.ubuntu.com.' type 'A'
[resolv] querying: 'ns3.canonical.com.' qtype: 'A'
[cache] => stashed
archive.ubuntu.com. CNAME
[plan] plan 'archive.ubuntu.com.cdn.cloudflare.net.' type ‘A'
Then returns NODATA instead of synthesizing.
Config (unchanged):
lua:
policy-script: |
for _, name in ipairs({
'security.ubuntu.com.',
'archive.ubuntu.com.'
}) do
assert(C.kr_rule_local_data_ins(
kres.rrset(kres.str2dname(name), kres.type.AAAA, nil, C.KR_RULE_TTL_DEFAULT),
nil, policy.get_tagset({'dns64'}), C.KR_RULE_OPTS_DEFAULT
) == 0)
end
And tested also:
lua:
policy-script: |
assert(C.kr_rule_local_data_ins(
kres.rrset(kres.str2dname('security.ubuntu.com.'), kres.type.AAAA, nil,
C.KR_RULE_TTL_DEFAULT),
nil, 0, C.KR_RULE_OPTS_DEFAULT
) == 0)
Any ideas what could have changed? The fact that even 6.1.0/6.2.0 no longer work suggests
a dependency issue, but I can't pinpoint it.
Thanks for your help!
Gabriel
Le 13 janv. 2026 à 14:22, oui.mages_0w--- via
knot-resolver-users <knot-resolver-users(a)lists.nic.cz> a écrit :
This is very elegant with tags, thank you for the tip.
The important point for my config was to know that a view with tags is acting like is has
an implicit answer: allowed.
I confirm it works, I use it this way:
views:
- answer: refused
subnets:
- 0.0.0.0/0
- ::/0
- answer: allow
options: &no_dns64
dns64: false
subnets:
- 127.0.0.0/8
- <other allowed IPv4 ranges>
- answer: allow
dst-subnet: <dst_subnet_public_ipv6>
options: *no_dns64
subnets: &ipv6_allowed
- ::1/128
- <other allowed IPv6 ranges>
- answer: allow
dst-subnet: <dst_subnet_anycast_ipv6>
options: *no_dns64
subnets: *ipv6_allowed
- tags: [ dns64 ]
dst-subnet: <dst_subnet_anycast_dns64_ipv6>
subnets: *ipv6_allowed
lua:
policy-script: |
assert(C.kr_rule_local_data_ins(
kres.rrset(kres.str2dname('security.ubuntu.com.'), kres.type.AAAA, nil,
C.KR_RULE_TTL_DEFAULT),
nil, policy.get_tagset({'dns64'}), C.KR_RULE_OPTS_DEFAULT
) == 0)
Thanks you again!
Le 13 janv. 2026 à 10:57, Vladimír Čunát
<vladimir.cunat(a)nic.cz> a écrit :
On 12/01/2026 00.11, * wrote:
However, I cannot use it in my production
environment as this returns NODATA globally (all views) for
security.ubuntu.com.
I have several views not using dns64 for which the AAAA record should be the existing
original answer.
While on Lua level it's not ergonomic, tags are supported in
these APIs, so you can do a tiny change, e.g.:
lua:
policy-script: |
assert(C.kr_rule_local_data_ins(
kres.rrset(kres.str2dname('security.ubuntu.com.'), kres.type.AAAA, nil,
C.KR_RULE_TTL_DEFAULT),
nil, policy.get_tagset({'myTag'}), C.KR_RULE_OPTS_DEFAULT
) == 0)
and then you just need to add myTag to the views where you want to apply this rule (in
YAML).
You can read more about tags and views in the docs, around page
https://www.knot-resolver.cz/documentation/latest/config-policy-new.html --