Commit Graph
1 Commits
  • Add DNSMint DNS API (#7238)
    * Add DNSMint DNS API
    
    DNSMint mints hostnames on domains it operates and serves from its own
    authoritative nameservers, so a customer has no zone of their own and the
    challenge is published through its API.
    
    The hostname is derived server-side from the challenge name, so there is
    no root zone to detect and no record id to track: the value published is
    the value removed. Wildcards work because the API keeps the two newest
    values for a name, which is what the apex and wildcard pair needs.
    
    Tested against Let's Encrypt staging for a wildcard plus its apex.
    
    * Add DNSMint DNS API
    
    DNSMint mints hostnames on domains it operates and serves from its own
    authoritative nameservers, so records are published through its API
    rather than a zone you run.
    
    An ACME challenge goes to the DNS-01 endpoint, which derives the hostname
    from the challenge name: no root zone to detect, no record id to track,
    and the value published is the value removed. Wildcards work because the
    API keeps the two newest values for a name.
    
    Any other TXT name is an ordinary record under a hostname and goes to the
    records endpoint instead, which is why the add and rm functions branch on
    the _acme-challenge label. Issuing certificates needs only the dns01:write
    scope; the record endpoint needs hostnames:read and hostnames:write.
    
    Tested against Let's Encrypt staging for a wildcard plus its apex, and
    the non-challenge TXT path against the live API.
    
    * dnsmint: honour DNSMint_Api instead of overwriting it
    
    The assignment was unconditional, so exporting DNSMint_Api did nothing - the
    plugin reset it to the default every time it was sourced. Every neighbouring
    plugin with an _Api variable treats it as an override; this one only looked
    like it did.
    
    Found while writing the dnsapi2 entry: the sentence documenting the override
    would have been false.
    
    * dnsmint: format case blocks with shfmt -i 2
    
    * dnsmint: portable record lookup on removal
    
    grep -F is not on Solaris /usr/bin/grep, and "\n" in a sed replacement is a
    GNU extension that BSD sed writes as a literal n. The second is the one that
    loses data: without the split the whole reply stays on one line, so the match
    succeeds whatever the value is and the id taken is the first record under the
    hostname rather than the one holding the challenge. Removal then deletes
    somebody else's TXT record.
    
    Literal newline in the replacement, as dns_glesys.sh does it, and a case
    pattern per line with the case outside a command substitution.
    
    Docs and Issues now point at dnsapi2 and at the tracking issue upstream.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    
    * dnsmint: echo into sed, and keep _head_n 1 on the id
    
    Both from review on #7238.
    
    The reply arrives with no trailing newline, so printf "%s" hands sed an
    incomplete final line. Solaris /usr/bin/sed discards one, and here that line
    is the whole reply: the loop then sees nothing and every removal reports the
    record already gone, leaving the challenge TXT behind. echo, as lines 154 and
    172 of this file already do.
    
    _head_n 1 was dropped in 61ef816c. A record object carrying a nested id under
    "data" makes _rid two lines and the DELETE URL is then malformed.
    
    ---------
    
    Co-authored-by: kxbnb <hello@dnsmint.com>
    Co-authored-by: Claude Opus 5 <noreply@anthropic.com>