dehydrated is a letsencrypt/ACME client implementation in currently about 2500 lines of bash code. It’s relatively easy on the dependencies and should run on most Linux systems out of the box. It provides a easy and huzzle-free alternative to certbot for automatic certificate retrieval on ACME servers, e.g. letsencrypt. In this tutorial I’m giving you a quickstart guide on how you can use dehydrated
to setup a letsencrypt certificate for your own webserver.
This tutorial works on a openSUSE Linux server (Leap or Tumbleweed and derivatives) and assumes you are using the nginx
webserver. It should be relatively simple though to adjust to other webservers e.g. apache2
or lighthttpd
.
Installation
zypper in dehydrated
Yes, it’s that simple. dehydrated
comes with the actual script, configuration files in /etc/dehydrated
and a handy systemd service timer, the dehydrated.timer
for automatic certification renewal.
Configuration
To get letsencrypt running you need to do three things:
- Add your domain to
/etc/dehydrated/domains.txt
This is really just a text file containing all of your domains, one domain per line.
- Optional: Adjust the configuration in
/etc/dehydrated.config
to your needs
But the defaults should already work out of the box. I recommend to set CA="letsencrypt-test"
before going in production to check the configuration first.
- Add the challenge directory to your
nginx
configuration, e.g.
server {
listen 80;
listen [::]:80;
server_name my-awesome-dehydrated.server;
location /.well-known/acme-challenge {
alias /var/lib/acme-challenge;
}
...
}
That’s it. Now you should be ready to go!
Running dehydrated / Obtaining your certificates
First display, read and accept the TOS:
# dehydrated --display-terms
# dehydrated --register --accept-terms
And then run dehydrated to create new certificated
# dehydrated --cron
This should create your certificates in domain subfolders located in /etc/dehydrated/certs/
, e.g.
/etc/dehydrated/certs/feldspaten.org/
├── cert.csr
├── cert.pem
├── chain.pem
├── fullchain.pem
└── privkey.pem
...
Configure nginx to use the certificates
As last step AFTER you were able to obtain the certificates is to configure nginx
to use those certificates for a tls connection.
As first optional step, I want to ensure that only secure ciphers are used by defining a common tls options file in /etc/nginx/options-tls-nginx.conf
. This is similar to the approach that cert-bot
is doing. Here is my current file as template:
# /etc/nginx/options-ssl-nginx.conf
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
Next, also as optional step, is to generate Diffie-Hellman parameters for additional security on your tls connections. /etc/nginx/dhparam.pem
appears to me as a good location and I create them with 4096 bits. 2048 is fine too, but don’t go lower:
openssl dhparam -out /etc/nginx/dhparam.pem 4096 # this might take a bit
chmod 0400 /etc/nginx/dhparam.pem # ensure nobody else can access them
Finally we add the following instructions to our server
block in the nginx
virtual hosts file to enable tls:
server {
listen 443 ssl http2;
listen [::]:443 ssl ipv6only=on http2;
server_name m1.feldspaten.org;
ssl_certificate /etc/dehydrated/certs/feldspaten.org/fullchain.pem;
ssl_certificate_key /etc/dehydrated/certs/feldspaten.org/privkey.pem;
include /etc/nginx/options-tls-nginx.conf; # optional but recommended
ssl_dhparam /etc/nginx/dhparam.pem; # optional but recommended
...
}
Now, check if the configuration is ok, and if so, restart/reload your nginx
server and you’re good to go:
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# systemctl restart nginx
Enable certificate auto-update
To enable the automatic update of your certificates, simply use the dehydrated.timer
timer:
systemctl enable --now dehydrated.timer
Check if everything is alright:
# systemctl status dehydrated.timer
● dehydrated.timer - Run Certificate Update Runner for Dehydrated
Loaded: loaded (/usr/lib/systemd/system/dehydrated.timer; enabled; vendor preset: disabled)
Active: active (waiting) since Thu 2022-06-30 09:01:32 CEST; 1 day 1h ago
Trigger: Sat 2022-07-02 00:59:15 CEST; 14h left
Triggers: ● dehydrated.service
And you’re good to go.
Congratulations! You have your letsencrypt certificate process setup and automated using dehydrated
and you’re awesome 🚀