dehydrated quickstart

A simple site certificate with Let's Encrypt, dehydrated, and Apache
Created: 2018-05-01 Updated: 2021-11-30 (Updated for ACME v02 API paths)

I didn’t like the look of installing the official Let’s Encrypt client and all of its dependencies on Slackware. Thankfully, there are a number of alternative ACME-protocol clients.

dehydrated appeals to me because it’s a Bash shell script and it’s easy to set up. However, getting started using the README and other documentation is a bit challenging to piece together.

So I’m documenting my process for my future reference and for anyone else who would like to get going quickly with a simple example.


If you’re running Slackware like me, then you’ll be happy to know there’s a SlackBuild for dehydrated. Installation looks like this:

$ sudo sbopkg -i dehydrated
$ which dehydrated

(2021-08-02 Update: the slackbuild is currently a little out of date. But you can easily fix that like I did. See "Updating a Slackbuild" below.)

Otherwise, you can clone the repo and install manually, which would look something like this (untested):

$ git clone
$ sudo cp dehydrated/dehydrated /usr/bin/


Dehydrated looks for a config file in several locations, including /etc/dehydrated/config. Let’s create one:

# cat > /etc/dehydrated/config

Let’s take this config line-by-line:

  • CA is the certificate authority URL - notice that we’re going to start with "staging" to test our setup before we move to the real deal

  • CHALLENGETYPE is the method we want to use to verify we own this domain. http-01 will look for a specific URL on our web server. The alternative is dns-01, which requires us to edit our DNS zone file

  • WELLKNOWN is used in conjunction with the http-01 challenge type. It is the directory to which dehydrated should write the challenge file. In our simple example, we’re getting a certificate for one domain with a single web root (at /var/www/htdocs/). The .well-known/acme-challenge URL is where Let’s Encrypt will be looking, so this setting will put the file right where its expecting it. Getting certificates for more than one domain on the same server will require just a little bit more work

  • CONTACT_EMAIL is where Let’s Encrypt will send an expiration email if your certificate is about to expire and hasn’t been renewed


We also need to specify which domains for which to request certificates. There’s another file for that:

# cat > /etc/dehydrated/domains.txt

That one’s easy. You can have just a single domain name, or you can add some subdomains on the same certificate by putting them on the same line ( Blank lines and comments (#) are ignored.

If you have multiple domains on this server, you can specify them on separate lines. (You’ll probably also need to do some server trickery to get them all to work with the WELLKNOWN path above.)

Prepare for the http-01 challenge

To meet Let’s Encrypt’s verification challenge, dehydrated is going to try to write a specifically-named file to our above WELLKNOWN path. The path will need to exist:

$ mkdir -p /var/www/htdocs/.well-known/acme-challenge

We also need Apache to be able to read the file in order to serve it for the challenge:

$ sudo chgrp -R apache /var/www/htdocs/.well-known

Do a test run

Now we can run dehydrated:

$ sudo dehydrated -c

The -c option stands for "cron" and is pretty much the dehydrated universal register/renew operation (it’s also how you’ll be running the command as a cron job to automatically renew later).

If the challenge fails, you may need to check your Apache configuration. For example, I’d forgotten to add a <VirtualHost> directive entry for the www subdomain at The challenge had passed for, but all I kept seeing was the error and assumed I’d missed a dehydrated configuration parameter somewhere.

If all goes well, there will be no errors and you will actually have a test/staging certificate from Let’s Encrypt!

Get a real certificate

Let’s change the CA URL from "staging" to the production API:

$ sudo sed -i 's/acme-staging-v02/acme-v02/' /etc/dehydrated/config

All the sed command above did was change the config line:

TO:   CA=""

(Feel free to make the change in your favorite text editor.)

We’re almost ready to run dehydrated again. But if we do, it will see that we already have a certificate (from staging) and won’t request a new one. (Try it and see!)

To get our real certificate, we’ll need to delete the test one:

$ sudo rm -rf /etc/dehydrated/certs/*

Now you’re ready for the real certificate:

$ sudo dehydrated -c

Since it worked with staging, you should have no problem with production.

You now have a new directory containing the certificates for your domain(s):

$ sudo tree /etc/dehydrated/
|-- accounts
|-- certs
|   |--
|   |   |-- cert-000000000.csr
|   |   |-- cert-000000000.pem
|   |   |-- cert.csr -> cert-000000000.csr
|   |   |-- cert.pem -> cert-000000000.pem
|   |   |-- chain-000000000.pem
|   |   |-- chain.pem -> chain-000000000.pem
|   |   |-- fullchain-000000000.pem
|   |   |-- fullchain.pem -> fullchain-000000000.pem
|   |   |-- privkey-000000000.pem
|   |   `-- privkey.pem -> privkey-0000000000.pem
|   `-- test
|-- config
`-- domains.txt

Serious Apache configuration is beyond this article, but here’s the basic idea of what you want to have to use your new certificate in /etc/httpd/httpd.conf (or wherever you and your distro like to store Apache’s configuration):

	SSLEngine on
	SSLCertificateFile /etc/dehydrated/certs/
	SSLCertificateKeyFile /etc/dehydrated/certs/
	SSLCertificateChainFile /etc/dehydrated/certs/

Restart Apache to load the new directives:

$ sudo /etc/rc.d/rc.httpd restart

The above works in Slackware; you may need to look up the correct way to restart Apache on your distro of choice.

Congratulations, you should now have a secure domain reachable at https://<your domain>.

Setup a cron job to keep the certificate updated

Since the certificate will eventually expire, you’ll want to make sure you get a new certificate before that happens.

Happily, renewing certificates with an ACME client like dehydrated is meant to be completely automated. Here’s the certbot guide to renewal.

I’ve seen a lot of advice for running the script weekly, which sounds about right to me.

The traditional way to schedule a weekly task is to schedule a cron task by editing the cron table (crontab) like so:

$ sudo crontab -e

Add adding an entry such as this example:

14 3 * * 5 /usr/bin/dehydrated -c

(Which would run weekly at 03:14 every 5th day of the week.)

Setup a cron job to keep the certificate updated…​Slackware style!

Or for us Slackware users, just throw something into the /etc/cron.weekly script dir.

I don’t really trust that I’ve set up cron correctly until I’ve seen it run successfully a few times, so I added some logging to my dehydrated script.

Here’s my /etc/cron.weekly/dehydrated:


echo "Checking cert renewals at `date`" >> $MYLOG
/usr/bin/dehydrated -c >> $MYLOG 2>&1

We can run it manually to be sure it works and then see if the log was written:

cat /var/log/dehydrated

Looking good:

Checking cert renewals at Wed May 22 10:22:28 UTC 2019
# INFO: Using main config file /etc/dehydrated/config
Processing with alternative names:
 + Checking domain name(s) of existing cert... unchanged.
 + Checking expire date of existing cert...
 + Valid till Aug 19 00:06:56 2019 GMT (Longer than 30 days). Skipping renew!

Maybe make yourself a calendar reminder to check on it every once in a while. Otherwise, you can let the computer do the work!

Updating a Slackbuild

As I update this circa 2021, I’ve been using dehyrated to keep my website’s certificate up to date for three years. All is well. But I did notice that the slackbuild on was a little out of date.

This was a great opportunity to reacquaint myself with the process of updating and manually installing a slackbuild!

This one was a simple version update:

Get the slackbuild archive and extract it:

tar -xf dehydrated.tar.gz

Download the new version of the source archive to the extracted slackbuild directory:

cd dehydrated

Update the version in the slackbuild script:

vim dehydrated.SlackBuild
# replace VERSION=${VERSION:-0.6.5}
# with    VERSION=${VERSION:-0.7.0}

Update the file with the version and MD5 checksum of the source (I think this step is optional if you just want to build a quick package for yourself):

md5sum dehydrated-0.7.0.tar.gz
# replace VERSION and MD5SUM

Then run the slackbuild script to generate the new package and install (or in this case, upgrade) it:

upgradepkg /tmp/dehydrated-0.7.0-noarch-1_SBo.tgz

It looks like there’s a bit of a freeze on while we await the release of Slackware version 15.0. I wouldn’t be surprised if many packages were updated after 15 comes out.