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