Certbot preferred challenge methods http to dns. How to use static CNAME delegation for DNS

Hi everyone, like everyone who was using Sectigo/Incommon for certs we got all caught up in
the Certinext conversion. Our leadership decided to not go that route and contracted with
Sectigo directly. Yesterday was my first try and using the usual "certbot certonly" command
that I used in the past. I have to change the fields for the server, key, hmac id. To my
surprise it hung on me with no reason why. I eventually add "-v" and saw the "http-01" message
challenge. This is something we never had to deal with using Incommon. Turns out that is the
default and uses port 80 which needs to be open. I checked our systems and we have lots of our
systems listening on that port which will be a problem. Talking with another team member we
saw the option to use dns-01.

Now with dns-01 this confuses me. There is all of this txt file creations, and tokens which
are used. Seems like a ton of detail which I am struggling to understand. I came across this
another option "Static CNAME Delegation (Direct to ACME or SCM)". Instead of giving win-acme
continuous access to write DNS records, the DNS team sets up a one-time, static CNAME record.
When Sectigo queries _acme-challenge..colostate.edu during dynamic DNS-01 checks,
the public DNS server redirects Sectigo to follow the CNAME target. This allows Sectigo to
read the validation token without touching your central DNS zones. This option seems like a
great idea to me if it would work.

We are running Oracle Linux 8. The certbot we installed from the yum epel repo last year.
This has been working great. I later found out version 1.22 is old but it was working great
for us before all the certinext things came up. Before I go upgrading anything I want to be
sure I need to do that for what we need to do. I did try using the option
"--preferred-challenges dns" with the "manual" option. It prompted me to create a DNS
record with the has value. I didn't do this.

It seems to me using the validation method of "dns-01" you have a few ways of handling this.
One with the tokens and a lot of work managing them. The other seems to be using the Static
CNAME Delegation which seems like a better way to do this.

I think I have internet overload trying to understand this. With using the manual option it
seems there is the need for these manual hook scripts. I think I read somewhere if you create
a cert with the manual option you can't renew it automatically.

If you can help me understand this better I would appreciate it. I am probably way off on
this. Thank you for the help.

Rich

You appear to have an understanding of dns-01, you are correct that it operates by adding a TXT record at _acme-challenge.<domain>.

There are three ways to provision this record of which you've identified two:

  • Directly adding the record to the <domain> zone. This requires permission to add/remove the record in the zone and an API if automation is desired. Unfortunately this may require giving certbot more privileges than required if the DNS server doesn't support ACLs.
  • Using a CNAME to allow the record to be provisioned elsewhere, this is typically used by CAs so that users don't have to use an ACME client and is currently being phased out in favor of persistent DNS records (Latest Baseline Requirements | CA/Browser Forum)[1]. This is also used by acme-dns although a self hosted instance is recommended (GitHub - acme-dns/acme-dns: Limited DNS server with RESTful HTTP API to handle ACME DNS challenges easily and securely. · GitHub)
  • Delegating the _acme-challenge subdomain, this requires creating the _acme-challenge.<domain> zone on a DNS server and delegating the _acme-challenge subdomain by placing NS records in the <domain> zone. This allows for a different DNS server to be used which might be more easily automatable or allow for privilege separation.

Direct modification and delegation are the recommended options. CNAME based solutions delegate authorisation to another party that could issue certificates for your domain although this is less of an issue if you're delegating authorisation to your CA.


  1. dns-persist-01 will be different from this by offering cryptographic key binding ↩︎

CNAME delegation doesn't remove the need for a DNS record creation per each renewal.
It merely delegates that exact same requirement to some other FQDN [which might be handled by another domain or by some other company].

Speaking about HTTP...
[Abbreviated for clarity]

If HTTP requests from the Internet are being handled [at all], whatever is doing that can simply proxy your HTTP-01 challenge requests to your FQDN [presuming your Oracle Linux 8 can be reached (internally) via port 80].

I believe there is a typo, I think you want _acme-challenge.colostate.edu instead.
before colostate.edu you have 2 dots.

As an aside, for people migrating from InCommon you should just be able to use Let's Encrypt (or any other ACME CA) with any ACME Client, unless you require Entity/Org Validated certs (the ones that include your organization name in the cert). Most people don't.

For DNS Challenges to work your ACME client need to tell the responding DNS server what value to respond with. Normally this involves configuration a DNS plugin/provider for your ACME client that knows how to talk to that DNS provider.

So to have an _acme-challenge.subdomain.yourdomain.com CNAME delegating to _acme-challenge.someotherdomain.com you need to be pushing the updates to _acme-challenge.someotherdomain.com. In your case that looks to be _acme-challenge.certs.ac.atriumcampus.com for example, they are not a DNS provider I've heard of.

Since Certbot was mentioned you should know that it does not natively support dns-01 challenges for delegated domain names (either CNAME or NS). It only updates the _acme-challenge TXT record related to a domain name requested for the certificate.

Certbot works with acme-dns only because acme-dns provides a custom plugin.

You can write custom hooks to handle delegations. It just isn't available as-is.

@rblumlei Hasn't Sectigo given you any advice on how best to get certs with its system? Isn't that part of what you pay them for? We talked about this back in June. Even though you decided to stay with Sectigo the same background about Let's Encrypt and Certbot remain. See: Certbot release levels, and switching from Sectigo to CertiNext - #2 by MikeMcQ

to put the pieces above together, because the answer is split across three posts and the order matters.

rg305 is right that delegation does not remove the per-renewal record. something still has to write a fresh txt value for every issuance. what the cname changes is where that write happens and who needs the credential for it. the cname itself is the static part: you create _acme-challenge.host.colostate.edu as a cname to a name in the delegated zone, once, and never touch it again. the txt record at the far end is what changes on every renewal.

so the question to answer first is not about certbot, it is: who runs the zone the cname points into, and what do they accept an update over? in your case the target looks like _acme-challenge.certs.ac.atriumcampus.com, which is somebody else's zone, so only they can tell you how a value gets in there. a cname pointing at a name that nobody updates just moves the failure: the ca follows it, finds nothing, and the challenge fails with a message about a missing txt record rather than about the delegation.

on certbot specifically, mikemcq's point is the one that will cost you time if you miss it. certbot does not follow delegations itself. it writes the txt for the name in the certificate and nothing else. two ways out:

  • the acme-dns plugin (certbot-dns-acmedns), if the far end speaks the acme-dns protocol. this is the well-trodden path.
  • --manual-auth-hook and --manual-cleanup-hook, which are just scripts. certbot hands your script the domain and the validation value in $CERTBOT_DOMAIN and $CERTBOT_VALIDATION, and whatever the script does with them is your business, including posting them to whatever api the delegated zone offers. --manual-cleanup-hook removes it afterwards.

worth knowing before you invest in hooks: several other clients follow the cname natively, so the delegation needs no special support at all. lego, acme.sh and posh-acme all resolve _acme-challenge.<name> first and then act on wherever it points. if you are not tied to certbot, that is less code to maintain than a pair of hook scripts.

one practical note on the port 80 half of your original question, since it may make all of this optional: dns-01 is not the only way out of "port 80 is already taken". a single wildcard obtained once and distributed is one answer, and rg305's suggestion of proxying just the /.well-known/acme-challenge/ path from whatever already answers on 80 is another, and it is usually a smaller change than standing up a dns automation path across a fleet.