Skip to content

Cached wildcard-expanded answer: NSEC3 duplicated 4x and RRSIGs dropped (15.6.2) #2267

Open

Description

@thospr

Environment

  • Technitium DNS Server 15.6.2, LXC container on Proxmox
  • DNSSEC validation: enabled
  • Forwarders: 9.9.9.9, 149.112.112.112; Serve Stale: enabled
  • Direct recursion (no forwarders) not tested for this issue

Zone fta.wf is public, DNSSEC-signed (ED25519, NSEC3) and contains *.fta.wf,
so foo.fta.wf can be used to reproduce. The authoritative servers
(ns1/ns2/ns3.hyp.net) always return a correct answer.

Steps

  1. Flush cache.
  2. Run dig +dnssec @10.0.0.20 foo.fta.wf A every 5 seconds.

Result (NSEC3 = number of NSEC3 records in AUTHORITY,
RRSIG_NSEC3 = number of RRSIGs covering NSEC3):
10:31:54 NSEC3=1 RRSIG_NSEC3=2 TTL=3600 <- Query log: Recursive
10:31:59 NSEC3=4 RRSIG_NSEC3=0 TTL=3595 <- Query log: Cached
10:32:04 NSEC3=4 RRSIG_NSEC3=0 TTL=3590 <- Cached
10:32:09 NSEC3=4 RRSIG_NSEC3=0 TTL=3585 <- Cached
10:32:14 NSEC3=4 RRSIG_NSEC3=0 TTL=3580 <- Cached
10:32:19 NSEC3=4 RRSIG_NSEC3=0 TTL=3575 <- Cached

Correct answer (first query): AUTHORITY has one NSEC3 plus 2 RRSIGs.
Broken answer (every cached query): AUTHORITY has the same NSEC3 four
times and no RRSIG for it. The ad flag is still set.

Observations

  • Every cache hit is broken; the first (recursive) answer is correct.
    Entries are not stale (TTL counts down normally).
  • Not affected: cached NODATA answers with NSEC3 (AAAA for an existing
    host) and positive answers for names with an explicit record.
  • Setting the CD bit makes no difference.
  • A validating client (systemd-resolved) fails on the cached answer.
  • Original symptom in the DNS Client tool: Extended DNS Error
    "RRSIGsMissing: Attack detected! e5m335uuom58dh2897eat9kl4hveg0bt.fta.wf/NSEC3".

good answer:

; <<>> DiG 9.20.29 <<>> +dnssec @10.0.0.20 foo.fta.wf A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57485
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 3, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;foo.fta.wf.                    IN      A

;; ANSWER SECTION:
foo.fta.wf.             2208    IN      A       130.61.54.175
foo.fta.wf.             2208    IN      RRSIG   A 15 2 3600 20261128072536 20261029072536 5453 fta.wf. SbykMKtLzwE0c+5g+FwQU1376ZjGX8qO2mEuAfGIOf+L50+rz6oQSP86 s1Lvh6EkYPyVO4AEncmjzvxfa+aVBQ==
foo.fta.wf.             2208    IN      RRSIG   A 15 2 3600 20261128072536 20261029072536 23249 fta.wf. hI0Kcj0vi+4j+ZbQkXxtoTrJXfckiDZKMNsAZfnWE+EDXqmOKnfyCY96 xGgwEsiVemelVCEUFyofXtYL7jlPCQ==

;; AUTHORITY SECTION:
E5M335UUOM58DH2897EAT9KL4HVEG0BT.fta.wf. 2208 IN NSEC3 1 0 0 - KOE1LGO9BB6UDHATSL19SE4NQF9G3DD7 TXT RRSIG
E5M335UUOM58DH2897EAT9KL4HVEG0BT.fta.wf. 2208 IN RRSIG NSEC3 15 3 3600 20261128072536 20261029072536 5453 fta.wf. I+Jg3dFZMlMkXhMd9fRJiyluXdVkfztkdRz027MpTlIibP5FiJ6boIax dSuKbakuVYDx72OzArOAXnZGpxzzCg==
E5M335UUOM58DH2897EAT9KL4HVEG0BT.fta.wf. 2208 IN RRSIG NSEC3 15 3 3600 20261128072536 20261029072536 23249 fta.wf. KnnMAO0z+pw63t1UGy4I5iisST0qovAb+nNWcUex6pydX7VY0a0GTr// njzer+i8j/ArbRtVzmnbXzkb7j3eCA==

;; Query time: 9 msec
;; SERVER: 10.0.0.20#53(10.0.0.20) (UDP)
;; WHEN: Thu Oct 29 10:55:06 CET 2026
;; MSG SIZE  rcvd: 542

broken answer:

; <<>> DiG 9.20.29 <<>> +dnssec @10.0.0.20 foo.fta.wf A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35599
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 4, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;foo.fta.wf.                    IN      A

;; ANSWER SECTION:
foo.fta.wf.             2202    IN      A       130.61.54.175
foo.fta.wf.             2202    IN      RRSIG   A 15 2 3600 20261128072536 20261029072536 5453 fta.wf. SbykMKtLzwE0c+5g+FwQU1376ZjGX8qO2mEuAfGIOf+L50+rz6oQSP86 s1Lvh6EkYPyVO4AEncmjzvxfa+aVBQ==
foo.fta.wf.             2202    IN      RRSIG   A 15 2 3600 20261128072536 20261029072536 23249 fta.wf. hI0Kcj0vi+4j+ZbQkXxtoTrJXfckiDZKMNsAZfnWE+EDXqmOKnfyCY96 xGgwEsiVemelVCEUFyofXtYL7jlPCQ==

;; AUTHORITY SECTION:
E5M335UUOM58DH2897EAT9KL4HVEG0BT.fta.wf. 2202 IN NSEC3 1 0 0 - KOE1LGO9BB6UDHATSL19SE4NQF9G3DD7 TXT RRSIG
E5M335UUOM58DH2897EAT9KL4HVEG0BT.fta.wf. 2202 IN NSEC3 1 0 0 - KOE1LGO9BB6UDHATSL19SE4NQF9G3DD7 TXT RRSIG
E5M335UUOM58DH2897EAT9KL4HVEG0BT.fta.wf. 2202 IN NSEC3 1 0 0 - KOE1LGO9BB6UDHATSL19SE4NQF9G3DD7 TXT RRSIG
E5M335UUOM58DH2897EAT9KL4HVEG0BT.fta.wf. 2202 IN NSEC3 1 0 0 - KOE1LGO9BB6UDHATSL19SE4NQF9G3DD7 TXT RRSIG

;; Query time: 0 msec
;; SERVER: 10.0.0.20#53(10.0.0.20) (UDP)
;; WHEN: Thu Oct 29 10:55:12 CET 2026
;; MSG SIZE  rcvd: 476

Activity

  1. ShreyasZare commented on Oct 29, 2026

    @ShreyasZare
    Member

    Thanks for reporting this issue. Will get this fixed soon.

  2. muhammad-tariq-zaman commented on Oct 29, 2026

    @muhammad-tariq-zaman

    One useful next diagnostic, following the details already in this issue, would be to repeat the same test with direct recursion (no forwarders): flush the cache, then run dig +dnssec @10.0.0.20 foo.fta.wf A repeatedly and compare whether the cached answer still shows NSEC3=4 with RRSIG_NSEC3=0, or returns to NSEC3=1 with RRSIG_NSEC3=2. That would help separate a cache-only fault from a forwarder-related one, since direct recursion is noted in the issue as not yet tested.

  3. thospr commented on Oct 29, 2026

    @thospr
    Author

    Update with data from a clean setup. In my LAN a gateway feature had been redirecting port 53 traffic to its own resolver; I paused it and verified that a query to a root server now returns the real answer. I also queried the authoritative server from a host outside my LAN: ns2.hyp.net returns a correct and complete answer for foo.fta.wf A (aa flag, TTL 3600, A + 2 RRSIG, NSEC3 + 2 RRSIG):

    ; <<>> DiG 9.18.39-0ubuntu0.22.04.7-Ubuntu <<>> +dnssec +norec @ns2.hyp.net foo.fta.wf A
    ; (2 servers found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10286
    ;; flags: qr aa; QUERY: 1, ANSWER: 3, AUTHORITY: 3, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags: do; udp: 1400
    ;; QUESTION SECTION:
    ;foo.fta.wf.                    IN      A
    
    ;; ANSWER SECTION:
    foo.fta.wf.             3600    IN      A       130.61.54.175
    foo.fta.wf.             3600    IN      RRSIG   A 15 2 3600 20261128072536 20261029072536 5453 fta.wf. SbykMKtLzwE0c+5g+FwQU1376ZjGX8qO2mEuAfGIOf+L50+rz6oQSP86 s1Lvh6EkYPyVO4AEncmjzvxfa+aVBQ==
    foo.fta.wf.             3600    IN      RRSIG   A 15 2 3600 20261128072536 20261029072536 23249 fta.wf. hI0Kcj0vi+4j+ZbQkXxtoTrJXfckiDZKMNsAZfnWE+EDXqmOKnfyCY96 xGgwEsiVemelVCEUFyofXtYL7jlPCQ==
    
    ;; AUTHORITY SECTION:
    e5m335uuom58dh2897eat9kl4hveg0bt.fta.wf. 3600 IN NSEC3 1 0 0 - KOE1LGO9BB6UDHATSL19SE4NQF9G3DD7 TXT RRSIG
    e5m335uuom58dh2897eat9kl4hveg0bt.fta.wf. 3600 IN RRSIG NSEC3 15 3 3600 20261128072536 20261029072536 5453 fta.wf. I+Jg3dFZMlMkXhMd9fRJiyluXdVkfztkdRz027MpTlIibP5FiJ6boIax dSuKbakuVYDx72OzArOAXnZGpxzzCg==
    e5m335uuom58dh2897eat9kl4hveg0bt.fta.wf. 3600 IN RRSIG NSEC3 15 3 3600 20261128072536 20261029072536 23249 fta.wf. KnnMAO0z+pw63t1UGy4I5iisST0qovAb+nNWcUex6pydX7VY0a0GTr// njzer+i8j/ArbRtVzmnbXzkb7j3eCA==
    
    ;; Query time: 17 msec
    ;; SERVER: 192.174.68.10#53(ns2.hyp.net) (UDP)
    ;; WHEN: Thu Oct 29 21:13:42 CET 2026
    ;; MSG SIZE  rcvd: 54
    

    The behaviour in Technitium is identical in all configurations (cache flushed, dig +dnssec @10.0.0.20 foo.fta.wf A every 5 s):

    A) direct recursion, no forwarders
    21:25:32 NSEC3=1 RRSIG_NSEC3=2 TTL=3600 <- Query log: Recursive
    21:25:37 NSEC3=4 RRSIG_NSEC3=0 TTL=3595 <- Query log: Cached
    ... (same for all following queries)

    B) forwarder Quad9 over TCP:
    first query NSEC3=1 / RRSIG_NSEC3=2,
    all following NSEC3=4 / RRSIG_NSEC3=0

    C) forwarder Quad9 over HTTPS: same result

    So the answer from upstream is complete, but every answer served from the cache has the NSEC3 duplicated 4x and its RRSIGs missing, independent of the upstream path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions