Great article! One thing that might be worth adding is that ACME is not a secure protocol in cases where one client could potentially spoof another client’s address and perform the ACME challenge in its place. For network devices like load balancers and switches, this is definitely a concern since depending on the network architecture, these devices may be able to spoof each others’ addresses easily. SCEP doesn’t solve this problem either of course. It’s a challenging problem to solve and something I’ve been working on myself.
The security of ACME also depends a lot on DNS and related infrastructure. For example, I use dns-01 for a couple of my VMs, but my DNS host (Gandi) doesn’t provide a way of granting an API token that is locked down to a specific record or set of records, so either of the VMs could request Let’s Encrypt certs for any of my domains.
FWIW, I use acme.sh, which wasn’t on the list. Its default automation flow is a bit annoying because you want to run its cron task as an unprivileged user to get the certs and put them in a staging area and then run the deploy phase as root to move the certs into a location that the unprivileged user can’t write to. Unfortunately, it has a thing that can install the crontab entry in the unprivileged user’s crontab, which is completely unhelpful because that’s intrinsically racy with respect to the deploy step. The sane way of running it is from a periodic script that drops privileges to run acme.sh as the unprivileged user, blocks until it’s finished, and then runs the deploy step.
I was a bit concerned that the authors of acme.sh seemed to struggle with the idea of privilege separation and their recommended deployment is to use sudo from the unprivileged user to elevate privileges to root to run the deploy script. That’s incredibly easy to get wrong (allowing shell-script invocation via privilege elevation is never a good idea) and brings sudo into the attack surface.
Doesn’t matter if you can spoof the address, because it won’t work without the account’s private key. See RFC8555 6.2
ACME should be a part of an integrated part of an OS, IMHO. OpenBSD has the right idea here. The integration could let you go even further - your web server could transparently set up ACME challenges for each certificate, for example.
I agree ACME support could be much more widespread.
For internal CA stuff, we went Hashicorp’s Vault product. It handles cert renewal with an HTTPS call basically, a very simple API. It would be nice if they also offered ACME, for tools that support the ACME workflow also, but that is sort of a chicken/egg problem I guess, since very few tools support ACME.