Repository navigation
Patch release. Every zone mutation in DPanel rewrites the whole zone file, so any record the parser could not represent faithfully was silently altered or dropped on the next unrelated edit. Three such cases are fixed, along with an .env load-order bug that could re-delegate a zone to the wrong nameservers.
No configuration change is required. Defaults are unchanged, so existing installs behave exactly as before.
Fixed
SRV records lost their trailing dot. parseZone stripped it from every non-TXT value, but renderZone restored it only for CNAME and MX. An SRV target sip.example.com. came back as sip.example.com, which BIND then resolves against $ORIGIN as sip.example.com.<zone>. The record survived its own creation and broke on the next edit to that zone — a delayed failure that does not point back at the edit that caused it.
Subdomain NS delegations were deleted. parseZone skipped all NS records as infrastructure, so an operator-added delegation (sub IN NS ns1.other.net.) vanished on the next zone write. Only apex NS records are skipped now.
The SOA serial could go backwards. YYYYMMDDNN has room for 99 revisions per day. The 100th produced an 11-digit serial that overflows the uint32 SOA field and failed the 10-digit reader, so the following write read it back as 0 and regressed — which stops zone transfers to secondaries. Every path is now guarded to return a strictly larger, in-range, 10-digit serial.
.env was not loaded by modules that read it at require time. lib/dns.js read DPANEL_NS1/DPANEL_NS2 into constants at import but relied on the requiring process having loaded dotenv. server.js does; a maintenance script or node -e one-liner does not, and would silently fall back to the built-in defaults — then re-stamp the zone's apex NS and SOA MNAME to the wrong nameservers on its first write. lib/imap.js and lib/analytics-mailer.js had the same shape with milder consequences.
Added
DPANEL_NS1/DPANEL_NS2— the vanity nameserver pair is no longer hard-coded, so a second host can advertise its own. Defaults unchanged.- NS re-stamp audit trail. The apex NS RRset and SOA MNAME are re-stamped on every zone write, so an unrelated record edit can silently re-delegate a zone once that pair changes. That behaviour is intentional, but now logs as
dns:ns-restampwith before/after values. - BIND reload failures are reported.
reloadBind()swallowed every error, leaving BIND serving stale data with no signal. It now logsdns:reload-failedand returns a status. It still does not throw — the zone on disk is already validated, and rolling back a good write over a transientrndchiccup is the worse failure.
Removed
panel.<domain>A record is no longer written into new zones. The panel is served only at each host's own hostname, so this stamped a record pointing at an unserved name into every zone.
Upgrading
The fixes are not retroactive — they preserve what is already on disk, so anything the old parser mangled stays mangled. After deploying, audit for pre-existing damage:
# SRV targets missing a trailing dot — being resolved against $ORIGIN
grep -H "IN[[:space:]]*SRV" /var/lib/bind/*.db | grep -v '\.$'
# Should be exactly 2 NS per zone unless a delegation legitimately exists
grep -c "IN[[:space:]]*NS" /var/lib/bind/*.dbSubdomain delegations already deleted by the old parser cannot be recovered from the zone files and must be re-added. See PROD_MIGRATIONS.md for the full checklist.