[Dnsmasq-discuss] [PATCH v2] Fix local host records being overridden by upstream NXDOMAIN
Dominik Derigs
dl6er at dl6er.de
Sun Aug 9 07:57:05 UTC 2026
Hey Simon,
this is iteration #2 of a patch I sent on 2026-05-16, archived as
https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2026q2/018476.html
It has had no reply, so here it is again, rebased onto current master
and with
one small change over v1 (see below).
A name that only exists locally - /etc/hosts, a DHCP lease, or
--host-record -
loses to upstream when it is queried for a type it does not have.
answer_request()
finds no matching record, gives up, and the query is forwarded. The
upstream is
authoritative for the public parent zone, knows nothing about the name and
answers NXDOMAIN, which is factually wrong: the name does exist, it just
has no
record of that type. This bites hard in practice because Linux resolvers
send
AAAA and HTTPS/SVCB alongside every A query, so a plain A-only host
record is
enough to trigger it several times per lookup.
There is already a safety net for this in process_reply(), converting an
upstream NXDOMAIN for a locally-known name into NODATA, but it sits
behind the
!bogusanswer gate. For a local name under a signed public parent the
upstream
denial is exactly the answer that fails validation, so the one code path
meant
to catch this case is skipped whenever DNSSEC is on.
The patch closes both:
1. answer_request() answers NODATA itself when the name has local
F_HOSTS/F_DHCP/F_CONFIG records but nothing for the queried type, so the
query is never forwarded in the first place.
2. The NXDOMAIN-to-NODATA conversion in process_reply() runs before the
bogus-answer gate. Local records are authoritative for a name's
existence
no matter what an upstream denial validates to.
Changed in v2: the log_query() call in answer_request() now only sets
F_IPV4/F_IPV6 for A/AAAA queries, so an MX or HTTPS query is logged as
"NODATA" instead of "NODATA-IPv6".
Reproducer, with --host-record=node-1.example.org,10.0.20.20 and any
upstream
that is authoritative for example.org:
dig @localhost node-1.example.org A -> NOERROR, 10.0.20.20
dig @localhost node-1.example.org AAAA -> forwarded, upstream NXDOMAIN
dig @localhost node-1.example.org HTTPS -> forwarded, upstream NXDOMAIN
With the patch the last two are answered locally as NODATA and never
leave the
machine. Downstream report with a user hitting this in the wild:
https://github.com/pi-hole/FTL/issues/2841
Best regards,
Dominik
-------------- next part --------------
A non-text attachment was scrubbed...
Name: v2-0001-Fix-local-host-records-being-overridden-by-upstre.patch
Type: text/x-patch
Size: 3891 bytes
Desc: not available
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20260809/238cd151/attachment.bin>
More information about the Dnsmasq-discuss
mailing list