-
v0.0.2
StableGates / frontend (push) Successful in 1m18sGates / test (push) Successful in 2m27sGates / test-aarch64 (push) Successful in 5m39sGates / package (push) Successful in 3m34sGates / container (push) Successful in 13sCI / gates (push) Successful in 11m57sRelease / guard (push) Successful in 1m30sGates / frontend (push) Successful in 1m6sGates / test (push) Successful in 1m28sGates / test-aarch64 (push) Successful in 5m41sGates / package (push) Successful in 28sGates / container (push) Successful in 16sRelease / gates (push) Successful in 7m55sRelease / publish (push) Successful in 10m37sreleased this
2026-08-14 01:06:58 +00:00 | 85 commits to master since this releaseConfiguration can now be a file that every boot converges to, filtering gains regex rules and honors blocklist exception lines, and two refresh bugs that silently kept stale state are fixed. Note the three breaking changes below if you script against
nxdns importor run with--config.Added
- Declarative configuration for IaC.
nxdns run --config=<file>makes the file the sole source of configuration: every boot converges the database to it in one transaction, preserving blocklist downloads, compiled lists and client history, so an unchanged file costs zero downloads and zero writes. Barenxdns runkeeps the database (and the web UI) in charge, exactly as before. In file mode the web UI is read-only for configuration and says so; runtime actions (pause, blocklist refresh, certificate reload) stay live.GET /api/settingsreports which authority governs the process. nxdns importnow refuses a file whose application would delete configuration rows, names the tables and counts, and applies it only with the new--allow-deleteflag. Additive and edit-in-place imports need no flag.- Regex rules. Rules gain a third kind,
regex, besideexactandwildcard, for per-group allow and block patterns such as^ad[0-9]+-. The engine is homegrown and linear-time by construction, so no pattern can make matching blow up; backreferences and lookaround do not exist, and a bad pattern is refused at insert time with the limit it hit. Matches appear in/api/lookupand the query log asrule_allow_regex/rule_block_regex. Regex still comes only from you: regex lines in downloaded lists stay counted and skipped. - Blocklist exception lines are honored. An Adblock-Plus
@@||name^line in a downloaded list now lifts that name — and its subdomains — out of what the attached lists block. Exceptions sit below every rule you wrote: a downloaded list can reopen only a hole another downloaded list dug, never override an operator decision. Each source reports how many it carried. - Browser-only lines are counted where you can see them. Every source now reports how many of its lines nxdns skipped as syntax with no DNS meaning — cosmetic filters,
$-modifier rules — beside the existing skipped-regex count. Both blocklist tables show the number and the UI explains the difference: a list whose skipped-unsupported count dwarfs its domain count is written for browser extensions, and its DNS or hosts variant will block more. Previously such a list compiled to almost nothing and looked clean.
Changed
- Breaking:
nxdns run --config <file>changed meaning. It used to seed the database once and then ignore the file; it now makes the file the authority on every boot, which deletes any configuration the file does not declare — including edits made through the web UI since the seed. Before upgrading a unit that carries--config: either drop the flag to keep the database in charge, or adopt file mode with the sequence in the upgrade guide. Order matters there: export the file with the NEW binary (stopped). - Breaking: 0.0.1 exports are refused by this version. A 0.0.1
nxdns exportwrites both.password = ""and the stored.password_hash, and this version refuses a file that carries both. This bites any old export — an adoption file or a configuration backup fed tonxdns importalike. Fix an existing export by deleting its.password = ""line (keep the.password_hashline). Take fresh backups with the new binary. - Breaking: the offline password-change recipe changed. Setting
.password = "new"together with.password_hash = ""is now refused (emptypassword_hashis an explicit "disable authentication", and the two fields cannot both be present). To change the password in the file: set.passwordand delete the.password_hashline entirely. nxdns import --forceis renamed--allow-delete.- A fresh install no longer seeds from
/etc/nxdns/config.zonby presence. Usenxdns importonce, or run in file mode with--config. - The admin UI's internals moved to TypeScript 7 and replaced Tailwind with StyleX and React Aria. The visible change is small: selects are real widgets with working keyboard focus; everything else renders as before.
- The
config.dbschema is a single baseline definition again; numbered migration steps start accumulating at v0.1.
Fixed
- A list switching a name between its exact and wildcard forms never took effect. The compiled-list checksum hashed the exact and wildcard bodies as one unseparated byte stream, so a list carrying
a.exampleand the same list carrying*.a.exampleproduced the same digest, and the refresh kept the old compiled files. The checksum now separates the bodies. Every source recompiles once on its first refresh after the upgrade; no re-download of unchanged content is forced beyond the refresh's normal fetch. - A refresh could store stale skip counts. When a refresh found the list content unchanged, it wrote the previously stored skip counters back to the database while showing the fresh ones in the UI, and the next restart reverted the numbers to the stale copy. All counters now persist from the fresh compile.
- An Adblock-Plus entry with embedded whitespace (
||good.example bad.example^) compiled into an entry no query could ever match. Such lines are now counted as unsupported instead.
Downloads
- Declarative configuration for IaC.