dnsclay: DNS UPDATE/AXFR/NOTIFY to many custom DNS operator APIs gateway
Dnsclay provides a standard DNS UPDATE/AXFR/NOTIFY interface for changing DNS records at your DNS operator that only provides API access through their custom web API.
Need for an API
When you register a domain name, the company you register it through typically sets up DNS hosting for the domain too (a “zone”). They often have a web interface where you can add/remove DNS records. For many people this is enough. They create some initial records and don’t touch DNS for a long time.
There are situations where you want an API to make DNS changes. For example for ACME DNS-based validiation, which is needed for certificates with wildcard names.
I am developing mox, a mail server, and I want to change DNS records for email. One of its goals is to make it easy to operate. A modern email setup requires quite a few DNS records.
The first feedback I received after the initial mox announcement was that adding all the DNS records through DNS operator web interfaces was cumbersome. Indeed those web interfaces are often not very helpful, making you add the records one by one. Only if you’re lucky you get the ability to import DNS records in (an underspecified subset of the) zone file format.
But it’s not just the initial setup that benefits from an API to change DNS records. More important are the key rollovers (DKIM, DANE host keys), policy changes (SPF, DMARC, TLSRPT, MTA-STS, CAA) and other configuration changes also require changes to DNS. With DNS caching and propagation delays, asking admins to make the DNS changes in lockstep with making other email configuration changes is very error prone. Letting software take care of it all prevents errors and is less work for admins. So I’m planning to implement that in mox. I just need an API to add/remove DNS records.
Good & bad news
The good news is that an API for making DNS changes exists: DNS UPDATE (RFC 2136). DNS servers like BIND or Knot support it and it’s easy to configure. If you’re using these, you may not need dnsclay!
The bad news is that most of the domain registrars/DNS operators don’t offer it. If they have an API at all, it’s typically a custom API they developed internally, based on HTTP/JSON.
Developers writing software that make DNS changes could all implement all those custom APIs in their software. This is indeed happening, for example with ACME clients. It’s a lot of work for developers. It will also add many dependencies to software projects because of SDKs of especially the larger cloud providers (their generic SDKs cover all their services).
I don’t want to implement all these custom APIs in mox. Ideally, I want to implement just one protocol in mox for making DNS changes. DNS UPDATE seemed to be the only candidate. A HTTP/JSON-based protocol would be more familiar to current developers, making it less work to use, but I don’t know of any, and I don’t want to invent yet another custom API. So DNS UPDATE it has to be.
DNS UPDATE, AXFR, NOTIFY, TSIG, TLS and SOA
Dnsclay translates incoming DNS UPDATE requests to calls to the various DNS operator web APIs. With DNS UPDATE, clients will send a DNS message that asks to add/remove certain records. The message can also specify prerequisites that must hold, such as the existence or absence of certain records. These prerequisites and changes are encoded in a standard DNS message. It’s not too complicated.
AXFR
Dnsclay also implements AXFR. AXFR is normally used by secondary DNS servers to synchronize DNS records in zones from the primary DNS server.
The AXFR interface in dnsclay allows clients (such as mox) to list all current records. Without AXFR, clients could discover records by making regular DNS requests. But going through a recursive resolver would introduce unwanted caching. Going straight to the authoritative name servers means clients would have to do DNSSEC verification, which isn’t trivial and would probably be skipped in practice. Then there are wildcard records that complicate matters. With AXFR, we get a list of actual records straight from the authoritative name server over a connection authenticated with TSIG and/or TLS.
Dnsclay implements authentication with TSIG and/or TLS with client authentication based on TLS public key (instead of certificate name/expiration/constraints). Dnsclay also implements “extended dns errors” for helpful error messages.
Tools like dig and nsupdate can be used for DNS AXFR/UPDATE with dnsclay, useful for testing.
NOTIFY
I expect clients like mox will want to stay up to date with any changes in the DNS zone. Configuration and DNS changes will be made by stepping through a state machine: Waiting for cached old records and cached negative lookups to expire before using a new key. Removing old records once they are no longer needed, e.g. old DKIM records expiration of any messages that may be in transit. DNS NOTIFY is the simple mechanism primary DNS servers use to tell secondary DNS servers they should initiate a zone transfer (AXFR or the incremental IXFR) to get the latest records. Dnsclay allows configuring addresses to send DNS NOTIFY messages to on changes. You probably won’t be surprised that all the custom cloud DNS operator APIs don’t have a mechanism for notifying about changes. So dnsclay polls periodically.
SOA and synchronizing
Changes in records can be detected by looking up the DNS record of type “SOA” for a zone. It includes a “serial”, which changes each time any record changes. The SOA record also contains a “refresh interval” which secondary DNS servers use schedule the next time they check for an update. Dnsclay does not use that refresh interval since it is intended for use between all DNS servers under control of the DNS operator. Instead, dnsclay will query the SOA record every hour, and initiate a full sync every 24 hours. After a change in the change is detected, the SOA record will be queried a bit more often for a while, speculating more changes may be coming. Dnsclay initiates a full sync because some DNS operators don’t follow the standards and don’t update the SOA serial at all. For example, SOA records at AWS Route53 always have serial 1. Dnsclay will always ensure a change in DNS records result in a new serial for a zone, keeping track of its own serial if needed.
When a DNS UPDATE or DNS AXFR comes in for a zone, dnsclay first syncs its local copy of the DNS records in from the DNS operator, ensuring it always responds with the current/latest records. It’s just the DNS NOTIFY messages that may be delayed a bit. But at least clients won’t have to poll for changes periodically if they configure the DNS NOTIFY mechanism in dnsclay.
Web interface
Zones are configured in dnsclay through the web interface. Adding a zone asks for a “provider” and its required input fields, often an API key. TSIG, TLS public keys and DNS NOTIFY addresses can be added/removed to a zone.
Dnsclay also has a web interface to add/remove/update DNS records, a side-effect of having a local synchronized copy of DNS records and the ability to add/remove/update DNS records.
The web interface is basic. Adding a zone:
And the editable record sets in a zone, and credentials and notify addresses (note the orange block, indicating the record set may not be fully propagated yet):
Dnsclay can show the history with propagation states over time:
“Providers”
Dnsclay currently has 59 “providers” at the time of writing, with implementations provided by the existing packages from https://github.com/libdns, which are community-maintained packages originally developed for Caddy for ACME DNS-based verification. Because I don’t have accounts at most of these providers, I can’t test them all.
These “providers” have methods for listing/adding/removing/updating records. DNS UPDATE has requirements that can’t be fully implemented with this interface, such as requests with both additions and deletions being processed atomically. I’m leaving it as a known implementation for now.
Questions
I have questions, perhaps you have some helpful insights. If so, please share them!
It seems the general idea of making automated DNS changes by software isn’t very common. Why is that? Is it just not needed often enough? I do think email is a relatively heavy user of DNS records. I know about https://www.domainconnect.org, but it seems aimed at hosted services that need a relatively basic set of preconfigured DNS records (templates), and mostly for one-time setup (the “async flow” for making automated changes without a user present apparently isn’t commonly implemented by DNS operators) and I don’t think it can list current records for a zone. Also, hosted services and DNS operators need to agree to work with each other, which doesn’t seem great for scaling. After a cursory look, I concluded domain connect won’t work for self-hosted software, since you either need to sign the DNS-changing payload with a secret key (we can’t distribute that!), or you have to redirect back to a preconfigured service domain (but you’re using your own domain, I don’t want to be involved in your self-hosted setup). I recently learned there may be workarounds (involving subdomains of a preconfigured service domain), but I’m not yet convinced that’s a good idea.
Or perhaps it is deemed too risky to have DNS-changing credentials on servers? If those credentials are compromised, attackers can do quite some damage. Would you (only) be comfortable if the configured credentials only have permission to preconfigured record names/types/TTLs or operations? Dnsclay doesn’t implement that yet, but it’s on the todo-list.
Why do DNS operators implement custom web APIs instead of DNS UPDATE? Perhaps because they have more services and they want to make DNS fit their API instead of the other way around? How do these DNS operators implement their web interfaces and custom APIs? I wouldn’t be surprised if they make DNS UPDATE requests to the DNS server software they run. It would be sad if dnsclay is converting DNS UPDATE requests to custom cloud API calls only for them to be translated back into DNS UPDATE requests…
Do you have a zone hosted at one of the supported providers? If so, please test it adding/removing/updating records works as expected.
All feedback/insights/questions are welcome, in comments here or elsewhere, or by email to mechiel@ueber.net. Dnsclay is open source software, MIT-licensed. See https://github.com/mjl-/dnsclay and https://pkg.go.dev/github.com/mjl-/dnsclay for details.