Dehydrated: Letsencrypt/acme client implemented as a shell-script
github.com
github.com
The best thing is it's declarative: you provide a text file with domains you want in each certificate, and it makes it happen.
Certbot has discrete commands you have to run to add, remove, or modify certificates, so you have to keep track of state. We had a management UI to control these domains, so it didn't work well with something like terraform (which I think otherwise solves the state problem for certbot). Instead we just wrote out the domain file based on db config changing + daily, and ran dehydrated. If there were no certificate changes or renewals needed, nothing would happen.
Also the hooks are great, iirc we had a pre-check in place for our own http-01 validation, so as not to cause failures on let's encrypt. (Mostly customers would cname domains to us, but lots could go wrong). We were also using s3 to store the validation files (again, super easy with bash hooks) to make it work across a pool of load balancers.
This is a great example of a tool where a focus on simplicity (config, hooks, and the way it stores everything) creates an incredibly easy to use, flexible (and thus powerful) system.
They plan to keep the project open source and employ Lukas to continue maintaining it.
filter="$(printf 's/.\[%s\][[:space:]]\([^"]*\)/\\1/p' "$(json_path "${1:-}" "${2:-}")")"
Please, no! How can you know this is safe?
Why not just use Python? It is installed pretty much everywhere, supports json without such hacks.
Yes, but which version?
Not the modules, but Python itself.
MacOS Sonoma (the latest version) doesn't include Python at all; older versions of MacOS which are still supported ship with Python 2.x
> I don't think
> target audience
You != people
Then address this to the owners of those machines. And get a load of cash ready to give it to them, so they could migrate to somehitng newer.
I know of a couple large organizations that have tens of thousands of RHEL 7 machines that use letsencrypt for customer websites, and I sent this project to sysadmins on their teams, so it's very realistic to expect that businesses are still using supported software.
Not everyone can just upgrade to the latest version of Ubuntu every 6 months for their production workloads like you might expect.
#!/bin/sh
set -eu
set -o pipefail
cd /home/letsencrypt
openssl verify -CAfile lets-encrypt-x3-cross-signed.pem -attime `date -d 'next month' '+%s'` mah_domain.crt | grep expired || exit 0
DT=`date "+%Y%m%d"`
python3 acme-tiny/acme_tiny.py --account-key account.key --csr mah_domain.csr --acme-dir /srv/www/mah_domain/htdocs/.well-known/acme-challenge/ > signed_${DT}.crt
curl -sO https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.p...
cat signed_${DT}.crt lets-encrypt-x3-cross-signed.pem > mah_domain_chained_${DT}.pem
mv mah_domain_chained_${DT}.pem mah_domain_chained.pem
mv signed_${DT}.crt mah_domain.crt
set +e
nginx -c /srv/nginx/conf/nginx.conf -s reload
Using this exact shebang line signals "This script is intended to be executed directly (not a python module) and it only needs the python3 standard library."
maybe for dev environments, but certainly not for servers
I'm also not sure distros generally care about LSB. Debian dropped it years ago and did any distro even bother to implement it correctly?
$ wc --lines /etc/dehydrated/domains.txt
5161 /etc/dehydrated/domains.txt # Close weird external file descriptors
exec 3>&-
exec 4>&-
From this commit:https://github.com/dehydrated-io/dehydrated/commit/b116e6bc2...
This, together with the fact that most shell scripting is bash based which is, in my opinion, not a very good language, makes it less secure to me than a python tool.
One of the biggest risks today is supply chain attacks. The more dependencies you have, the more people you are giving the ability to tamper with your critical code paths.
In this case you only actually need curl, openssl, and busybox. Those depend on at least a small libc implementation and a kernel but those are certainly already present.
Coreutils or busybox is probably already installed too. Still, I will grant the requirement of musl and a linux kernel since we are being pedantic or maybe talking about an embedded linux use case, so 5 deps total to boot from metal and get a cert.
To be fair I would never actually ship openssl or busybox in a real embedded project. Would probably write a simple standalone binary using the standard library of Go or something.
All the packages listed are already probably installed on your system, so you have to worry about their integrity already (your system package manager (RPM, Deb) probably leverages them).
Something like Certbot pulls in dependencies on top of what your system already has, whereas Dehydrated or Acme.sh use tools that you already have to worry about anyway because they're part of the base OS.
awk, grep, curl, getent, sudo, mkdir, mv, ln, cat, rm, openssl, touch
Most of these have around 10 dependencies on libs.
Don't misunderstand me. I have nothing against the script. I just don't like the argument that bash is better because it has no dependencies.
The only things that are a bit heavy in the list are openssl and curl. Still, they are relatively self-contained tools, nothing to do with the dependency hell of certbot.
Basically I'm not avoiding Certbot to make a point, I just think it's inferior for my specific use cases. I don't know about Dehydrated but I also expect it to be BS free.
I discovered the issue was that the plugin does some pretty broad-brush guesswork about which domain in your DNS hosting it should actually populate with the response value. If you own a bunch of similar domain names (as many orgs do), the plugin may guess wrong.
Much happier to be using dehydrated, and I don't regard it as a major impediment that I had to spend 10 minutes hand writing the necessary API call to the DNS provider.
Also their official builds are built with Alpine which is a hobby distro that does not even do signed code or packages.
Alpine chooses low security for low contribution friction. It is the Wikipedia of Linux distros, which granted it a huge package repository fantastic for experimental use and reference, but it is not something sane to blindly trust the latest packages of in production.
It is one of the reasons why I made stagex, which in most cases is a near drop-in replacement.
EDIT: Also, stagex looks pretty compelling; I hope it catches on!
Icing on the cake is that the Certbot team advertises alternative install methods, of which none work and all of the lengthy guides for them recommend to use Snap instead. It’s an insult for professionals.
I've only been using it for a little while, but the pip + venv method seems to work decently well: https://certbot.eff.org/instructions?ws=other&os=pip
> Partial support > The Certbot team supports this installation method on a best effort basis. If you are on a more obscure or heavily customized system, these instructions may not work and the Certbot team may be unable to help you resolve the problem.
This is an instant no-go for any professional environment I ever worked in.
So ridiculous to have to install yet another package manager, snapd, to get certbot installed "the easy way".
The alternative to get around snapd works fine (IMHO, for my situation, a lightsail instance running amazon linux 2023 where installing snapd is a pain in the ass), but you still have to jump through some hoops.
It's 2024. If you're still distributing snaps as the preferred method of install, you're alienating your users. AppImage, Flatpak, and regular containers are all far better deployment options.
Dropped lxd because of it. Now I hear they're a proper debian package, but that decision was so weird (especially the auto-update part) I don't trust them anymore.
Is there a problem with that?
> this mode of operation is unable to install certificates or configure your webserver, because our installer plugins cannot reach your webserver from inside the Docker container. > > Most users should use the instructions at certbot.eff.org. You should only use Docker if you are sure you know what you are doing and have a good reason to do so.
These problems are solvable if you know what you do, but the whole premise of ACME was making it easier to obtain certificates; plus, I shouldn’t need to decide between an autonomous and hostile package manager or keeping a container environment running, secure, and configured - to set up bloody TLS certificates for a Webserver. That said, good for you if it works :)
This means its dependencies footprint is much smaller, and allows you to do things that can be a nightmare to configure with Certbot or other alternatives. For example, at one of the scenarios I had to set up was that we had to query a credential via HashiCorp Vault, which is then used to cURL into an API endpoint. The shell script in total was pretty short (~200 LOC) and it worked extremely well. The fact the shell script is so simple that I could test adding/removing records without ever invoking ACME process is also a huge benefit.
[1]: https://github.com/dehydrated-io/dehydrated/blob/master/docs...
I had also used a pre-shared private key, which I put on a F5 BigIp, and just scheduled a job on the F5 to pull the updated certs daily.
Constant breakage unless you're using snaps on the most popular distributions. The CLI is absolutely idiotic and convoluted and the plugins do a lot of guess work without informing you, which results in some fun debugging. It's also a large pile of dependencies that take up space.
They seem to have gone through some effort for this to be true.
Why would POSIX be implied in any way? I mainly use windows, should I have been upset because I thought cmd or powershell was implied?
sudo apt install certbot python3-certbot-nginx
And it “just works” on Ubuntu. The whole thing is super easy and takes around 1 minute to get a cert installed and configured with nginx.Also not everyone wants to install few dozens of packages just for this little thing.
There’s this misconception that you need extra packages to get certificates working with different software.
For the rest, I'll indeed look into lighter alternatives some day. But the setup works on its own so I'm a bit lazy.
Sure. Now look at the dependencies that are installed compared to dependencies that are installed for dehydrated (or acme.sh, etc) which generally are: bash, OpenSSL, cURL. This is very handy for more appliance-like system (I ran dehydrated on (RH-based) F5s for years before ACME was put into the GUI; also ran it on (FreeBSD-based) Isilons.)
Also, if you want to do an audit of the code, how many lines of Python need to be examined (including dependencies) compared to how many lines of Bash? (Both would have common dependencies like (Open)SSL and HTTP/cURL libraries.) As we saw with the recent XZ kerfuffle, 'software supply chains' are becoming important.
Personally I find it much easier to understand / configure dehydrated:
$ git clone https://github.com/dehydrated-io/dehydrated.git
$ sudo cp dehydrated/dehydrated /usr/bin/
# cat > /etc/dehydrated/config
WELLKNOWN="/var/www/htdocs/.well-known/acme-challenge"
CONTACT_EMAIL="you@example.com"
# cat > /etc/dehydrated/domains.txt
example.com www.example.com
# mkdir -p /var/www/htdocs/.well-known/acme-challenge
$ sudo dehydrated -c
(Ubuntu/Debian has packages for it as well.)