Which Lets Encrypt client should SlickStack use?

Thanks to all the people smarter than me who commented on my previous thread seeking clarity on what steps the Certbot client goes through when requesting and managing LE certs.

As part of that discussion, I realized that there is a measurable amount ambiguity among extremely talented developers re: many aspects of the Lets Encrypt and Certbot world. I'm not nearly as smart as most of the people in that thread, so it made me feel a little bit better :slight_smile:

I also realized that Certbot might not be the best solution for SlickStack, my open source bash script project for deploying LEMP stack WordPress servers.

A major feature of SlickStack is that it only supports a single TLD domain per KVM cloud server; this is purposeful and is meant to improve security and usability in a world of ever-cheaper web hosting. I've realized a side benefit of this approach is that less same-IP requests are sent to the Lets Encrypt servers (for whatever that is worth) which in some cases, might help avoid rate-limits or other issues.

But in my linked thread above, some of you suggested using acme.sh instead of Certbot if the goals of my project were to maintain a very lightweight server stack; it seems Certbot is increasingly focused on automatic file management for general web hosting providers, such as cPanel/Apache providers who don't mind some bloat and don't want to manually request/renew/manage their LE SSL certs... it also made me realize that I haven't spent enough time over the past few years trying to understand where Certbot ends and where Lets Encrypt begins -- both technically, and otherwise.

So, again, leveraging the incredible knowledge in this community... I'm hoping a few people might suggest whether SlickStack should use Certbot (Ubuntu-friendly, more automation, but more bloat) or another lighter client such as acme.sh or otherwise... in particular, I'm wondering if there are any other lightweight clients that are well-maintained which could help achieve my goals of the following:

  • Requires as few files/dependencies as possible
  • Meant for sysadmins who prefer setting their own cron jobs for SSL renewals (etc)
  • Not meant for automatic modification of Nginx configuration
  • Supports custom location of cert files/keys
  • Supports DNS verification AND web root verification from Lets Encrypt
  • Well-maintained and/or sponsored

Could I just "check Google"... yes, I could, but I just learned an incredible amount of things on my last thread that otherwise would have taken me months of discovery. Thanks for your time, folks!

3 Likes

If you have the time, space, patience, and bandwidth, you could install an ACME client, use it, then uninstall it [every 60-90 days]. Sure, there is plenty of wrong with that approach but also plenty that matches your criteria.

If that approach is undesirable, then I would lean towards acme.sh.

3 Likes

This is where acme.sh shines vs. certbot; its dependencies are very minimal. It needs a shell, of course. curl and openssl. socat to operate in standalone mode. And I think that's it.

acme.sh does set its own cron job, though you could modify it as desired.

acme.sh doesn't modify any server configuration. certbot doesn't have to either (if you run it in certonly mode, you're on your own to install the certs).

acme.sh supports this, just like certbot, and in largely the same way. It keeps its own store of cert files (in ~/.acme.sh by default, rather than /etc/letsencrypt). Using the --cert-file, --key-file, --ca-file, and/or --fullchain-file parameters, you can tell it to save a copy of the cert files wherever you want; your server can then do whatever you want it to do with them.

AFAIK, acme.sh has the best support out there for DNS validation, supporting over 100 DNS APIs. And yes, it supports web root verification as well.

acme.sh seems to be pretty actively maintained.

6 Likes

Another possibility might be uacme. It's written in plain C, with the only dependencies being libcurl and either GnuTLS, OpenSSL, or mbedTLS. You'd need your own script (which you might borrow from acme.sh) to handle DNS validation with your provider of choice, though.

3 Likes

To be honest, you could just write your own. The gold standard of bare minimal dependencies and invasiveness remains gethttpsforfree.com, which is written entirely in Javascript. It is also the most laborious and represents a true DIY approach that is heavily commented and thus serves as a great basis for building your own script client.

2 Likes

@griffin that client requires the user to run commands locally, instead of calling them directly. That's nice if you want to learn which steps an ACME client has to do, but it is nothing you really want to use. Better take a look at https://github.com/diafygi/acme-tiny instead, which is a tiny Python program (~200 lines of code) which calls openssl by itself. It is somewhat feature-limited, so it's not good for everyone, but depending on what you need it could be perfect for you - if not just as a starting point for developing your own ACME client.

3 Likes

I'm intimately familiar with gethttpsforfree.com as I dissected every last character of it when writing my own client. I'm not a particular fan of Python. I prefer to use my own client as I know exactly what it's doing at all times. You are right about the usage of that website though. It's not something one can just "script-into" one's operations. :slightly_smiling_face:

2 Likes

...but that seems to be what OP's really interested in.

3 Likes

I don't think you need to worry about any of these. Looking at your use-case scenarios, and having read the other thread, there really isn't anything negative about using Certbot. The amount of customization you are talking about looks like bloat and feature creep.

Certbot is well documented. It predictably stores certs in a given location. While it holds archives for long periods of time... the size of these is negligent. You're focused on a single TLD, so disk space is just not going to be an issue. If you want to get rid of the MINIMAL python dependencies, acme-sh is really the only option.

The big concern I would have in your use-case scenarios though, is exceeding the weekly Duplicate Certificate and Certificates per Registered Domain rate limits. Those tend to be problematic in poorly designed or misconfigured cloud systems.

Regarding acme-tiny, it's quite old and simple. the very limited features include no support for chain selection or alternates.

3 Likes

Thanks so much for all your feedback! I will respond generally to avoid too much back-and-forth.

It sounds like acme.sh is by far the most popular Certbot alternative, at least for a bash-only approach which certainly fits the bill with our SlickStack project.

The uacme script sounds interesting but written in C (requires make install to setup) and no DNS verification. I suppose it could be a lightweight option if DNS verification is not essential.... that said, their GitHub repo is a little bit difficult to follow for me (personally).

I'd never heard of acme-tiny before either, thanks for sharing that @felixf ... I'm no Python expert but with a script that small, it looks easy to figure out.... also, an impressive number of contributors.

Thanks again @jvanasco and you are exactly correct, we ran into those issues previously. Part of the problem was my desire to cleanup files, but we've since removed that feature, which seems to now avoid those duplicate certificate errors (now it says "not yet due for renewal" instead).

We also now request the SITE_DOMAIN along with the staging. and dev. subdomains (if enabled) all in the same Lets Encrypt certificate to reduce SSL requests. Thus, if a developer changes their settings to either a new domain, or enables/disables the staging/dev sites, our bash scripts (using Certbot) will see those new settings and use the new domain(s) the next time our certonly script runs... and since only a single FQDN is supported on SlickStack, I think this approach should be okay (in special cases, e.g. WordPress Multisite using dozens of subdomains, I guess we will need to add a wildcard option or again combine all desired subdomains into a single certificate bundle).

3 Likes

If you have a repeatable installation, compile the binary once and then copy it over as needed. And any validation (DNS or HTTP) is going to take an external script, but it supports both of these, at least according to its github page.

3 Likes

As you are looking for the ACME client to best fit to your special requirement, I believe it is a must for you to go through that list:

4 Likes

In my experience, the bulk of the Rate Limiting issues will come from people/systems spinning up new nodes to deal with traffic and then requesting certificates. People with entry-level and mid-level experience on cloud-based design/devops will often create/delete workers and not even think about persisting the Certificates.

That's why we opted for an API driven CertificateManger+Client. When we scale up nodes, we request Certificates from an internal API which first checks to see if there are existing Certificates and centrally processes the procurement.

5 Likes

Just following up here that I found a GitHub Issue that clarified for me the big question:

./acme.sh  --install  --nocron

YES! ...you can completely disable the auto-cron job that acme.sh adds to your Linux crontab... this is pretty exciting for me, since SlickStack hardcodes it's own crontab file.

As far as file management, I'm thinking to just create our own symlinks instead... this is the approach we have used successfully with Certbot thus far. It's one less thing you have to worry about.

I'm trying to keep everything under the /var/www/ directory for usability/backup purposes so I'm thinking just hardcoding the Nginx config files with symlink locations should be fine:

/var/www/certs/cert.pem
/var/www/certs/chain.pem
/var/www/certs/fullchain.pem
/var/www/certs/keys/privkey.pem (or key.pem)
2 Likes

Keep in mind this warning from acme.sh:

After the cert is generated, you probably want to install/copy the cert to your Apache/Nginx or other servers. You MUST use this command to copy the certs to the target files, DO NOT use the certs files in ~/.acme.sh/ folder, they are for internal use only, the folder structure may change in the future.

5 Likes

I don't really think this is a good idea--why not just tell acme.sh to put the cert files where you want them?

2 Likes

I recommend uacme: https://github.com/ndilieto/uacme#features

Of course being the author I am biased, but I believe it's a good match for all your requirements, and particularly the first two.

2 Likes