Skip to main content

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.

Why the queue is a comparison

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:

StateMeaning
PublishedThe backend has exactly what the row holds.
PublishingChanged within the last five minutes and not delivered yet. Normal.
Not publishedPending for more than five minutes. The state that means something is wrong: a lost trigger, a stopped worker or a refused value.
Never publishedWritten and never published, with no useful "since".
Not supportedThe 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.

FieldValue
MNAMEThe server's first DNS Server host.
RNAMEhostmaster.<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 TTL1800 s
NS TTL21600 s
Refresh, retry, expire86400, 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:

EveryWhatCommand for the same pass
5 minutesOffers 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.
MinuteRemoves expired temporary records (DNS Records).dns purge-expired-records
5 minutesResolves 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.