Releases: danhorntx/dpanel
Release list
v2.0.1 — DNS zone round-trip fixes
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.
v2.0.0 — Security, Mail Deliverability, App Manager, Mobile
Major release. New security features, a complete mail deliverability stack,
in-panel database browser, Node/Python app manager, full backup restore,
comprehensive responsive design, and the refreshed user guide.
Added
Security
- Two-Factor Authentication (TOTP) — RFC 6238, works with any standard
authenticator app. New-IP login alerts. Disable requires current password. - API Keys — bearer tokens (
dpk_…) for external automation, with
adminandreadscopes. Audit-logged. SHA-256 hashed at rest. - Audit Log UI — searchable, filterable view of every state-changing
admin action. - Login attempt tracking — DB-backed brute-force lockout (5 fails / 15
min) on top of the existing rate limiter.
Mail & Deliverability
- Mail Health Probe — 11 deliverability checks (rDNS, HELO, MX,
SPF, DKIM, DMARC, MTA-STS, TLS-RPT, TLS cert, RBL listings on Spamhaus /
Barracuda / SpamCop / SORBS). Daily cron, alert on failure. - MTA-STS (RFC 8461) — policy file +
mta-sts.<domain>Apache vhost +
_mta-stsDNS record, auto-published per mail-enabled domain. - TLS-RPT (RFC 8460) —
_smtp._tls.<domain>TXT auto-published. - DMARC Aggregate Report Processor — IMAP fetch from a configured inbox,
parse XML (with.gz/.zip/ raw decoding), store in
dpanel_dmarc_reportskeyed by(org_name, report_id). - Per-domain IMAP TLS via Dovecot SNI —
local_nameblocks managed in
/etc/dovecot/conf.d/95-dpanel-sni.conf. ImapFlow client picks the right
cert based on the user's email domain. - Subdomain mail provisioning — mail-enabled subdomains write records
into the managed parent zone under prefixed names (mail.app,
_dmarc.app, etc.).
Apps & Databases
- Database Browser — phpMyAdmin-equivalent: paginated row view,
structure (columns / indexes / engine), free-form SQL runner, audit-
logged queries. - Node / Python App Manager — PM2-backed process management with
Apache reverse proxy, auto port allocation in 3000–3999, live logs,
Restart / Stop / Start / Destroy controls. - WordPress install via job queue — long-running install now async
with progress reporting.
System
- Domain Health Dashboard — per-domain aggregator: SSL, DNS, Mail
Health, backups, disk usage, PHP version, Apache error count. Surfaces
the worst status as the overall summary. - Backup Restore — restore files or databases from the UI with a
RESTOREtype-to-confirm guard, wipe-target / drop-recreate options.
Audit-logged. - File Manager — chmod, archive extract, bulk delete + move, image
preview. Permissions column inline editor; supports.zip,
.tar.gz,.tar.bz2,.tar. - Notifications — email alerts for SSL expiry (< 14 days), Mail
Health probe failures, backup failures, new-admin-IP logins. Dedup'd
for 24 hours. Logged todpanel_notifications. - Job Queue — in-process queue with progress + log per job, polled
via/api/jobs/:id. Currently powers WordPress install.
UX
- Responsive / Mobile — sidebar collapses to off-screen below 768px
with a hamburger toggle. Tables progressively hide low-priority
columns at 1100/900/820/700/640/560/480px breakpoints. Modals turn
into full-width bottom sheets on phones. Touch-target enlargement on
(pointer: coarse)devices. DB Browser sidebar collapses above main
pane on narrow screens. - Changelog modal — click the version pill in the sidebar.
- User Guide link in the sidebar footer.
Changed
- Atomic domain provisioning —
routes/domains.jsPOST flow replaced
with a 13-step reconciler inlib/state/domain.js. Each step has
check,apply, and a rollback closure. On partial failure, all prior
steps are rolled back in reverse. - Apache
deleteVhostnow also removes the certbot-generated
-le-ssl.conftwin. setupMailDnsnow writes MTA-STS / TLS-RPT records in addition to
the existing MX/SPF/DMARC; correctly handles subdomain provisioning by
walking up to the managed parent zone.dns.js SERVER_IP— previously hardcoded to the production IP;
now auto-detected viahostname -I, withDPANEL_SERVER_IPenv var
override.- WebSocket terminal session check — already used DB-backed sessions
cleanly; no functional change.
Fixed
- 🚨 Empty database backups (critical) —
lib/mysql.js dumpDatabase
invokedmysqldump ... \${name}` ...in a shell string, which the shell interpreted as command substitution.mysqldump` was running
with no database argument and producing 20-byte empty gzip streams.
Every database backup taken in production since the original release
was affected. - Webmail / autoconfig vhost collision — the autoconfig vhost
claimedwebmail.<domain>as aServerAlias, intercepting webmail
traffic and returning 403 (Apache picked whichever vhost loaded first
alphabetically). Fixed at the source + added a vhost collision guard
that refuses new vhosts whose hostnames overlap an existing one. - Webmail vhost ACME exemption — the
ProxyPass /directive
swallowed Let's Encrypt http-01 challenges, silently breaking cert
renewals. New webmail vhosts include anAlias+ProxyPass !
exemption for/.well-known/acme-challenge/. - Maildir literal-brace bug —
mkdir -p .../Maildir/{cur,new,tmp}
was creating a literal directory named{cur,new,tmp}because
execSyncruns through/bin/sh(dash), which doesn't brace-expand. - Missing npm dependencies —
helmet,dotenv,cookie,
cookie-signature,geoip-lite,isbotwererequire()'d but not
declared inpackage.json. Fresh installs crashed on boot. - Admin email reading deleted config.json —
getAdminEmail()
read fromconfig.json(renamed to.migratedafter the DB
migration), so Let's Encrypt registrations used theadmin@<newdomain>
fallback. Now reads fromdpanel_users.email. - Dovecot users file format — entries written with non-numeric UID
columns; newer Dovecot rejects. Fixed format + Dovecot config uses
override_fieldsfor backwards compatibility with legacy entries.
Security
- Disable-2FA endpoint requires the current password (anti-hijack).
- API keys never returned by list endpoint — only the prefix is stored.
- Bcrypt cost factor 12.
- Session cookies set
sameSite=strict,secure=true,httpOnly=true.
Migration notes
- New env vars:
DPANEL_SERVER_IP(recommended explicit set),
DPANEL_MAIL_HOSTNAME(optional override for Postfix HELO),
DMARC_INBOX_EMAIL/PASSWORD(DMARC processor, optional),
DPANEL_SEED_<PROVIDER>+_PASSWORD(seed list deliverability test,
optional). - Run
npm installafter pulling (new deps) andnpm install -g pm2
(required for the App Manager). - Existing webmail vhosts on production servers need an ACME exemption
patch — seePROD_MIGRATIONS.md. - Existing database backups created before this release are likely
empty; checkfind /opt/dpanel/backups -name "*_db_*.sql.gz" -size -100cand recreate any matches.