Mostly fixes for Linux home networks and IPv6 upstreams, a tighter dashboard auth check, and an easier way to find the dashboard token.
⚠️ Check before upgrading
Loopback requests now need the token unless Host is local. A page that DNS-rebinds its domain to 127.0.0.1 could previously read the query log and add overrides without a token. The loopback exemption now only applies when Host is localhost, *.localhost, an IP literal or a .numa name. If you front the dashboard with a same-host reverse proxy that passes the original Host through (Caddy and Traefik do by default), it will get a 401: send the token upstream or rewrite Host to the upstream address. Opening the dashboard as http://<hostname>:5380 now asks for the token too. (#420)
🏠 Linux home networks
- Search domains from resolv.conf (
lan,fritz.box) forward to the system resolver instead of a hardcoded AWS VPC address that returned SERVFAIL everywhere else. Thanks @hb9eue (#414, #415) - Without systemd-resolved (Raspberry Pi OS, minimal Debian), the resolv.conf backup moves to
/var/lib/numaso the unprivileged service can read it; existing backups migrate automatically (#418)
🌐 IPv6 upstreams
Plain-UDP IPv6 upstreams never worked, in forward or recursive mode, because the socket was always bound to 0.0.0.0. They do now. (#417)
📦 Smaller responses
Repeated names are written as compression pointers, so an 8-record answer fits in 512 bytes again instead of coming back truncated. Thanks @Guara92 (#404, #405)
🔑 numa token
Prints the dashboard token the way the daemon resolves it, with where it came from. numa install also shows the token path. With Docker: docker exec numa numa token. Thanks @robogeek for the nudge (#408, #412, #416)
🩺 numa service status shows the OS resolver
It now prints the nameserver the OS actually uses, so a Numa that silently stopped being the system resolver is visible. (#406)
Also notable
- A taken API port (Technitium defaults to 5380) no longer takes the dashboard down silently: DNS keeps serving and the API retries every 5 s (#411, #423)
- The ODoH relay caps target responses while streaming instead of after buffering the whole body (#419)
- README: running Numa as primary DNS, network-wide setup recipe, ODoH threat model and service privileges (#401-#403, #409, #410)
All changes
What's Changed
- docs: name the auto-mode DoH fallback and document relay logging and limits by @razvandimescu in #401
- docs: list per-client rules in the comparison table by @razvandimescu in #402
- docs: state the ODoH threat model, service privileges and AI use in the README by @razvandimescu in #403
- fix(buffer): write repeated names as compression pointers by @razvandimescu in #405
- fix(make): retry the deploy probe instead of one dig after one second by @razvandimescu in #407
- feat(status): report whether the OS resolver points at numa by @razvandimescu in #406
- docs(readme): add a section on running Numa as primary DNS by @razvandimescu in #410
- fix(install): show where the API token lives by @razvandimescu in #408
- docs(recipes): add network-wide setup by @razvandimescu in #409
- feat(cli): add numa token by @razvandimescu in #412
- fix(serve): fail startup when the API port is taken instead of panicking in a task by @razvandimescu in #411
- fix(system_dns): forward Linux search domains to the system resolver by @razvandimescu in #415
- fix(forward): bind UDP upstream sockets in the upstream's address family by @razvandimescu in #417
- fix(system_dns): keep the Linux resolv.conf backup where the daemon can read it by @razvandimescu in #418
- fix(relay): enforce target response cap while streaming by @razvandimescu in #419
- fix(api): require the token for loopback requests with a foreign Host by @razvandimescu in #420
- test(integration): use a blocked-domain fixture the default list still carries by @razvandimescu in #422
- fix(serve): keep serving DNS when the API port is taken by @razvandimescu in #423
Full Changelog: v0.23.1...v0.24.0