Reference/Changelog
v6.21.66
Reference

Changelog

A complete timeline of all NexoralDNS releases, from initial launch to the latest version. Most recent first.

v8.21.64-stable

LATESTAugust 1, 2026
NewThe core DNS server was rewritten in Go. UDP:53, TCP:53 and DoT:853 all behave as before — same 7-layer pipeline, same fail-safe bypass, same wildcard blocking, same circuit breakers, same upstream list
ImprovedMulti-core work no longer needs cluster.fork(). One process opens a UDP listener per 75% of CPU cores, all sharing port 53 via SO_REUSEPORT, and the kernel spreads datagrams across them. Every query is handled on its own goroutine
ImprovedA malformed packet can no longer take down the server. Each query is isolated, so a panic costs exactly one query instead of every listener in the process — the old cluster model dropped every in-flight query on the affected worker
ImprovedMeasured 12,746 queries/second at 3.8 ms average latency on a consumer laptop, with the load generator running on the same machine and zero dropped queries
FixedAnalytics were reaching MongoDB at roughly one record every two seconds while hundreds of thousands queued up behind them. Every consumer shared a single AMQP channel, and prefetch is a channel-level setting, so a consumer asking for 1 silently capped the analytics batch consumer that had asked for 1000. Each consumer now opens its own channel
FixedA consumer whose channel closed stopped receiving for good — reconnecting the connection did not help, because the consumer was still bound to the dead channel. Consumers now reattach automatically
FixedThe analytics batch job resolved its MongoDB collection once at startup. If the database was not up yet, that handle stayed empty for the process lifetime and every batch was requeued forever. It is now resolved per batch, with insert errors caught and reported
FixedA DNS answer built for a non-IPv4 value emitted a shorter rdata field than its own length header declared, producing a malformed packet. Such values now fall back to 0.0.0.0
ImprovedThe per-query log line moved from info to debug, and the per-publish broker log was removed. At production query rates those two lines were the single most expensive thing on the request path, since every write serialises through one lock. Set LOG_LEVEL=debug to bring the query log back
ImprovedThe service on/off check is remembered in memory for 5 seconds instead of hitting Redis on every single query. A policy change still takes effect immediately, because the broadcast clears the memo
ImprovedDNS-over-TLS certificates are generated in-process with crypto/x509 instead of shelling out to the openssl binary, and are written atomically through a uniquely-named temp file so a stale or pre-planted file can never leave the private key world-readable
ImprovedThe dependency graph is wired once at startup and checked by the compiler, replacing the string-keyed DI container — a mis-wired dependency is now a build error instead of a crash on the first query that needs it

v6.12.53-stable

July 6, 2026
ImprovedAll console.log/console.error replaced with pino async structured logging — synchronous I/O eliminated from every hot path, event loop no longer blocked by logging
ImprovedMongoDB timeouts configured (connectTimeoutMS: 5s, serverSelectionTimeoutMS: 5s, socketTimeoutMS: 30s) — stuck connections no longer accumulate under load
ImprovedFastify requestTimeout set to 30s — slow clients can no longer exhaust the worker pool
ImprovedRedis KEYS command replaced with SCAN cursor iteration — O(N) blocking Redis operation eliminated from cache invalidation
ImprovedDNS query processing now has a 5-second timeout guard — hanging DB/RabbitMQ calls no longer leave clients waiting indefinitely; SERVFAIL returned on timeout
NewPre-allocated dgram socket pool (256 sockets) for upstream DNS forwarding — eliminates create/destroy syscall overhead per query
FixedSocket listener collision in forwarder pool — per-query socket.on("message") listeners could cross-wire responses when multiple queries shared a socket; replaced with single permanent listener dispatching by DNS TXID
ImprovedUpstream DNS analytics publish moved off the response path — fire-and-forget, no longer awaits RabbitMQ before sending answer to client
NewCircuit breaker for each upstream DNS server — 5 failures in 30s opens the breaker; dead servers skipped in ~0ms instead of waiting 2s per attempt; auto-recovery probe after 30s cooldown
ImprovedUpstream DNS server status (breaker state + failure count) exposed in forwarder status endpoint

v6.11.53-stable

July 6, 2026
FixedA malformed or truncated DNS packet — e.g. a self-referential compression pointer — could spin a worker’s event loop forever, so a single crafted UDP datagram from any LAN client could take down DNS for everyone pinned to that worker; the parser now bounds every label walk and caps compression-pointer jumps
FixedAPI error responses were being sent with HTTP 200 (the real code appeared only in the JSON body) — failed logins, not-found, and conflicts now return their correct HTTP status, so browsers, proxies and the dashboard interpret them properly
FixedDNS record update and delete were scoped only by record id, letting one user modify or delete another user’s records by guessing the id; both now enforce domain ownership
FixedWildcard block rules over-matched — *.facebook.com also blocked notfacebook.com and evil-facebook.com; wildcard matching now respects label boundaries and blocks the domain plus its subdomains only
FixedUpstream responses with TTL 0 were cached permanently instead of not cached, defeating instant block/unblock toggling and serving stale records indefinitely
FixedThe DoT (DNS-over-TLS) certificate could be generated by several cluster workers at once and persist a mismatched cert/key pair; it is now generated once by the cluster primary before forking, with atomic writes
FixedThe IP-change watcher could write "nameserver 0.0.0.0" into /etc/resolv.conf on a transient interface blip and break host DNS; unreliable readings are now ignored and resolv.conf is written atomically (and it no longer corrupts the search directive)
FixedThe IP-change watcher’s Redis client permanently stopped reconnecting after 10 attempts, silently dropping all later IP-change events; it now retries indefinitely with capped backoff
FixedGranular DNS permissions were unusable — the list route required a delete permission and the delete route required a non-existent permission code; added the missing "View DNS Record" permission and corrected the route mappings so only Full Access no longer works
FixedAuthorization: Bearer <token> headers were not stripped of the scheme prefix before verification
FixedDNS record cache invalidation is now consistent across add/update/delete (keyed by record name) and awaited, so edits take effect reliably
ImprovedThe JWT signing secret is now a persisted random 256-bit key generated on first boot, replacing a low-entropy machine-derived secret — existing sessions are invalidated once on upgrade and users must sign in again
ImprovedDNS analytics publishing moved fully off the response path — a RabbitMQ outage no longer delays DNS answers, and broker reconnection runs in the background
ImprovedAccess-control lookups now use O(1) exact-match membership plus a small wildcard scan instead of scanning the entire blocklist on every query
ImprovedCache-admin key enumeration uses Redis SCAN instead of the blocking KEYS command
ImprovedMongo collection handles are resolved fresh per call, so a database reconnect no longer leaves services holding a dead client

v5.8.48-stable

July 4, 2026
NewAdded automatic CLI packaging (.deb and .tar.gz) for amd64, arm64, and i386 architectures, published automatically to GitHub Releases on push.
NewAdded self-updating CLI feature via nexoraldns pack command to fetch, download, and install latest package releases directly.
ImprovedSimplified CLI commands; after the first curl installation, users can manage all NexoralDNS services via direct nexoraldns start/stop/update/remove commands.
NewAdded automatic package registration to the installer, automatically downloading and installing the Debian package on initial deployment.
FixedCompletely uninstalls the CLI package and cleans up commands during the remove flow.

v5.8.47-stable

July 2, 2026
FixedUpstream DNS forwarding no longer shares one socket across concurrent queries — a burst of many simultaneous lookups (e.g. one page load) was silently dropping most of them; traced to socket contention (verified: 20 concurrent queries through one shared socket lost 19, while giving each its own socket lost none, repeatably)
ImprovedEach forwarded query now uses its own short-lived socket instead of a shared singleton, removing the transaction-ID rewriting and pending-request tracking the old design needed to disambiguate concurrent queries
NewConcurrent upstream forwards capped at 256 in-flight at once, queueing beyond that, so a large burst can no longer exhaust the process’s file descriptor limit
ImprovedUpstream DNS provider list trimmed from 14 servers to 6 (Cloudflare, Google, Quad9 unfiltered) — dropped Verisign, OpenDNS (applies its own filtering even on "standard" tier), and 4x legacy Level3/CenturyLink IPs of uncertain reliability; cuts worst-case forwarding time from 28s to 12s
NewGitHub Actions workflow now detects whether a push only touched Docs/Markdown/.github/.claude files and skips the Docker build entirely for those, with a build-summary annotation either way (image size, digest, layer count on real builds)
ImprovedDocs site version badge and install-command URLs are now server-rendered from GitHub’s live API (VERSION file, README.md) instead of hand-copied, cached 12h server-side and shared across all visitors

v5.7.46-stable

July 2, 2026
ImprovedMongoDB connection pool size now scales with CPU count instead of a flat driver default — floor of 20, ceiling of 50 per worker, targeting ~200 aggregate connections across the cluster
FixedUDP socket buffer resizing now runs only after the socket confirms it is bound; previously threw silently and never applied, including in the upstream DNS forwarder
NewDocker entrypoint raises the OS-level UDP buffer ceiling (net.core.rmem_max/wmem_max) at container start so the buffer resize above actually takes effect
FixedRabbitMQ queue declarations were being re-asserted on every publish/consume call; now memoized once per queue per process, fixing an argument mismatch between publisher and consumer declarations along the way
FixedRemoved a stray debug log firing on every cache-miss DNS lookup
ImprovedArchitecture documentation rewritten to match the current implementation

v4.7.46-stable

July 2, 2026
NewDNS query status handling now includes fail-safe options — queries keep resolving via cache or upstream even if MongoDB is temporarily unreachable
NewHealth check service reports MongoDB, Redis, and RabbitMQ status
ImprovedCron job execution integrated into cluster master and Fastify server startup
ImprovedRabbitMQ consumer batch size and timeout tuned for analytics processing
ImprovedMongoDB connection initialization cleaned up, index creation syntax improved
ImprovedDockerfile and ecosystem config updated for service management; MongoDB connection initialization added to cluster setup

v4.6.45-stable

July 2, 2026
NewLog export functionality with async processing and cleanup
NewAnti-AI Mode — domain filtering for AI tools, joining Anti-Porn and Anti-Ads modes
NewUser and role management routes and services (RBAC dashboard)
ImprovedPermission handling for domain and user management features

v3.6.45-stable

July 2, 2026
ImprovedDocs site rewritten, with a new achievements section on the homepage
ImprovedUI components refactored for styling and consistency; layout and responsiveness enhanced
RefactorRemoved unused TCP broker and event mapping code

v3.5.44-stable

June 20, 2026
NewDNS over TCP (port 53) — RFC 1035 §4.2.2 / RFC 7766; 2-byte length-prefix framing, 30s idle timeout
NewDNS over TLS / DoT (port 853) — RFC 7858; TLS 1.2+ enforced, self-signed cert auto-generated via openssl
NewIDNSIOHandler interface — unified IO contract so UDP, TCP and TLS share one 7-layer pipeline
ImprovedStartRulesService refactored to singleton per transport with shared single-flight inflight map
ImprovedStatic Redis subscription guard prevents duplicate cache:invalidate listeners in cluster mode
ImprovedTLS cert persisted to /etc/nexoral/cert — shared across restarts and cluster workers
ImprovedAuthentication — removed Authorization header requirement from DNS and Domains routes
ImprovedSession management — auto-expiration for inactive sessions, rotating refresh tokens
ImprovedRedis caching for session management
ImprovedBroker service removed from ecosystem (consolidated into main server)

v3.4.43-stable

March 15, 2026
ImprovedAdded comprehensive documentation and project guidelines
ImprovedCleaned up model configuration in settings.json

v3.4.42-stable

February 16, 2026
NewAnti-Porn and Anti-Ads block modes with curated domain lists
NewBlockDeviceModal — block devices by domain-based policies
ImprovedRedis cache invalidation for ACL and service status updates
ImprovedBlockList service refactored for stateless operation

v3.3.38-stable

January 4, 2026
NewWildcard domain support in Access Control (e.g. *.ads.com)
NewCron job to load Access Control policies into Redis on startup
NewIP Groups and Policies management in the dashboard
ImprovedACL caching with new Redis keys for blocked domains
ImprovedBlockList service — checkDomain method with domain logging
ImprovedPagination changed to cursor-based approach for query logs
FixedReduced global cache TTL from 5s to 3s for improved freshness

v3.3.37-stable

January 1, 2026
NewChange password functionality with validation modal
NewLogout confirmation modal with localStorage cleanup
NewMongoDB auto-delete index for Analytics collection (TTL)
FixedpasswordUpdatedAt timestamp issue in User collection
ImprovedAuth store enhanced with passwordUpdatedAt tracking

v1.2.7-stable

October 2, 2025
NewConnected Devices page — view all active devices on the LAN
NewDomain management — DomainCard, DomainModal, RecordModal components
NewDHCP controller for fetching connected IPs and network info
ImprovedDatabase configuration includes default RBAC roles
ImprovedAuthentication middleware added with JWT guard on all routes

v1.1.5-stable

September 30, 2025
NewInstall script — start, stop, and update commands added
NewComplete uninstall / remove flow via install.sh
ImprovedCluster mode with PM2 — multi-core DNS processing
ImprovedDocker Compose v2 configuration and optimized build
FixedAuth controller refactored to use BuildResponse for consistent errors

v1.0.0

INITIALSeptember 24, 2025
NewCore DNS server with Redis caching (7-layer query pipeline)
NewWeb dashboard — Next.js + React management interface
NewSupport for A, AAAA and CNAME records
NewDomain blocking with exact-match and wildcard rules
NewGitHub Actions workflow for Docker image build and push
NewMongoDB with RBAC — role-based access control from day one
ℹ️
Stay updated
Watch releases on GitHub at github.com/nexoral/NexoralDNS/releases.