I have two upstream local dns servers for example.tld which I can resolve directly:
root@OpenWrt:~# dig subdomain.example.tld @172.29.30.31
; <<>> DiG 9.20.15 <<>> subdomain.example.tld @172.29.30.31
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12295
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;subdomain.example.tld. IN A
;; ANSWER SECTION:
subdomain.example.tld. 60 IN A 172.29.30.10
subdomain.example.tld. 60 IN A 172.29.30.20
;; Query time: 10 msec
;; SERVER: 172.29.30.31#53(172.29.30.31) (UDP)
;; WHEN: Sun Nov 23 11:31:07 UTC 2025
;; MSG SIZE rcvd: 65
tcpdump
root@OpenWrt:~# tcpdump -A -i any -n 'udp and (host 172.29.30.30 or host 172.29.30.31)'
tcpdump: WARNING: any: That device doesn't support promiscuous mode
(Promiscuous mode not supported on the "any" device)
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
### dig subdomain.example.tld @172.29.30.31
11:31:07.273129 eth4 Out IP 192.168.110.4.49285 > 172.29.30.31.53: 12295+ [1au] A? subdomain.example.tld. (56)
E..T.{..@..;..n...d....5.@?40.. .........subdomain.example.tld.......).........
..+.}..9-.
11:31:07.282074 eth4 In IP 172.29.30.31.53 > 192.168.110.4.49285: 12295 2/0/0 A 172.29.30.10, A 172.29.30.20 (65)
E..]..@.=.k...d...n..5...I..0............subdomain.example.tld..............<....d
.........<....d.
but I get no answer if I dig 127.0.0.1
root@OpenWrt:~# dig subdomain.example.tld @127.0.0.1
; <<>> DiG 9.20.15 <<>> subdomain.example.tld @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48256
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;subdomain.example.tld. IN A
;; Query time: 10 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
;; WHEN: Sun Nov 23 11:31:27 UTC 2025
;; MSG SIZE rcvd: 33
root@OpenWrt:~#
however tcpdump shows it did query the server and got a response :
tcpdump
root@OpenWrt:~# tcpdump -A -i any -n 'udp and (host 172.29.30.30 or host 172.29.30.31)'
tcpdump: WARNING: any: That device doesn't support promiscuous mode
(Promiscuous mode not supported on the "any" device)
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
### dig subdomain.example.tld @127.0.0.1
11:31:27.931569 eth4 Out IP 192.168.110.4.58912 > 172.29.30.30.53: 19864+ [1au] A? subdomain.example.tld. (56)
E..T.m@.@.^]..n...d.. .5.@? M.. .........subdomain.example.tld.......).........
.....}I..e
11:31:27.931635 eth4 Out IP 192.168.110.4.58912 > 172.29.30.31.53: 19864+ [1au] A? subdomain.example.tld. (56)
E..Ts.@.@.....n...d.. .5.@?4M.. .........subdomain.example.tld.......).........
.....}I..e
11:31:27.940663 eth4 In IP 172.29.30.31.53 > 192.168.110.4.58912: 19864 2/0/0 A 172.29.30.20, A 172.29.30.10 (65)
E..].)@.=.f...d...n..5. .I..M............subdomain.example.tld..............<....d..........<....d
11:31:27.941686 eth4 In IP 172.29.30.30.53 > 192.168.110.4.58912: 19864 2/0/0 A 172.29.30.20, A 172.29.30.10 (65)
E..]P%@.<.....d...n..5. .IZ.M............subdomain.example.tld..............X....d..........X....d
Same goes for nslookup :
root@OpenWrt:~# nslookup subdomain.example.tld 172.29.30.31
Server: 172.29.30.31
Address: 172.29.30.31:53
Non-authoritative answer:
Name: subdomain.example.tld
Address: 172.29.30.10
Name: subdomain.example.tld
Address: 172.29.30.20
*** Can't find subdomain.example.tld: No answer
Tcpdump
root@OpenWrt:~# tcpdump -A -i any -n 'udp and (host 172.29.30.30 or host 172.29.30.31)'
tcpdump: WARNING: any: That device doesn't support promiscuous mode
(Promiscuous mode not supported on the "any" device)
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
## nslookup subdomain.example.tld 172.29.30.31
13:32:08.032625 eth4 Out IP 192.168.110.4.32918 > 172.29.30.31.53: 29796+ A? subdomain.example.tld. (33)
E..=..@.@.....n...d....5.)?.td. .........subdomain.example.tld.....
13:32:08.032714 eth4 Out IP 192.168.110.4.32918 > 172.29.30.31.53: 30565+ AAAA? subdomain.example.tld. (33)
E..=..@.@.....n...d....5.)?.we. .........subdomain.example.tld.....
13:32:08.040892 eth4 In IP 172.29.30.31.53 > 192.168.110.4.32918: 29796 2/0/0 A 172.29.30.10, A 172.29.30.20 (65)
E..].>@.=.No..d...n..5...I.jtd...........subdomain.example.tld..............<....d
.........<....d.
13:32:10.533925 eth4 Out IP 192.168.110.4.32918 > 172.29.30.31.53: 30565+ AAAA? subdomain.example.tld. (33)
E..=..@.@.....n...d....5.)?.we. .........subdomain.example.tld.....
root@OpenWrt:~# nslookup subdomain.example.tld 127.0.0.1
Server: 127.0.0.1
Address: 127.0.0.1:53
Non-authoritative answer:
*** Can't find subdomain.example.tld: No answer
Tcpdump
root@OpenWrt:~# tcpdump -A -i any -n 'udp and (host 172.29.30.30 or host 172.29.30.31)'
tcpdump: WARNING: any: That device doesn't support promiscuous mode
(Promiscuous mode not supported on the "any" device)
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
#######nslookup subdomain.example.tld 127.0.0.1
11:32:47.987048 eth4 Out IP 192.168.110.4.37277 > 172.29.30.30.53: 23226+ A? subdomain.example.tld. (33)
E..=.|@.@.Ie..n...d....5.)? Z.. .........subdomain.example.tld.....
11:32:47.987137 eth4 Out IP 192.168.110.4.37277 > 172.29.30.31.53: 23226+ A? subdomain.example.tld. (33)
E..={.@.@.....n...d....5.)?.Z.. .........subdomain.example.tld.....
11:32:47.987359 eth4 Out IP 192.168.110.4.55877 > 172.29.30.30.53: 37405+ AAAA? subdomain.example.tld. (33)
E..=.}@.@.Id..n...d..E.5.)? ... .........subdomain.example.tld.....
11:32:47.987433 eth4 Out IP 192.168.110.4.55877 > 172.29.30.31.53: 37405+ AAAA? subdomain.example.tld. (33)
E..={.@.@.....n...d..E.5.)?.... .........subdomain.example.tld.....
11:32:47.996742 eth4 In IP 172.29.30.31.53 > 192.168.110.4.37277: 23226 2/0/0 A 172.29.30.10, A 172.29.30.20 (65)
E..]..@.=.H...d...n..5...I..Z............subdomain.example.tld..............<....d
.........<....d.
11:32:47.997406 eth4 In IP 172.29.30.30.53 > 192.168.110.4.37277: 23226 2/0/0 A 172.29.30.20, A 172.29.30.10 (65)
E..]._@.<..b..d...n..5...I..Z............subdomain.example.tld..............X....d..........X....d
11:32:50.490065 eth4 Out IP 192.168.110.4.55877 > 172.29.30.30.53: 37405+ AAAA? subdomain.example.tld. (33)
E..=.r@.@.Ho..n...d..E.5.)? ... .........subdomain.example.tld.....
11:32:50.490132 eth4 Out IP 192.168.110.4.55877 > 172.29.30.31.53: 37405+ AAAA? subdomain.example.tld. (33)
E..=|.@.@.....n...d..E.5.)?.... .........subdomain.example.tld.....
Full DHCP config
root@OpenWrt:~# cat /etc/config/dhcp
config dnsmasq
option domainneeded '1'
option localise_queries '1'
option rebind_protection '1'
option local '/lan/'
option domain 'lan'
option expandhosts '1'
option cachesize '1000'
option authoritative '1'
option readethers '1'
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
option localservice '1'
option ednspacket_max '1232'
option localuse '1'
list rebind_domain 'example.tld'
list server '/example.tld/172.29.30.30'
list server '/example.tld/172.29.30.31'
config dhcp 'lan'
option interface 'lan'
option start '100'
option limit '150'
option leasetime '12h'
option dhcpv4 'server'
option dhcpv6 'server'
option ra 'server'
root@OpenWrt:~#