I have configured Unbound to:
- listen for domain queries on all interfaces in a LAN,
- forward these domain queries to an external DNS resolver via TLS,
- receive the resolved domain IPs from the external DNS resolver and return them to the corresponding clients.
How do I verify that such a configuration is functioning? Especially, how do I verify that:
- Unbound has forwarded the domain queries to the desired external DNS resolver over TLS?
- The resolved domain IPS are from the external DNS resolver and are not resolved by Unbound?
Below are two results from dig
ging google.com
. How can i use these results to do the above mentioned verifications?
root@DNS:/etc/unbound# dig google.com A @192.168.1.50 -p 3000
; <<>> DiG 9.18.28-0ubuntu0.24.04.1-Ubuntu <<>> google.com A @192.168.1.50 -p 3000
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22452
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 300 IN A 142.251.175.138
google.com. 300 IN A 142.251.175.100
google.com. 300 IN A 142.251.175.113
google.com. 300 IN A 142.251.175.101
google.com. 300 IN A 142.251.175.139
google.com. 300 IN A 142.251.175.102
;; Query time: 12 msec
;; SERVER: 192.168.1.50#3000(192.168.1.50) (UDP)
;; WHEN: Wed Oct 30 14:04:16 UTC 2024
;; MSG SIZE rcvd: 135
root@DNS:/etc/unbound# dig google.com A @192.168.1.50 -p 3000
; <<>> DiG 9.18.28-0ubuntu0.24.04.1-Ubuntu <<>> google.com A @192.168.1.50 -p 3000
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39764
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 300 IN A 142.251.175.139
google.com. 300 IN A 142.251.175.113
google.com. 300 IN A 142.251.175.100
google.com. 300 IN A 142.251.175.101
google.com. 300 IN A 142.251.175.138
google.com. 300 IN A 142.251.175.102
;; Query time: 184 msec
;; SERVER: 192.168.1.50#3000(192.168.1.50) (UDP)
;; WHEN: Wed Oct 30 14:05:30 UTC 2024
;; MSG SIZE rcvd: 135
Below are logs in unbound.log
with verbosity: 3
after restarting the unbound.service
and running the above dig command twice. I can see that the external DNS resolver is mentioned but I can't understand which line shows that it has resolved the domain and return the results to unbound.
[1730296502] unbound[6506:0] info: service stopped (unbound 1.19.2).
[1730296502] unbound[6506:0] info: server stats for thread 0: 0 queries, 0 answers from cache, 0 recursions, 0 prefetch, 0 rejected by ip ratelimiting
[1730296502] unbound[6506:0] info: server stats for thread 0: requestlist max 0 avg 0 exceeded 0 jostled 0
[1730296502] unbound[6506:0] info: server stats for thread 1: 0 queries, 0 answers from cache, 0 recursions, 0 prefetch, 0 rejected by ip ratelimiting
[1730296502] unbound[6506:0] info: server stats for thread 1: requestlist max 0 avg 0 exceeded 0 jostled 0
[1730296502] unbound[6506:0] info: server stats for thread 2: 0 queries, 0 answers from cache, 0 recursions, 0 prefetch, 0 rejected by ip ratelimiting
[1730296502] unbound[6506:0] info: server stats for thread 2: requestlist max 0 avg 0 exceeded 0 jostled 0
[1730296502] unbound[6506:0] info: server stats for thread 3: 0 queries, 0 answers from cache, 0 recursions, 0 prefetch, 0 rejected by ip ratelimiting
[1730296502] unbound[6506:0] info: server stats for thread 3: requestlist max 0 avg 0 exceeded 0 jostled 0
[1730296503] unbound[6658:0] debug: module config: "subnetcache validator iterator"
[1730296503] unbound[6658:0] notice: init module 0: subnetcache
[1730296503] unbound[6658:0] warning: subnetcache: serve-expired is set but not working for data originating from the subnet module cache.
[1730296503] unbound[6658:0] warning: subnetcache: prefetch is set but not working for data originating from the subnet module cache.
[1730296503] unbound[6658:0] debug: subnetcache: option registered (8)
[1730296503] unbound[6658:0] notice: init module 1: validator
[1730296503] unbound[6658:0] notice: init module 2: iterator
[1730296503] unbound[6658:0] debug: target fetch policy for level 0 is 3
[1730296503] unbound[6658:0] debug: target fetch policy for level 1 is 2
[1730296503] unbound[6658:0] debug: target fetch policy for level 2 is 1
[1730296503] unbound[6658:0] debug: target fetch policy for level 3 is 0
[1730296503] unbound[6658:0] debug: target fetch policy for level 4 is 0
[1730296503] unbound[6658:0] debug: Forward zone server list:
[1730296503] unbound[6658:0] info: DelegationPoint<dns.quad9.net.>: 0 names (0 missing), 4 addrs (0 result, 4 avail) parentNS
[1730296503] unbound[6658:2] debug: Forward zone server list:
[1730296503] unbound[6658:2] info: DelegationPoint<dns.quad9.net.>: 0 names (0 missing), 4 addrs (0 result, 4 avail) parentNS
[1730296503] unbound[6658:0] debug: cache memory msg=66104 rrset=66104 infra=7952 val=66400 subnet=74536
[1730296503] unbound[6658:1] debug: Forward zone server list:
[1730296503] unbound[6658:1] info: DelegationPoint<dns.quad9.net.>: 0 names (0 missing), 4 addrs (0 result, 4 avail) parentNS
[1730296503] unbound[6658:0] info: start of service (unbound 1.19.2).
[1730296503] unbound[6658:2] debug: cache memory msg=66104 rrset=66104 infra=7952 val=66400 subnet=74536
[1730296503] unbound[6658:3] debug: Forward zone server list:
[1730296503] unbound[6658:3] info: DelegationPoint<dns.quad9.net.>: 0 names (0 missing), 4 addrs (0 result, 4 avail) parentNS
[1730296503] unbound[6658:1] debug: cache memory msg=66104 rrset=66104 infra=7952 val=66400 subnet=74536
[1730296503] unbound[6658:3] debug: cache memory msg=66104 rrset=66104 infra=7952 val=66400 subnet=74536
[1730297056] unbound[5388:0] debug: subnetcache[module 0] operate: extstate:module_state_initial event:module_event_new
[1730297056] unbound[5388:0] info: subnetcache operate: query google.com. A IN
[1730297056] unbound[5388:0] debug: validator[module 1] operate: extstate:module_state_initial event:module_event_pass
[1730297056] unbound[5388:0] info: validator operate: query google.com. A IN
[1730297056] unbound[5388:0] debug: iterator[module 2] operate: extstate:module_state_initial event:module_event_pass
[1730297056] unbound[5388:0] info: resolving google.com. A IN
[1730297056] unbound[5388:0] info: resolving (init part 2): google.com. A IN
[1730297056] unbound[5388:0] info: resolving (init part 3): google.com. A IN
[1730297056] unbound[5388:0] info: processQueryTargets: google.com. A IN
[1730297056] unbound[5388:0] info: sending query: google.com. A IN
[1730297056] unbound[5388:0] debug: sending to target: <google.com.> 216.239.38.10#53
[1730297056] unbound[5388:0] debug: cache memory msg=70045 rrset=100203 infra=29147 val=67208 subnet=74536
[1730297056] unbound[5388:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1730297056] unbound[5388:0] info: iterator operate: query google.com. A IN
[1730297056] unbound[5388:0] info: response for google.com. A IN
[1730297056] unbound[5388:0] info: reply from <google.com.> 216.239.38.10#53
[1730297056] unbound[5388:0] info: query response was ANSWER
[1730297056] unbound[5388:0] info: finishing processing for google.com. A IN
[1730297056] unbound[5388:0] debug: validator[module 1] operate: extstate:module_wait_module event:module_event_moddone
[1730297056] unbound[5388:0] info: validator operate: query google.com. A IN
[1730297056] unbound[5388:0] debug: subnetcache[module 0] operate: extstate:module_wait_module event:module_event_moddone
[1730297056] unbound[5388:0] info: subnetcache operate: query google.com. A IN
[1730297056] unbound[5388:0] debug: cache memory msg=70045 rrset=100203 infra=29147 val=67208 subnet=74536
[1730297130] unbound[5379:0] debug: subnetcache[module 0] operate: extstate:module_state_initial event:module_event_new
[1730297130] unbound[5379:0] info: subnetcache operate: query google.com. A IN
[1730297130] unbound[5379:0] debug: validator[module 1] operate: extstate:module_state_initial event:module_event_pass
[1730297130] unbound[5379:0] info: validator operate: query google.com. A IN
[1730297130] unbound[5379:0] debug: iterator[module 2] operate: extstate:module_state_initial event:module_event_pass
[1730297130] unbound[5379:0] info: resolving google.com. A IN
[1730297130] unbound[5379:0] info: resolving (init part 2): google.com. A IN
[1730297130] unbound[5379:0] info: resolving (init part 3): google.com. A IN
[1730297130] unbound[5379:0] info: processQueryTargets: google.com. A IN
[1730297130] unbound[5379:0] info: sending query: google.com. A IN
[1730297130] unbound[5379:0] debug: sending to target: <com.> 2001:503:83eb::30#53
[1730297130] unbound[5379:0] debug: cache memory msg=78073 rrset=130165 infra=41184 val=69264 subnet=74536
[1730297130] unbound[5379:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_noreply
[1730297130] unbound[5379:0] info: iterator operate: query google.com. A IN
[1730297130] unbound[5379:0] info: processQueryTargets: google.com. A IN
[1730297130] unbound[5379:0] info: sending query: google.com. A IN
[1730297130] unbound[5379:0] debug: sending to target: <com.> 192.41.162.30#53
[1730297130] unbound[5379:0] debug: cache memory msg=78073 rrset=130165 infra=41184 val=69264 subnet=74536
[1730297130] unbound[5379:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1730297130] unbound[5379:0] info: iterator operate: query google.com. A IN
[1730297130] unbound[5379:0] info: response for google.com. A IN
[1730297130] unbound[5379:0] info: reply from <com.> 192.41.162.30#53
[1730297130] unbound[5379:0] info: query response was REFERRAL
[1730297130] unbound[5379:0] info: processQueryTargets: google.com. A IN
[1730297130] unbound[5379:0] info: sending query: google.com. A IN
[1730297130] unbound[5379:0] debug: sending to target: <google.com.> 216.239.32.10#53
[1730297130] unbound[5379:0] debug: cache memory msg=78073 rrset=132972 infra=41184 val=69414 subnet=74536
[1730297130] unbound[5379:0] debug: iterator[module 2] operate: extstate:module_wait_reply event:module_event_reply
[1730297130] unbound[5379:0] info: iterator operate: query google.com. A IN
[1730297130] unbound[5379:0] info: response for google.com. A IN
[1730297130] unbound[5379:0] info: reply from <google.com.> 216.239.32.10#53
[1730297130] unbound[5379:0] info: query response was ANSWER
[1730297130] unbound[5379:0] info: finishing processing for google.com. A IN
[1730297130] unbound[5379:0] debug: validator[module 1] operate: extstate:module_wait_module event:module_event_moddone
[1730297130] unbound[5379:0] info: validator operate: query google.com. A IN
[1730297130] unbound[5379:0] debug: subnetcache[module 0] operate: extstate:module_wait_module event:module_event_moddone
[1730297130] unbound[5379:0] info: subnetcache operate: query google.com. A IN
[1730297130] unbound[5379:0] debug: cache memory msg=78333 rrset=133364 infra=41492 val=69414 subnet=74536
You can leave
tshark
running on the server while resolving names from a client usingdig
:on the server (replacing
eth0
with the interface used by Unbound to communicate with the external resolver) and, e.g.on the client.
-Y'ip.src == 192.168.1.50 and dns.qry.type == 1'
: sets up a filter to display only type 1 (A) DNS requests coming from IP 192.168.1.50 (the server)By setting
tshark
up this way, any type 1 (A) DNS request coming from IP 192.168.1.50 (the server) passing through interfaceeth0
on the server will be displayed, easily allowing you to understand if a request was forwarded or resolved by Unbound itself because Unbound itself was authoritative for the name / the name was cached.For example, if I leave
sudo tshark -i wlo1 -Y'ip.src == 192.168.1.93 and dns.qry.type == 1'
running on a terminal and rundig askubuntu.com A
on another terminal, this shows up (my machine is on 192.168.1.93 and is set up to resolve names by querying 192.168.1.254):I discovered a way to check this via checking
/etc/unbound/unbound.log
. The file/etc/unbound/unbound.conf
must declare these attributes.unbound.log
would contain logs stating that :The query is forwarded to external DNS over TLS.
The external DNS replying:
The ip address of the queried domain:
The logs shown in my question did not contain these lines as they were not generated using these attributes.