ad flag missing in response to a tlsa query

I'm trying to figure out why the ad flag is not set for a specific
TLSA query:

unbound 1.9.6 is listening on port 1153:
dig +ad -p 1153 -t tlsa _25._tcp.mail.roaringpenguin.com
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 19607
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

It works fine for other domains, e.g.,
dig +ad -p 1153 -t tlsa _25._tcp.mail.nllabs.nl.
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 61517
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

delv can seemingly verify that -t tlsa _25._tcp.mail.roaringpenguin.com
does not exist:
; negative response, fully validated
; _25._tcp.mail.roaringpenguin.com. 1624 IN \-ANY ;-$NXDOMAIN

So what is wrong? Do I misunderstand what the ad flag indicates?
Is some setup (my side, server side) wrong?

* Claus Assmann via unbound-users:

I'm trying to figure out why the ad flag is not set for a specific
TLSA query:

unbound 1.9.6 is listening on port 1153:
dig +ad -p 1153 -t tlsa _25._tcp.mail.roaringpenguin.com
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 19607
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

It works fine for other domains, e.g.,
dig +ad -p 1153 -t tlsa _25._tcp.mail.nllabs.nl.
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 61517
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

delv can seemingly verify that -t tlsa _25._tcp.mail.roaringpenguin.com
does not exist:
; negative response, fully validated
; _25._tcp.mail.roaringpenguin.com. 1624 IN \-ANY ;-$NXDOMAIN

So what is wrong? Do I misunderstand what the ad flag indicates?

The opt-out bit is set on the NSEC3 record, so I assume the name is an
opt-out section of the zone. Therefore, the response cannot be
authenticated using DNSSEC.

Dne 01. 01. 20 v 10:50 Claus Assmann via unbound-users napsal(a):

I'm trying to figure out why the ad flag is not set for a specific
TLSA query:

unbound 1.9.6 is listening on port 1153:
dig +ad -p 1153 -t tlsa _25._tcp.mail.roaringpenguin.com
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 19607
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

It works fine for other domains, e.g.,
dig +ad -p 1153 -t tlsa _25._tcp.mail.nllabs.nl.
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 61517
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

delv can seemingly verify that -t tlsa _25._tcp.mail.roaringpenguin.com
does not exist:
; negative response, fully validated
; _25._tcp.mail.roaringpenguin.com. 1624 IN \-ANY ;-$NXDOMAIN

So what is wrong? Do I misunderstand what the ad flag indicates?
Is some setup (my side, server side) wrong?

Hello,

this is beacause zone roaringpenguin.com uses NSEC3 Opt-out:

$ dig +ad -t tlsa _25._tcp.mail.roaringpenguin.com +dnssec
(Look for the second "1" in NSEC3 records)

With opt-out, the positive answers can be validated normally but in case
of NXDomain, one cannot be sure that there is not an unsigned
delegation, since such delegation was opted out of the NSEC3 proof.
Therefore, the state of negative answer is only insecure. See
https://tools.ietf.org/html/rfc5155#section-9.2

this is beacause zone roaringpenguin.com uses NSEC3 Opt-out:

Thanks for the explanation!

With opt-out, the positive answers can be validated normally but in case
of NXDomain, one cannot be sure that there is not an unsigned
delegation, since such delegation was opted out of the NSEC3 proof.
Therefore, the state of negative answer is only insecure. See

Now I have to figure out how this information is returned from the
resolver to the application (which tries to implement DANE for SMTP).

Currently my code turns a permanent error into a temporary error
if the ad flag is not set for the TLSA lookup result but was set
for the MX/A results (because I thought that might indicate a
potential MitM attack).

However, this seems to be a legitimate configuration/result, but
how is that information returned by a (validating) resolver?
(this might be a question for a different mailing list, sorry).

> With opt-out, the positive answers can be validated normally but in
> case of NXDomain, one cannot be sure that there is not an unsigned
> delegation, since such delegation was opted out of the NSEC3 proof.
> Therefore, the state of negative answer is only insecure. See

Now I have to figure out how this information is returned from the
resolver to the application (which tries to implement DANE for SMTP).

The AD flag is not set.

Currently my code turns a permanent error into a temporary error if
the ad flag is not set for the TLSA lookup result but was set for the
MX/A results (because I thought that might indicate a potential MitM
attack).

That's a mistake in your implementation. A loopback validating resolver
is downgrade resistant, it never returns AD=0 for a lookup that should
have returned signed data. If the client does not set the "CD" bit,
validation either succeeds, or the lookup SERVFAILs.

Note that it is not just "NSEC3 opt-out" that cause TLSA results to be
insecure. The TLSA RR may also be aliased via a CNAME into an unsigned
zone, or there may be an unsigned delegation of the "_tcp" child node of
the MX host, ...

However, this seems to be a legitimate configuration/result, but how
is that information returned by a (validating) resolver? (this might
be a question for a different mailing list, sorry).

The validating resolver sets AD=0. Any non-failure response over a
secure channel (loopback or perhaps rarely IPsec) should not be
second-guessed by the application.

   1. AD=1, RCODE=NOERROR or NXDOMAIN => Valid signed result or DoE
   2. AD=0, RCODE=NOERROR or NXDOMAIN => Valid unsigned result or DoE
   3. RCODE=SERVFAIL, ..., timeout => Lookup failure

DANE applies in case 1, does not apply in case 2, and an MiTM attack may
be responsible for 3, so you skip the MX host.

When the MX host is (despite RFC5321, ...) an alias chain into an
ultimately unsigned zone, RFC7672 suggests checking the security status
of the initial CNAME (make a type=CNAME query with the MX host as
qname), which may be signed, and if so, still look for TLSA RRs of
_25._tcp.<mxhost>.

On the other hand if the MX is a CNAME chain signed at every step to an
ultimately signed A/AAAA RRset, then first check for TLSA RRs at the
destination, and those DoE or are not signed, then check at the source.

Perhaps follow-up to dane-users? Though this is more of a developer
question, and could perhaps even be for dane@ietf.org?