ZoneMirror, open source
ZoneMirror: real-time DNS sync from cPanel to Cloudflare
An MIT-licensed cPanel and WHM plugin, multi-tenant, with per-user encrypted tokens and a systemd-supervised daemon. No cron.
- PHPStan static analysis
Level 8
PHPStan static analysis
- test methods green on PHP 8.2, 8.3 and 8.4
690
test methods green on PHP 8.2, 8.3 and 8.4
- licence
MIT
licence
The usual way to get DNS from cPanel into Cloudflare is a hand-rolled script run by cron: export the zone, transform it, post it. That works for one zone, one admin and one server, and breaks the moment several cPanel users need their own Cloudflare accounts, real-time propagation, or a safe rollback when the API rate-limits.
The approach
ZoneMirror replaces it with an event-driven plugin: cPanel Zone Editor changes fire the standard hooks, land in per-user SQLite queues, and a root systemd-supervised daemon drains them into the Cloudflare API, one zone snapshot per cycle, with per-server rate-limit budgets and a dry-run mode.
What it protects
Each cPanel user enrols their own zones with their own Cloudflare token, so one server can mirror N users by N zones.
Tokens are encrypted at rest with libsodium XChaCha20-Poly1305, with an AES-256-GCM fallback, and user-level hooks never read the root-only master key. A log redactor scrubs bearer headers and long identifiers from every line before it is written.
The diff engine protects what sync must not destroy: email authentication records, Cloudflare-only records on delegated zones, and ACME or DMARC entries that must never be proxied. Record locks with five scopes let individual records opt out of synchronisation.
How it ships
The repository is run like a production project: PHPStan level 8, 690 test methods in CI across three PHP versions, shellcheck and formatting gates, SemVer releases with SHA-256 verification, and a one-line installer that registers the hooks, starts the daemon and drops a CLI with self-update.
- php
- cpanel