How DNS publication works
The server is an authoritative DNS server. Every zone on it is published to its own name servers, in the background, a few seconds after each change. The panel holds what a zone should say, the name servers hold what it does say, and the gap between the two is where DNS problems live.
The server's name servers
The elpan-dns package runs PowerDNS in a container. The panel knows it as
two DNS Server services on the server's own hosts, dns1.<server hostname> and dns2.<server hostname>, and every zone on the built-in
backend publishes those two as its NS records. The account holder gives the
same two names to their registrar; the Delegation tab in their
DNS Records
lists them, with the glue and DS records the parent zone needs.
A zone can be served elsewhere instead (DNS backends); everything below applies to all of them.
From a service to the name servers
Most records are not typed by anyone: a Website service publishes its A and AAAA records, a Mail service its MX, SPF, DKIM and DMARC, the zone its NS set. DNS is managed for you is the account holder's view of that. A change travels in four steps:
- Records. A service regenerates its records when it changes, and the account holder adds their own. Each record is one statement, kept with who made it, and never edited in place: an edit is a removal and a creation.
- Compilation. Everything at one owner name, whoever wrote it, is compiled into record sets: expired records drop out, several SPF records become the one a name may publish, one DMARC is selected, TTLs collapse to the smallest, and a suspended account's own records are marked suspended.
- The raw layer. The compiled record sets are stored with a signature of their content. This is the publication queue: a row whose signature differs from the one it was last published with is, by definition, not published yet.
- Delivery. A worker locks the zone, reads what the backend holds, and writes only what differs, then stamps the published signature back. A record set the backend already agrees with is never rewritten, so a converged zone is never re-signed and never costs a hosted backend its write quota.
Compilation and delivery run in the background workers, off a transactional outbox, so the request that changed a record returns at once and the name servers follow within seconds.
Nothing writes "pending" anywhere: the state is read from the two signatures the row carries, so a lost trigger, a worker that threw, or a message the transport gave up on all leave the same true statement.
What a record set's state means
The account holder sees a badge on a record only when there is something to say. The states, for a zone the panel publishes:
| State | Meaning |
|---|---|
| Published | The backend has exactly what the row holds. |
| Publishing | Changed within the last five minutes and not delivered yet. Normal. |
| Not published | Pending for more than five minutes. The state that means something is wrong: a lost trigger, a stopped worker or a refused value. |
| Never published | Written and never published, with no useful "since". |
| Not supported | The zone's backend cannot store this record type. Not a fault; the record is kept and published if the zone moves to a backend that takes the type. |
A zone on the Manual update backend, where a person makes the name servers agree, has states of its own (DNS backends). DNS Publication Failures is where the whole server's Not published rows and the backends' refusals are listed.
DNSSEC
Every zone is signed by default (DNSSEC Status on, denial of existence NSEC; NSEC3 is the alternative). The name server signs; the panel controls the setting and reads the DS records back from it after each zone change, since a zone that has just been told to sign has no DS records until it is signed.
The DS records are the one piece of DNSSEC state that has to leave the server: the account holder gives them to their registrar, and the Delegation tab reports whether the parent zone carries them.
The SOA
The panel owns the zone's SOA policy; the name server owns the serial. Nothing SOA-shaped goes through the pipeline, which is why a record change never touches the zone itself.
| Field | Value |
|---|---|
| MNAME | The server's first DNS Server host. |
| RNAME | hostmaster.<zone> |
| Minimum (negative caching) | 300 s, so that a name queried a moment before it is published, such as an ACME challenge, is not denied for hours. |
| SOA TTL | 1800 s |
| NS TTL | 21600 s |
| Refresh, retry, expire | 86400, 7200, 3600000; they matter only to a zone-transfer secondary, which is opt-in per zone. |
What repairs itself
Timers in the workers close the gaps the event path cannot see:
| Every | What | Command for the same pass |
|---|---|---|
| 5 minutes | Offers every outstanding record set to its backend again: up to 50 zones and 200 record sets per zone in a pass, zones the panel publishes first, nothing changed less than two minutes ago. On a manual zone, checks whether the person has entered it. | dns publish-pending |
| Hour (a slice; every zone once a day) | Recompiles a rotation of zones from their records, catching a compilation whose message was lost. | |
| Minute | Removes expired temporary records (DNS Records). | dns purge-expired-records |
| 5 minutes | Resolves SPF records that need flattening and refreshes the flattened ones. | dns spf-refresh |
| Hour (a slice; every zone once a day) | Asks the parent zone what it carries for the zone. |
dns republish is deliberately not on a timer: a converger that quietly
repaired everything every hour would hide the signal that the normal path
is broken.
The commands
elpanctl dns publish-pending
The five-minute pass, by hand. Bounded, so run it again for more, or use
dns republish for a whole zone.
elpanctl dns republish
elpanctl dns republish <zone>
elpanctl dns republish <zone> --dry-run
elpanctl dns republish <zone> --verify
Recompiles the raw layer of one zone or every zone from its records, hands each zone to its backend to be swept, and converges the zone-level settings (signing, denial of existence, transfer ACL, SOA policy). A zone that is already correct is left untouched. Run it after a deployment that rebuilds the raw layer, after the workers were stale, or when a zone is suspected out of step. A second run must report no changes; anything it keeps reporting is real drift. It is safe on suspended accounts, since the raw layer carries the suspension.
Ordinarily the comparison is through a marker the panel stamps into each
record set at the backend (for PowerDNS, the record set's comment), which
is blind to one thing: a record set somebody edited at the name server
behind the panel's back. --verify compares the records themselves and
repairs what it finds, at no more cost than an ordinary run.
elpanctl dns inspect <zone> <name> <type>
elpanctl dns inspect <zone> @ TXT
elpanctl dns inspect <zone> <name> <type> --mirror
One record set from both sides: what the records compile to, what the panel
holds, when it last changed and published it, what the name servers hold
and when they last took it, the marker, and whether the two are converged.
Use it when a record looks wrong and nothing is waiting in the publication
queue: that means the panel believes it has published, and this is the only
tool that asks the name servers. Records with no raw record set beneath
them are reported as an error, because nothing in the pipeline is waiting
for them; dns republish <zone> compiles them. --mirror asks this
server's own name servers about a zone that is served elsewhere
(DNS backends).
Zones that fall behind without any failure being recorded, as they do when the workers are stopped, are listed under Zones Behind on DNS Publication Failures.