Can Unbound DNSSEC be used with forwarding a private domain to Dnsmasq?

Started by LemurTech, February 13, 2026, 04:25:18 AM

Previous topic - Next topic
I'm running OPNsense 26.1.1 with:
  • Unbound as the main DNS resolver (full recursion)
  • Dnsmasq for DHCP for two VLANs (1 and 12); DNS listening on port 53053
  • Windows AD domain: sarangan.lan (VLAN 1, AD DNS forwards to Unbound

Internal DNS domains
  • sarangan.lan - Windows domain, VLAN 1
  • iot.lan - IoT devices, VLAS 12 - pointed to Unbound
  • infra.lan - APs, switches in both VLANs - pointed to Unbound

Architecture
  • VLAN 1 domain clients use AD DNS
  • DCs forward all non-AD queries to Unbound (192.168.2.1)
  • Unbound does full recursion for public domains
  • Domain Override in Unbound: iot.lan -> 127.0.0.1:53053 so Unbound forwards iot.lan to Dnsmasq
  • Dnsmasq has DHCP reservations with hostnames under iot.lan

Behavior
With DNSSEC disabled in Unbound, everything works:
  • somedevice.iot.lan resolves (from VLAN 1 or from OPNsense)
  • DCs forward iot.lan queries properly
  • Unbound forwards to Dnsmasq correctly

If I enable DNSSEC, resolution for iot.lan starts failing within 30 seconds:
  • Queries return NXDOMAIN
  • Disabling DNSSEC immediately fixes it

Example (works, then stops working):

root@fw01:~ # nslookup emporia.iot.lan 127.0.0.1
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
Name:   emporia.iot.lan
Address: 192.168.12.86

root@fw01:~ # nslookup emporia.iot.lan 127.0.0.1
Server:         127.0.0.1
Address:        127.0.0.1#53

** server can't find emporia.iot.lan: NXDOMAIN

I've tried:

  • Adding iot.lan, infra.lan, and sarangan.lan to Insecure Domains (these seem to be added automatically in the config when forwarding to Dnsmasq is configured, but I added them anyways).
  • Disabling Strict QNAME Minimisation
  • Disabling DNSSEC hardening
  • Clearing caches
  • Restarting services

The issue persists as long as DNSSEC is enabled.

I have been all over the interwebs and have had long discussions with the AI oracles. Is it expected behavior that Unbound DNSSEC validation conflicts with forwarding a private, non-delegated TLD like .lan to Dnsmasq?

My current suspicion is that this is not an Unbound problem, it's a Dnsmasq problem. When DNSSEC is enabled, something changes the behavior of Dnsmasq and it no longer treats `iot.lan` as local:

DNSSEC enabled:

root@fw01:~ # drill .0.0.1 -p 53053 emporia.iot.lan
;; ->>HEADER<<- opcode: QUERY, rcode: NXDOMAIN, id: 64879
;; flags: qr rd ra ; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;; emporia.iot.lan.     IN      A

;; ANSWER SECTION:

;; AUTHORITY SECTION:
.       2494    IN      SOA     a.root-servers.net. nstld.verisign-grs.com. 2026021301 1800 900 604800 86400

;; ADDITIONAL SECTION:

;; Query time: 0 msec
;; SERVER: 127.0.0.1
;; WHEN: Fri Feb 13 10:31:58 2026
;; MSG SIZE  rcvd: 108

DNSSEC Disabled:

root@fw01:~ # drill u/127.0.0.1 -p 53053 emporia.iot.lan
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 7948
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; emporia.iot.lan.     IN      A

;; ANSWER SECTION:
emporia.iot.lan.        1       IN      A       192.168.12.86

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 0 msec
;; SERVER: 127.0.0.1
;; WHEN: Fri Feb 13 10:32:35 2026
;; MSG SIZE  rcvd: 49

I will be honest with you :

I am not even sure you will ever get this to work, because even tho DNSmasqd can be an Authoritive DNS Server I think it can only deal with DNSSEC when used as a Forwarding DNS Server ?!

But you could try adding the right DNSSEC related DNS Records to DNSmasqd and see the result for yourself...



I am confused by the DNSmasqd documentation/man page about this stuff so I wouldn't mind anyone showing me that I am wrong! ;)
Weird guy who likes everything Linux and *BSD on PC/Laptop/Tablet/Mobile and funny little ARM based boards :)

I do a similar thing, using Unbound as the resolver, forwarding my local domain to Dnsmasq and it seems fine.

Do you have DNSSEC validation turned on Dnsmasq?  I don't in my setup, only in Unbound.  I don't have DNSSEC hardening turned on but I notice you've tried that both ways anyway.

Another thing I notice which may not be relevant is that Dnsmasq seems to be trying to forward the query, given the response mentions NXDOMAIN with a reference to root-servers.net.  In my setup I have enabled 'Do not forward to system defined DNS servers' in Dnsmasq settings.  It may not help but since you're using Dnsmasq just to serve local domains, and Unbound should be the recursive resolver, it makes sense to me to never allow Dnsmasq to do any forwarding.  If nothing else it may make it easier to diagnose what's going on since you'll know any answer from Dnsmasq is _only_ from Dnsmasq.

I notice another potential problem in your tests: doing some similar tests myself, I noticed that the port specifier must be first

This will use the specified port:
drill -p PORT @127.0.0.1 NAME
This will not, the port seems to just be silently ignored:
drill @127.0.0.1 -p PORT NAME
(I normally use dig instead, where the order doesn't seem to matter as much.)

So what you're seeing probably is Unbound behaviour changing, rather than Dnsmasq.  The fact you don't see 'aa' (authoritative answer) in the flags response is a clue that you're going via a recursive resolver and not hitting Dnsmasq directly.

tl;dr I don't know why it doesn't work, sorry!  But maybe you can at least change your drill command and be sure Dnsmasq isn't changing here.