Hello fellow Go programmers!
I have created a new DNS provider module for Caddy.
It’s quite different from the other DNS providers because it does not use any API, instead it simply makes Caddy serve the challenge records itself.
To get this to work, only one additional DNS record (NS
record for _acme-challenge
) is required.
I’ve tested it against Caddy’s own embedded ACME CA and Let’s Encrypt staging (and it works), but it’s not production ready yet.
There are a few reasons for this:
- I’m not actually a Go programmer (this is the first thing I’ve written in it)
- It relies on deprecated & undocumented Caddy behavior (forgive me)
- It’s only been tested manually so far
-
dns_challenge_override_domain
/override_domain
isn’t supported, and neither is theacme_dns
Caddyfile global option
I’d be happy if you guys could take a look at it and give me feedback, especially about whether I’m using Go right.
I’d also like to know whether the caddy.Replacer
stuff in Provision()
makes any sense at all (to be honest, I just copied that from another DNS provider module and don’t really know what it does).
If anyone has a lot of experience with DNS, I’m also curious about the error codes I’ve chosen to return for the various cases (in the make_handler()
function): is it okay to reply REFUSED
to all non-TXT
requests?
Realistically, this handler will only be running for a second or so, while the challenge is being completed, but it should still be correct (and in my testing I also saw the LE staging CA query for CAA records
).
Finally, there’s the issue with implementing acmez.Solver
instead of certmagic.ACMEDNSProvider
with the libdns
interfaces.
I chose to do this because I think the acmez.Solver
interface fits a lot better, “semantically”, for what this module provides. In practical terms, it would probably work just as well to launch the server thread and do the Present()
stuff in AppendRecords()
and then do the CleanUp()
in DeleteRecords()
… but to me that seemed worse than disregarding the deprecation.
I suppose if framed as “this is a server that runs as long as it has records to serve”, it could make sense as a libdns
-style provider, too.
If nothing else works out, this could always be implemented as a certmagic.Issuer
under tls.issuance
instead of dns.providers
, but that would involve copying almost all of the code from the tls.issuance.acme
issuer.
Since even the libdns
interfaces are still experimental / WIP I thought it’d be best to just do it like this for now and find out whether this is even useful or practical at all.
Ok, here’s the link (but remember: not production ready):
I’m curious to see what you think!
Regards,
xaos