public inbox for development@lists.ipfire.org
 help / color / mirror / Atom feed
* ZONEMD Records in DBL RPZ Zones Break Unbound DNSSEC Priming
@ 2026-02-15 11:58 ummeegge
  2026-02-16 11:35 ` Michael Tremer
  0 siblings, 1 reply; 9+ messages in thread
From: ummeegge @ 2026-02-15 11:58 UTC (permalink / raw)
  To: development

We've identified a compatibility issue with the IPFire Domain Blocklist
(DBL) RPZ zones. These zones contain a ZONEMD record (Type 63) at the
zone apex (e.g., ads.rpz.ipfire.org. 60 IN ZONEMD ...), intended for
data integrity checks. This record causes a critical failure in Unbound
DNS resolver when used with RPZ.

Impact was here:

    DNSSEC Failure: Unbound does not ignore the ZONEMD record during
RPZ processing and mistakenly interprets the zone apex record as a
policy rule for the root name (.).

    Symptoms: After loading more than one IPFire RPZ zone or modifying
the configuration file and restarting/reloading Unbound, the resolver
fails to prime its DNSSEC trust anchor. Typical log entries:


    unbound: info: rpz: applied [dbl-ads] . rpz-local-data . DNSKEY IN
    unbound: info: failed to prime trust anchor -- could not fetch
DNSKEY rrset . DNSKEY IN

Result: All DNSSEC validation fails, rendering the resolver unable to
resolve any domain names and effectively breaking DNS resolution for
the entire network.

The issue affects more users, as confirmed by Unbound GitHub Issue
#1404 (verified in Unbound 1.24.1/1.24.2) and potentially also #1152.

Technical Cause:

In Unbound's RPZ implementation (services/rpz.c), the function
rpz_type_ignored() filters out DNSSEC-related records (DNSKEY, RRSIG,
NSEC, etc.) to prevent them from being treated as policy rules. ZONEMD
(RFC 8976, Type 63) is missing from this ignore list – this is IMHO an
Unbound bug.

Loading process:

    Unbound reads the apex ZONEMD record.

    rpz_type_ignored(63) returns 0 → record gets processed.

    strip_dname_origin() removes the zone name → empty label (.).

    A rpz-local-data rule for . is created, blocking root DNSKEY
priming queries.

Note: A detailed analysis and proposed fix (add case
LDNS_RR_TYPE_ZONEMD: to rpz_type_ignored()) has been submitted to
Unbound Issue #1404. The root cause lies with Unbound.

Reproduction Steps:

    Configure one IPFire DBL RPZ zone (e.g., ads.rpz.ipfire.org)
following the instructions from https://www.ipfire.org/dbl/how-to-use .

    Restart Unbound → zone gets cached (may still work initially).

    Modify the configuration or add a second zone and restart Unbound
again → priming failure appears in logs.

Tested with Unbound 1.24.1 on IPFire Core 199 and Unbound 1.24.2 on
Rocky Linux 8.10 (on Unbounds Github). Single zone may load initially,
but fails reliably with config changes or by adding multiple zones.

Current temporary workaround:

Remove ZONEMD records post-download via script (e.g., cron job after
AXFR):


    sed -i '/IN[[:space:]]\+ZONEMD/d'
/var/lib/unbound/*.rpz.ipfire.org.zone

Then reload Unbound.


While Unbound developers might likely investigate and may fix
rpz_type_ignored() (Issue #1404), which way should IPFire users go
until then – since this blocks testing the Beta DBL usage with Unbound
(great project)? Haven´t tested a patched version of Unbound since i
have currently no build environment around but if again, am happy to
test preview versions!

May someone have similar problems or even another workaround or
potential Fix for this ?

Best regards,

Erik


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-02-17 18:14 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-15 11:58 ZONEMD Records in DBL RPZ Zones Break Unbound DNSSEC Priming ummeegge
2026-02-16 11:35 ` Michael Tremer
2026-02-16 13:30   ` ummeegge
2026-02-16 16:11     ` Michael Tremer
2026-02-17  9:18       ` ummeegge
2026-02-17 10:13         ` Michael Tremer
2026-02-17 12:29           ` ummeegge
2026-02-17 15:44             ` Michael Tremer
2026-02-17 18:14               ` ummeegge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox