Why is Unbound not like a `dig +trace`?

François Lafont francois.lafont.1978 at gmail.com
Tue Sep 23 18:15:35 UTC 2025


Hi,

I have a question concerning Unbound but maybe it will be a question about the DNS protocol finally, I'm not sure.

First, you can test a:

     dig +trace ac-versailles.fr. CAA

it works _systematically_ (it's a real domain). It's a `dig +trace`, so it's an iteration of no recursive DNS requests by following referrals from a root server to... the good server. :)

But now, with unbound, I have noticed that its way to solve a name is not a like a `dig +trace`. Let me show you. I have tested Unbound version 1.19.2 from an updated Ubuntu 24.04. Of course, I can test a more recent version (I will...). Here is my little configuration:

----------------------------------
server:

     # added by me.
     interface: 0.0.0.0
     port: 5300
     use-syslog: no
     statistics-interval: 0

     # rest comes from the distribution packaging.

     access-control: 0.0.0.0/0 allow
     auto-trust-anchor-file: "/var/lib/unbound/root.key"

remote-control:
   control-enable: yes
   control-interface: /run/unbound.ctl
----------------------------------

And I run unboud in foreground mode like this:

     /usr/sbin/unbound -d -p -v

Now I try:

     # 10.111.222.11 is the IP address of the VM where I have installed unbound.
     dig @10.111.222.11 -p 5300 ac-versailles.fr. CAA

It works too, but it's not my point. :)

During the dig request, here is the logs:

----------------------------------
[1758649362] unbound[3491:0] notice: Start of unbound 1.19.2.
[1758649362] unbound[3491:0] notice: init module 0: subnetcache
[1758649362] unbound[3491:0] notice: init module 1: validator
[1758649362] unbound[3491:0] notice: init module 2: iterator
[1758649362] unbound[3491:0] info: start of service (unbound 1.19.2).
[1758649378] unbound[3491:0] info: resolving ac-versailles.fr. CAA IN
[1758649378] unbound[3491:0] info: priming . IN NS
[1758649378] unbound[3491:0] info: response for . NS IN
[1758649378] unbound[3491:0] info: reply from <.> 192.112.36.4#53
[1758649378] unbound[3491:0] info: query response was ANSWER
[1758649378] unbound[3491:0] info: response for . NS IN
[1758649378] unbound[3491:0] info: reply from <.> 202.12.27.33#53
[1758649378] unbound[3491:0] info: query response was ANSWER
[1758649378] unbound[3491:0] info: response for . NS IN
[1758649378] unbound[3491:0] info: reply from <.> 192.58.128.30#53
[1758649378] unbound[3491:0] info: query response was ANSWER
[1758649378] unbound[3491:0] info: response for . NS IN
[1758649378] unbound[3491:0] info: reply from <.> 198.41.0.4#53
[1758649378] unbound[3491:0] info: query response was ANSWER
[1758649378] unbound[3491:0] info: priming successful for . NS IN
[1758649378] unbound[3491:0] info: response for ac-versailles.fr. CAA IN
[1758649378] unbound[3491:0] info: reply from <.> 193.0.14.129#53
[1758649378] unbound[3491:0] info: query response was REFERRAL

# My point is here... see below.
[1758649378] unbound[3491:0] info: response for ac-versailles.fr. CAA IN
[1758649378] unbound[3491:0] info: reply from <fr.> 194.0.36.1#53
[1758649378] unbound[3491:0] info: query response was REFERRAL

[1758649378] unbound[3491:0] info: resolving b.ns.ac-versailles.fr. AAAA IN
[1758649378] unbound[3491:0] info: resolving a.ns.ac-versailles.fr. AAAA IN
[1758649378] unbound[3491:0] info: response for ac-versailles.fr. CAA IN
[1758649378] unbound[3491:0] info: reply from <ac-versailles.fr.> 195.83.95.1#53
[1758649378] unbound[3491:0] info: query response was ANSWER
[1758649378] unbound[3491:0] info: prime trust anchor
[1758649378] unbound[3491:0] info: generate keytag query _ta-4f66-9728. NULL IN
[1758649378] unbound[3491:0] info: resolving . DNSKEY IN
[1758649378] unbound[3491:0] info: resolving _ta-4f66-9728. NULL IN
[1758649378] unbound[3491:0] info: response for a.ns.ac-versailles.fr. AAAA IN
[1758649378] unbound[3491:0] info: reply from <ac-versailles.fr.> 195.83.95.1#53
[1758649378] unbound[3491:0] info: query response was nodata ANSWER
[1758649378] unbound[3491:0] info: response for b.ns.ac-versailles.fr. AAAA IN
[1758649378] unbound[3491:0] info: reply from <ac-versailles.fr.> 195.83.95.1#53
[1758649378] unbound[3491:0] info: query response was nodata ANSWER
[1758649379] unbound[3491:0] info: response for . DNSKEY IN
[1758649379] unbound[3491:0] info: reply from <.> 192.203.230.10#53
[1758649379] unbound[3491:0] info: query response was ANSWER
[1758649379] unbound[3491:0] info: validate keys with anchor(DS): sec_status_secure
[1758649379] unbound[3491:0] info: Successfully primed trust anchor . DNSKEY IN
[1758649379] unbound[3491:0] info: validated DS fr. DS IN
[1758649379] unbound[3491:0] info: resolving fr. DNSKEY IN
[1758649379] unbound[3491:0] info: response for b.ns.ac-versailles.fr. AAAA IN
[1758649379] unbound[3491:0] info: reply from <ac-versailles.fr.> 195.83.95.1#53
[1758649379] unbound[3491:0] info: query response was ANSWER
[1758649379] unbound[3491:0] info: response for a.ns.ac-versailles.fr. AAAA IN
[1758649379] unbound[3491:0] info: reply from <ac-versailles.fr.> 195.83.95.2#53
[1758649379] unbound[3491:0] info: query response was ANSWER
[1758649379] unbound[3491:0] info: response for _ta-4f66-9728. NULL IN
[1758649379] unbound[3491:0] info: reply from <.> 199.7.83.42#53
[1758649379] unbound[3491:0] info: query response was NXDOMAIN ANSWER
[1758649379] unbound[3491:0] info: response for fr. DNSKEY IN
[1758649379] unbound[3491:0] info: reply from <fr.> 194.0.36.1#53
[1758649379] unbound[3491:0] info: query response was ANSWER
[1758649379] unbound[3491:0] info: validated DNSKEY fr. DNSKEY IN
[1758649379] unbound[3491:0] info: NSEC3s for the referral proved no DS.
[1758649379] unbound[3491:0] info: Verified that unsigned response is INSECURE
[1758649379] unbound[3491:0] info: response for a.ns.ac-versailles.fr. AAAA IN
[1758649379] unbound[3491:0] info: reply from <ac-versailles.fr.> 195.83.95.1#53
[1758649379] unbound[3491:0] info: query response was nodata ANSWER
[1758649379] unbound[3491:0] info: response for b.ns.ac-versailles.fr. AAAA IN
[1758649379] unbound[3491:0] info: reply from <ac-versailles.fr.> 195.83.95.1#53
[1758649379] unbound[3491:0] info: query response was nodata ANSWER
----------------------------------

Now I have caught the trafic with tcpdump/wireshark. According to these lines from logs:

----------------------------------
[1758649378] unbound[3491:0] info: response for ac-versailles.fr. CAA IN
[1758649378] unbound[3491:0] info: reply from <fr.> 194.0.36.1#53
[1758649378] unbound[3491:0] info: query response was REFERRAL
----------------------------------

Unbound makes a CAA request to 194.0.36.1 (which is g.ext.nic.fr, a DNS of the .fr zone). But it's false according to my tcpdump/wireshark:

----------------------------------
12 19:42:58.950815  testvm1.virt.priv  DNS  g.ext.nic.fr          87    Standard query 0x8c97 A ac-versailles.fr OPT
13 19:42:58.967235  g.ext.nic.fr       DNS  testvm1.virt.priv    525    Standard query response 0x8c97 A ac-versailles.fr NS a.ns.ac-versailles.fr NS b.ns.ac-versailles.fr NSEC3 RRSIG NSEC3 RRSIG A 195.83.95.2 A 195.83.95.1 OPT
34 19:42:59.011527  testvm1.virt.priv  DNS  g.ext.nic.fr          73    Standard query 0xddd0 DNSKEY fr OPT
38 19:42:59.027866  g.ext.nic.fr       DNS  testvm1.virt.priv    331    Standard query response 0xddd0 DNSKEY fr DNSKEY DNSKEY RRSIG OPT
----------------------------------

This is the copy of the only 4 lines of my wireshark when I filter with "ip.addr==194.0.36.1". The only request to "194.0.36.1" I can see with tcpdump (the truth ;)) is a type=A DNS request, not type=CAA request.

Why? Why is Unbound not like a `dig +trace`?

A `dig +trace` is a iteration of `dig +norecurse @<server> ac-versailles.fr. CAA` (with type **CAA** not A). With unbound it seems to be different. Why?

In a way, it's not a problem. In the end, we have the DNS resolution. Yes, but with this request, it becomes a real problem:

     dig +trace in.ac-versailles.fr. CAA

which works systematically with dig. But with unbound, the same request never works (timeout).
Indeed, with `dig +trace`, the last request is one of the two:

     # a.ns and b.ns are NS servers of zone "ac-versailles.fr".
     dig @a.ns.ac-versailles.fr. in.ac-versailles.fr CAA
     dig @b.ns.ac-versailles.fr. in.ac-versailles.fr CAA

and the response is empty with NOERROR. But with unbound this request never happens. Instead, unbound makes a type=A request and then try to request the NS server of the in.ac-versailles.fr zone (because there is delegation), which are unreachable (private IP addresses). In fact, there is a little DNS proxy in a.ns and b.dns to automatically answer an empty response with NOERROR to the type=CAA/name=in.ac-versailles.fr request. But Unbound never makes that request because its behavior seems to be different than a `dig +trace`.

Can you explain this point (why unbound is not like a `dig +trace`)?
Thanks for your help.

-- 
François Lafont



More information about the Unbound-users mailing list