github razvandimescu/numa v0.25.1

42 minutes ago

This release keeps forward mode answering when an upstream refuses or goes quiet, ahead of Quad9 leaving France on 24 November. It also tightens DNSSEC denial checks in recursive mode, halves DoT upstream latency, and fixes .local names on Linux and the query log on narrow screens.

⚠️ Check before upgrading

Upstreams are asked in list order. Forward mode used to sort upstreams by a score that only moved on bad answers, so one slow answer could move all traffic for good. Now the first listed upstream gets the queries until it fails. Put the one you prefer first. srtt = false under [upstream] keeps plain list order without the failover. (#495)

A REFUSED goes to the next upstream. An upstream that blocks with REFUSED (AdGuard Home in refused mode) listed before an unfiltered one no longer blocks, because the name goes to the next upstream. A server that refuses most names by design, listed before a public one, ends up marked failed; give it a [[forwarding]] rule instead. With ODoH and strict = false, a REFUSED from the target now goes to the fallback. (#496)

🔁 Upstream failover

With the built-in Quad9 + Cloudflare pair, Numa keeps resolving whether Quad9 refuses French users or stops answering them.

  • A timeout or an error marks an upstream as failed. It is asked last until it answers again. (#495)
  • About 1 in 20 forwarded queries also goes to a failed upstream listed earlier, in the background, so traffic returns when it recovers. (#495)
  • A REFUSED is retried on the next upstream. If every upstream refuses, the client gets the first REFUSED. (#496)
  • DoH upstreams follow list order and failover too. Before, they always went first and a dead one cost the full timeout on every cache miss. (#495)
  • The DoH keepalive follows the upstream in use after a failover, so its connection stays warm. (#497)
  • A DoH upstream that sends headers and then stalls no longer holds the query, and DoH and ODoH reply bodies are size-capped. (#481)

⚡ DoT upstreams

  • DoT queries set TCP_NODELAY. A new connection to Cloudflare went from 108 ms to 49 ms, Quad9 from 105 to 52. (#498)
  • DoT connections are reused for 10 s, so queries in a burst skip the TCP and TLS setup (about 15 ms instead of 50 on Cloudflare and Quad9). (#499)

🔒 DNSSEC

Recursive mode with DNSSEC on checks NSEC and NSEC3 denial proofs more strictly. Upgrade if you use it.

  • A denial counts only when the zone that holds the name signed it, and a DS denial only when the parent zone signed it. (#502)
  • A record at a zone cut or a DNAME no longer proves anything about names below it, and proves NODATA only for DS. (#503)
  • The NSEC check grows linearly with the number of records in the answer. (#504)

🏠 .local on Linux

  • A router that hands out local as the DHCP domain no longer makes every mDNS name wait 5 s for a SERVFAIL. Numa skips the search local entry, as it already did on macOS. A [[forwarding]] rule with suffix = "local" still applies. (#485)
  • A proxy TLD under a special-use name, such as tld = "local" or tld = "corp.local", answers its services without a forwarding rule. (#486)

📊 Dashboard

  • Sidebar panels collapse when you click their header, and stay that way. (#482)
  • Recent Queries shows on windows narrower than 1100 px, and its filters wrap on phones. Thanks @bcookatpcsd (#487, #488, #489)

Also notable

  • numa dnssec on (and lan, block) no longer turns a line with a trailing space into eenabled = true. (#479)
  • README first-run commands work as written. The Windows network-wide recipe lists the exact firewall rules. (#413, #484)
  • Dependency updates. (#491)
All changes

What's Changed

  • fix(cli): keep the key intact when a toggled line has trailing whitespace by @razvandimescu in #479
  • fix(release): refuse when main is out of sync, push main + tag atomically by @razvandimescu in #480
  • feat(dashboard): collapsible sidebar panels by @razvandimescu in #482
  • docs(readme): fix first-run commands, correct the comparison, trim by @razvandimescu in #484
  • fix(ctx): answer the proxy tld before the special-use check by @razvandimescu in #486
  • fix(system_dns): don't turn the local search domain into a forwarding rule on linux by @razvandimescu in #485
  • fix(dashboard): show the query log when the layout stacks to one column by @razvandimescu in #488
  • fix(dashboard): wrap the query log filters on phones by @razvandimescu in #489
  • chore(deps): bump the minor-and-patch group with 9 updates by @dependabot[bot] in #491
  • fix(forward): bound DoH and ODoH response bodies by time and size by @razvandimescu in #481
  • docs(recipes): add tested Windows firewall steps to network-wide setup by @razvandimescu in #413
  • fix(forward): ask upstreams in list order and re-test failed ones by @razvandimescu in #495
  • fix(forward): keep the upstream in use warm after a failover by @razvandimescu in #497
  • fix(forward): try the next upstream when one answers REFUSED by @razvandimescu in #496
  • perf(forward): set TCP_NODELAY on DoT upstream connections by @razvandimescu in #498
  • perf(forward): reuse DoT upstream connections by @razvandimescu in #499
  • fix(dnssec): check denial proofs against the zone that holds the name by @razvandimescu in #502
  • fix(dnssec): handle zone cuts and DNAMEs in denial proofs by @razvandimescu in #503
  • perf(dnssec): look up each NSEC wildcard once per closest encloser by @razvandimescu in #504

Full Changelog: v0.25.0...v0.25.1

Don't miss a new numa release

NewReleases is sending notifications on new releases.