DNS hosting (dnso.city)
dnso.city hosts the DNS for customers' domains: they keep their zones and records on Zappocity, and dnso.city's name servers answer for them. It was built in seven steps (docs/plans/dnso.md): zones and records on the account page and over the API, the name servers (the dns service) with DNSSEC, secondary DNS both ways, the delegation check, Mailocity teams' domains published there by automatic DNS, and billing. It is coming in the catalog until you make it available under Products: do that once dnso.city's name servers are set and two or more name servers are answering.
Plans
| Plan | Price a month (billed yearly; monthly 20% more) | Zones | Records per zone |
|---|---|---|---|
| Free | $0 | 3 | 100 |
| Personal | $3 | 25 | 500 |
| Business | $9 | 100 | 2,000 |
| Agency | $29 | 500 | 5,000 |
Every plan has DNSSEC; Personal and up add the API and secondary DNS, Business zone import and team access, Agency priority support and your own name servers. Queries are not counted (fair use: a zone that draws abusive traffic is rate limited). A Mailocity team's own domains are free on dnso.city. Prices, limits and features are changed under Products → dnso.city like any product's (limits: zones, recordsPerZone).
Billing: a DNS account starts on Free, renewed monthly without an invoice. On the organization's subscription on the account page, owners and billing members choose the plan and Monthly or Yearly. A dearer plan is invoiced at once for what is left of the current period (the difference in price, in proportion); a yearly or monthly period starts at the next renewal, which invoices the new period at its price; a cheaper plan takes effect without a refund. A plan the account does not fit (more zones, or more records in a zone) is refused.
For customers
On the account page, DNS hosting → Start a DNS account makes an organization they own on the Free plan (once dnso.city is available; up to three each). Then:
- Add the zone: a domain such as
example.com. A domain is served for one account only; if someone else added yours, support moves it. - Records: name (
@for the domain itself,www,*for a wildcard), type, TTL and data, written as DNS writes them:192.0.2.1;10 mail.example.com.for MX; any text for TXT (split for DNS as needed);0 issue "letsencrypt.org"for CAA.- A name with a CNAME has nothing else, and the domain itself cannot be a CNAME: use ALIAS there, which answers with the addresses of the host it names.
- NS records delegate a name below the domain; the domain's own name servers are dnso.city's.
- PTR records (a host name, such as
mail.example.com.) are for reverse zones, such as2.0.192.in-addr.arpa, delegated to dnso.city by whoever holds the addresses. - Each change raises the zone's serial.
- Delegation, on the zone's page: dnso.city asks the domain's parent (the registry, such as
com) directly whether it names dnso.city's name servers for the domain (delegated), some of them (partly), others (elsewhere: set the name servers at the registrar), or has no such domain (unregistered); and whether its DS record is the zone's (on), another key's (mismatch: resolvers that check DNSSEC fail until it is replaced at the registrar) or missing (off). The answer is kept a minute; Check again asks again after that. Over the API:GET .../zones/{zoneId}/delegation;corpsuite dns zone delegation. - Remove the zone, at the bottom of the zone's page: dnso.city stops serving the domain and its records here are deleted (a provider the zone is linked to keeps its copy). Move the domain's name servers away first if they are dnso.city's. Over the API:
DELETE .../zones/{zoneId};corpsuite dns zone remove. - A canceled DNS account (its subscription canceled) is kept, with its zones not served and not changeable, so support can bring it back; it says canceled on the account page, and one without zones is no longer listed.
- The organization's owners change its zones; other members read them. Owners change the plan on the organization's subscription there (a plan the account does not fit, with more zones or records than it allows, is refused).
The name servers
A name server (corpsuited with the dns service) answers for every zone of an active DNS account, authoritatively, over UDP and TCP, and refuses everything else (it never looks names up for others). It reads the zones from the platform every 30 seconds, fetching only those whose serial moved, and keeps them on disk: when the platform is down, it goes on answering with what it has.
- Publish the
_zappocitydiscovery record so the name servers find the platform. - On each name server, set
CORPSUITE_SERVICES=dns(addmx-backupfor a secondary that also takes mail), itsCORPSUITE_HOSTNAME(such asns1.dnso.city) andCORPSUITE_ACME_EMAIL, and runsudo corpsuite join; it finds the platform from the_zappocityrecord. Approve it under Settings → Servers in the admin panel. Optional:CORPSUITE_DNS_ADDR(:53),CORPSUITE_DNS_DIR(the zones it keeps) andCORPSUITE_DNS_RATE(answers a second per client network over UDP, 200). NOTIFY goes only to addresses on the internet (private ones too in dev mode). - The approved name servers that answer become dnso.city's name servers (Settings → DNS hosting, also
corpsuite dns settings): every zone's NS records, the first in its SOA. One that stops answering is taken out until it is back. They read the zones over the peer API and pass on NOTIFY from a secondary zone's own primary the same way; the platform's DNS secondaries job (every minute) transfers secondary zones. - Give the name servers' addresses to the registry as glue for the name servers' own domain.
What it answers: the records as kept; CNAME chains within the zone; wildcards (*) for names that do not exist below them; referrals with glue for names delegated with NS records; ALIAS at a zone's apex as its target's current addresses (looked up at most once a minute); SOA and the apex NS from the settings; NXDOMAIN or no data with the SOA (its minimum TTL, 5 minutes); ANY with the short answer of RFC 8482.
DNSSEC
Every zone is signed. It gets a key of its own when it is added (one ECDSA P-256 key, algorithm 13, both for the zone's keys and its records); the private part is kept sealed with the platform's key file and handed to the name servers with the zone. They sign its answers as it makes them, for resolvers that ask for DNSSEC, so names answered from a wildcard or an ALIAS are signed too. It proves a name or type absent with a compact denial (RFC 9824: an NSEC at the name asked, listing what it has or NXNAME), which cannot be walked to list the zone's names.
DNSSEC is on for a domain once its registrar publishes the zone's DS record, which the zone's page on the account page shows (and the zone API as dnssec.ds). Without it, resolvers use the answers unsigned.
A zone linked to another provider (below) is answered by that provider's name servers, not dnso.city's, so its DS record is not shown: turn DNSSEC on at the provider, which signs the zone there.
A DS record can also be added below the zone's apex, beside the NS records that delegate a name to other name servers, to carry DNSSEC down to them.
Linked providers: name servers kept elsewhere
A domain's name servers can stay at another DNS provider (Route53, Cloudflare, DigitalOcean, Gandi, GoDaddy, Hetzner, Linode, Namecheap, OVHcloud, Porkbun, Spaceship or Vultr) while its records are kept on dnso.city. Link the zone to the provider and dnso.city pushes every change there through the provider's API, a few seconds after it is made and once an hour in any case. Everything that changes records through dnso.city (the zone's page, the API, automatic DNS, the command line) then reaches the provider's name servers.
On the zone's page, under Linked provider, choose the provider, give the API credentials it asks for (each provider's are described on the form, as for automatic DNS) and a mode:
- Authoritative (the default): the provider's copy of the zone is made the same as dnso.city's. Records added at the provider are removed at the next push.
- Managed: only the record sets dnso.city keeps are changed at the provider. Others are left alone and listed on the zone's page as left alone; Keep here copies one into dnso.city, which manages it from then on.
Before the first push, the provider's records that dnso.city lacks are copied in (untick First copy the provider's records to skip this), so linking an authoritative zone takes nothing away. dnso.city never changes the provider's SOA or the NS records at the zone's apex, nor record types it does not keep; ALIAS records stay on dnso.city only.
The credentials are tried by reading the zone before they are kept. Their secret parts are sealed and never shown again; saving the link again with them left out keeps them. The zone's page shows whether the last push worked, with Push now to push at once. Unlink stops the pushes and leaves the provider's records as they are. Only a primary zone can be linked, by the account's owners.
While a zone is linked, its Delegation check expects the registry to name the provider's name servers ("Amazon Route53 answers for the domain") and a DS record of the provider's key, if any: turn DNSSEC on at the provider. It warns when the registry names dnso.city's name servers instead, as the linked copy is then not the one used. Route53's wildcard names (which it writes as \052) are the same * names here.
The API: GET, PUT and DELETE /api/account/dns/{accountId}/zones/{zoneId}/push on the account API, with POST …/push/run and POST …/push/adopt ({"sets": ["www A"]}, or none for all).
Secondary DNS: transfers to other name servers
On plans with secondary DNS (Personal and up), a zone can also be served by name servers elsewhere, as secondaries of dnso.city. On the zone's page, under Secondary DNS, list their IP addresses (up to 10, on the internet) and save:
- The first time, the zone gets a TSIG key, named
xfr.and the domain (xfr.example.com.), HMAC-SHA256. Its secret shows this once: set the key on the other name servers. Make a new key replaces it (the old one stops within a minute) and shows the new secret once. - The name servers transfer the zone (AXFR; an IXFR gets the whole zone too) over TCP, only to a listed address and only when the request is signed with the zone's key. Anything else is refused.
- When the zone changes, they send the addresses a NOTIFY, signed with the key, so they fetch it at once.
- An empty list stops transfers. A plan without secondary DNS stops them too (the list is kept for when it returns).
What goes out: the SOA, dnso.city's NS records, and every record, except ALIAS (it has no record of its own; the secondaries cannot answer it). The zone goes out unsigned: the name servers sign as they answer, so a secondary has no signatures to give. While the domain's registrar has the zone's DS record, resolvers that check DNSSEC fail on the secondaries' answers; use secondaries elsewhere only for zones without the DS record, or keep to dnso.city's own name servers.
On a secondary such as BIND:
key "xfr.example.com." { algorithm hmac-sha256; secret "the secret"; };
zone "example.com" { type secondary; primaries { 198.51.100.53 key "xfr.example.com."; }; };
with dnso.city's name servers' addresses as the primaries.
Secondary DNS: dnso.city as the secondary of zones kept elsewhere
On plans with secondary DNS, a zone whose records are kept on name servers elsewhere (the primaries) can be served by dnso.city too. On the account page, under the DNS account, Or serve a domain as a secondary of name servers elsewhere: the domain, the primaries' IP addresses (up to 10, on the internet, asked on port 53), and the TSIG key they sign transfers with, if any (name, HMAC-SHA256, -384 or -512, and its secret, kept sealed and never shown again).
- The platform asks the primaries for the zone's SOA and, when its serial moved, transfers the zone (AXFR over TCP). It does so on the schedule the SOA sets (refresh, between 5 minutes and a day; retry after a failure), within a minute of a primary sending NOTIFY to dnso.city's name servers (from a primary's own address only), and at once with Check now.
- The zone is served once first transferred, as the primaries give it: their SOA and NS, and every record type. Its records are read on the zone's page, not changed there. When the primaries have not answered for the SOA's expire time, it stops being served.
- What went wrong with the last check (a primary not answering, a wrong key, more records than the plan allows) shows on the zone's page; the zone as last transferred goes on being served meanwhile.
- A zone signed at its primary (with DNSKEY, RRSIG or NSEC records) is not taken yet: dnso.city would serve it without the signatures it needs.
- At the primary, allow transfers to dnso.city's name servers' and the platform's addresses, send NOTIFY to dnso.city's name servers, and add dnso.city's name servers to the zone's NS records (and at the registrar) for them to be asked.
Mailocity teams' domains
A Mailocity team's own domains are free on dnso.city: under Automatic DNS on a domain's page, a team publishes at dnso.city instead of Route53 (see automatic DNS). The zone is made in a DNS account of the team's organization on the Mailocity domains plan (any number of zones, 200 records each, DNSSEC; not sold, and not listed for sale). Its owners manage it like any other zone; the mail records are kept right by automatic DNS every hour.
When our addresses change
If the service's own addresses move (for example, its outgoing mail servers move to new IP addresses), records in your zones that name an old address exactly (an A or AAAA record, or an ip4:/ip6: term in your SPF record) are changed for you: first the new address is added beside the old, then, once the old one is retired, it replaces it. Nothing else in your zone changes, an address block you listed (such as ip4:203.0.113.16/28) is left as it is, and zones kept elsewhere (dnso.city as their secondary) are never changed. Each change is in the account's history.
For staff
A dnso.city subscription's resource is its DNS account. Staff manage every account, its zones and records on the DNS page of the admin panel, at /v1/platform/dns/accounts/{accountId}/zones (api/platform.yaml) and on the command line: corpsuite dns zones ACCOUNT-ID, dns zone add, dns zone, dns zone remove, dns record add, dns record set, dns record remove, dns zone transfers set, dns zone transfers new-key, dns zone primaries set, dns zone refresh, dns zone delegation, dns zone push, dns zone link, dns zone unlink, dns zone push now, dns zone adopt, and dns readdress when the platform's addresses move.