Why dig doesn't return ad flag when tested against authoritative server?

I have recently been working, but not finished settings up an email stack from scratch tutorial. Of importance was having dnssec enabled with unbound for opendkim. For work, I am trying to use kamailio to bypass nat on sip phones behind double nat, and one requirement was a DNS entry that is not supported by namecheap. It has been 30 years since I ran my own nameserver but decided to go this route with bind 9.20. Kamailio is running on a separate server but decided to put bind on the FreeBSD mail project server. I don't always understand what I am doing, more of a trial and error kind of guy, and once in awhile get that "Oh" light bulb kind of thing.

So I'll probably setup a tutorial on bind9 setup, since I did get it working. But getting no 'ad' flag with dig. It might just be that with my own authoritative server I am not considered authoritative? I have had some issues with ipfw, and putting static routes before outgoing setup and established seems to break things, might have something to do with edns. Currently everything works except when using dig against the FreeBSD dns server there is no 'ad' flag.

Figuring out how to upload the DS key records to namecheap with missing web enable buttons was fun but I'll cover that in the howto.
Code:
dig @1.1.1.1 okbsd.com +dnssec

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> @1.1.1.1 okbsd.com +dnssec
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23199
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;okbsd.com.                     IN      A

;; ANSWER SECTION:
okbsd.com.              600     IN      A       147.135.65.97
okbsd.com.              600     IN      RRSIG   A 13 2 600 20250613212124 20250530225014 8586 okbsd.com. FHw/GD0vlx/aczwTJhlrsdEHyH1Ur3TDiE7wF0rOnDSX/hFgHO5oBm4o 79xIU/a+O9cN7Ms/VBXzeOQpJc25ow==

# So NICE it has the 'ad' flag set.

Code:
dig @okbsd.com okbsd.com +dnssec +multiline

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> @okbsd.com okbsd.com +dnssec +multiline
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24928
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
; COOKIE: 41cf5a6648e6d47101000000683b992a1839d302be455dcb (good)
;; QUESTION SECTION:
;okbsd.com.             IN A

;; ANSWER SECTION:
okbsd.com.              600 IN A 147.135.65.97
okbsd.com.              600 IN RRSIG A 13 2 600 (
                                20250613212124 20250530225014 8586 okbsd.com.
                                FHw/GD0vlx/aczwTJhlrsdEHyH1Ur3TDiE7wF0rOnDSX
                                /hFgHO5oBm4o79xIU/a+O9cN7Ms/VBXzeOQpJc25ow== )
# So why no ad flag is set?

Also I just noticed, recursion enabled but not accepted, but I am not trying recursive, it's set as the authoritative server for itself?

Ok a little more DIGGING and found +norecurse
Code:
dig @okbsd.com okbsd.com +dnssec +multiline +norecurse

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> @okbsd.com okbsd.com +dnssec +multiline +norecurse
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12809
;; flags: qr aa; QUERY: 1, ANSWER: 2, AUTHORITY: 3, ADDITIONAL: 9

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
; COOKIE: f889823d2fda422a01000000683b9b3a8a405bea7ba10ee9 (good)
;; QUESTION SECTION:
;okbsd.com.             IN A

;; ANSWER SECTION:
okbsd.com.              600 IN A 147.135.65.97
okbsd.com.              600 IN RRSIG A 13 2 600 (
                                20250613212124 20250530225014 8586 okbsd.com.
                                FHw/GD0vlx/aczwTJhlrsdEHyH1Ur3TDiE7wF0rOnDSX
                                /hFgHO5oBm4o79xIU/a+O9cN7Ms/VBXzeOQpJc25ow== )

;; AUTHORITY SECTION:
okbsd.com.              600 IN NS ns1.okbsd.com.
okbsd.com.              600 IN NS ns2.okbsd.com.
okbsd.com.              600 IN RRSIG NS 13 2 600 (
                                20250613212124 20250530225014 8586 okbsd.com.
                                SWulrUU+kw5PxcKs0diKb8NfWpGPxKsiTjwCVI3IWPW7
                                2scABJS9mRf5IdZrgiYmoLI9o0+tsbvAU+8o8gkUOw== )

;; ADDITIONAL SECTION:
ns1.okbsd.com.          600 IN AAAA 2604:2dc0:100:1261::10
ns2.okbsd.com.          600 IN AAAA 2604:2dc0:100:1261::10
ns1.okbsd.com.          600 IN A 147.135.65.97
ns2.okbsd.com.          600 IN A 147.135.65.97
ns1.okbsd.com.          600 IN RRSIG A 13 3 600 (
                                20250613194706 20250530225014 8586 okbsd.com.
                                RcRvmhXeHfTJMRVeUw3Hw82Hr04B+leDrGeslW9Uo/tC
                                HZiH82IVL0Kd1oUKJ3TSf1VV08H82VkFTgBZY2+Pzg== )
ns1.okbsd.com.          600 IN RRSIG AAAA 13 3 600 (
                                20250613194706 20250530225014 8586 okbsd.com.
                                BO8Hf6L/8ZAFf5c48sOx21JJtAY5J8V0GMJuSaFlehD5
                                9V13+H2mKLZqo57fjIA9SlEE5zI0Cx99e8bot8DbXQ== )
ns2.okbsd.com.          600 IN RRSIG A 13 3 600 (
                                20250613194706 20250530225014 8586 okbsd.com.
                                FRXEvS/gypYiH7QmoBOknxsX0D4oK0f6kkr9KkqI8VmT
                                tufP8QAOWSz1EyqyMqWNoFIY7PVRULcB0mAUQfMeSw== )
ns2.okbsd.com.          600 IN RRSIG AAAA 13 3 600 (
                                20250613194706 20250530225014 8586 okbsd.com.
                                t0GQDLtCeqlIAkNht8V5jTvXMtDOT9szveb191/8RbLi
                                I5OMeTbOQA+8MXxd81V7V1+hqwwzAKV8FcPx3LI7IQ== )
I guess I should post my named.conf
Code:
options {
        directory       "/usr/local/etc/namedb/working";
        pid-file        "/var/run/named/pid";
        dump-file       "/var/dump/named_dump.db";
        statistics-file "/var/stats/named.stats";

        // DNSSEC
        dnssec-validation auto;


        // RECURSION
        recursion yes;
        allow-recursion { 127.0.0.1;
                        ::1;
                        147.135.65.97;
                        2604:2dc0:100:1261::10;
                        111.222.111.222
        };
        listen-on {
                127.0.0.1;
                147.135.65.97;
        };
        listen-on-v6    {
                ::1;
                2604:2dc0:100:1261::10;
        };
        disable-empty-zone "255.255.255.255.IN-ADDR.ARPA";
        disable-empty-zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA";
        disable-empty-zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA";
        allow-query { any; };
}

zone "." { type hint; file "/usr/local/etc/namedb/named.root"; };
...defaults ...
zone "okbsd.com" {
        type master;
        file "/usr/local/etc/namedb/dynamic/db.okbsd.com";
        dnssec-policy default;
        inline-signing yes;
};
Thanks in advance.... John
 
dig @1.1.1.1 okbsd.com +dnssec

; <<>> DiG 9.18.33-1~deb12u2-Debian <<>> @1.1.1.1 okbsd.com +dnssec
Seems you're using Linux, yet ask your questions over here? I don't care either way, but do keep in mind that there might be quite a difference between what you get on Linux, and what dns/bind-tools would provide. I conclude as much from all the config options which are available.

;; ANSWER SECTION:
okbsd.com. 600 IN A 147.135.65.97
okbsd.com. 600 IN RRSIG A 13 2 600 20250613212124 20250530225014 8586 okbsd.com. FHw/GD0vlx/aczwTJhlrsdEHyH1Ur3TDiE7wF0rOnDSX/hFgHO5oBm4o 79xIU/a+O9cN7Ms/VBXzeOQpJc25ow==

# So NICE it has the 'ad' flag set.
...
dig @okbsd.com okbsd.com +dnssec +multiline

# So why no ad flag is set?
You're querying 2 different servers, and thus you got 2 different results.

First you specifically target 1.1.1.1 but with the second command you use @okbsd.com which resolves to 147.135.65.97 (according to the first result), so it's a completely different server. I guess they don't sync? I wonder about that because when looking at the last answer section you'll see that it mentions having found 2 servers.

This makes it even stranger for me:

Code:
ns1.okbsd.com. 600 IN A 147.135.65.97
ns2.okbsd.com. 600 IN A 147.135.65.97
So why use 1.1.1.1 at first and expect that to suddenly work for the other server?
 
I use both Debian and FreeBSD interchangeably but for ShellUser's benefit I can use just FreeBSD for my tests. As the question is about bind9 running on a FreeBSD machine and you guys here are usually more responsive and let nit picky so prefer to ask my questions here. That being said I don't think its a Debian vs FreeBSD issue, and it might even by something with the registrar but since google returns ad on both domains it probably ins't that. And as I am still trying to find an answer ... thanks in advance.
Code:
# Local "FreeBSD" to okbsd.com lookup of another "other" "FreeBSD" server.
root@superbee:~# dig @147.135.65.97 okbiz.net +dnssec +multiline
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

# Local test of okbsd.com lookup of okbsd.com - no ad flags
root@superbee:~# dig @147.135.65.97 okbsd.com +dnssec +multiline
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
Remote query of okbsd.com bind9 server only shows the other domain with ad flag
Code:
# from okbsd.com against the other domain
[email]root@okbsd.com[/email]:~# dig @127.0.0.1 okbiz.net +dnssec +multiline
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

[email]root@okbsd.com[/email]:~# dig @127.0.0.1 okbsd.com +dnssec +multiline
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
Local query same as above only the other domain has ad flag set. So doesn't seem dependent on which interface, both yield same results.
Code:
# So lets ask google
root@superbee:~# dig @8.8.8.8 okbsd.com +dnssec +multiline
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

root@superbee:~# dig @8.8.8.8 okbiz.net +dnssec +multiline
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
See the difference, google says both are secure.


Thanks in advance
 
Okay sorry, I think I found the answer with google AI answer. More or less it is working how it is supposed to work. I didn't get the right answer before but I just needed to phrase my question apropriately.I kind of suspected this was the answer. It was an idea me nagging at the back of my brain and I wanted confirmation here.

As far as the 2 ns servers, the second one 'ns2' is a place holder for a secondary DNS. I'm planning to switch my main FreeBSD hosting in the fall so didn't want to do the extra work to set it up there. But I may since it seems pretty easy. put that, and the other debian test server with mail and the sip proxy I will probably scrap as well. Just wanted to get the DNS working so I can add a NAPTR record, not really sure what this does but seems like it is required to do a sip proxy and namecheap doesn't support NAPTR records.

Some how 'ad' only gets set when it gets authorized through a recursive lookup. And the 'ad' will not get set by an authoritative server since the auth servers only job is to provide authoritative answers (eg it is already authoritative or I guess the user would not be allowed or be using it as their primary dns server) not recursion on the auth domain. Eg my policies which said allow recursion only from my own machines, so other users would have little interest in putting this server in thier resolv.conf.

nslookup kind of gives the answer
Code:
root@superbee:~# nslookup okbsd.com 147.135.65.97
Server:         147.135.65.97
Address:        147.135.65.97#53

Name:   okbsd.com
Address: 147.135.65.97
Name:   okbsd.com
Address: 2604:2dc0:100:1261::10
VS
Code:
root@superbee:~# nslookup okbsd.com 8.8.8.8
Server:         8.8.8.8
Address:        8.8.8.8#53

Non-authoritative answer:
Name:   okbsd.com
Address: 147.135.65.97
Name:   okbsd.com
Address: 2604:2dc0:100:1261::10
Note the "Non-authoritative answer" when it's google

An authoritative server, even if it signs its own data, will not set the AD flag.
The AD flag is set by recursive resolvers to signal to the client that the data has been validated through DNSSEC.
To get a DNS response with the AD flag set, you need to query a recursive resolver that is configured to perform DNSSEC validation

Let me know if I got this wrong, but looks like normal behavior.
 
I just noticed the AA flag which means Authoritative Answer and only set if querying from the authoritative server so I guess it means that for dnssec to be working the ad flag needs to be set and if it isn't check for the aa flag. So I got to wondering if AA would be set even if dnssec is off so I setup a slave server. So interesting results.

Since the slave still considers itself authoritative it sets the AA flag even though I have not yet specified the slave ns server with the registrar.
So AA is useless for determining if a server is really authoritative, it only lets you know the server itself is configured as authoritative for the domain.

So I turned off dnssec on the slave.
No AA flag when I do a dig of the other domain.

So to really tell if your DNSSEC is working.
1. Test with dig your dns server against another domain that has DNSSEC enabled and look for the 'ad' flag.
2. To determine of dnssec is working right on a dns server with an authoritative domain, test a different dns server for which you are sure dnssec is enabled to see if your domain shows up with the 'ad' flag.
 
Back
Top