This tutorial will show you how to install the Let's Encrypt ACME client dehydrated.
To install dehydrated we simply clone it's repository:
git clone https://github.com/lukas2511/dehydrated.git /opt/dehydrated
Since dehydrated will be looking for it's config file in /etc/dehydrated
we should copy the provided examples to this location:
mkdir /etc/dehydrated
cp /opt/dehydrated/docs/examples/{config,domains.txt} /etc/dehydrated
I would advise to creating a symling to /usr/local/sbin/dehydrated
since it makes it easier to call dehydrated in your shell or cronjob.
In the /etc/dehydrated/config
we may provide our default configuration for a simple(r) call of dehydrated. (i.e. dehydrated --cron
instead of dehydrated --domain domain1.tld --domain domain2.tld --hook /path/to/your/hook ...
)
The example config of dehydrated comes with lot's of comments so it actually should be self explanatory. But never the less here are some configuration settings that might be helpful:
-
CA=""
: There are two possible options for this one. The first is the production CA (https://acme-v01.api.letsencrypt.org/directory) which provides you with a trusted / valid certificate but is subject to rate limits.The second one (https://acme-staging.api.letsencrypt.org/directory) is for testing purposes and doesn't provide a trusted / valid certificate but isn't subject to the rate limits mentioned above.
You should use the
acme-staging
CA until you are certain that your setup is correct! -
CHALLENGETYPE=""
: There are currently two types of challenge types. The first one isdns-01
, it gives you the option to verify ownership of a domain via DNS entries. Some DNS providers provide API's which could be used. The second one would behttp-01
which provides the challenge inside of the webroot directory of an already running webserver. -
CERTDIR=""
: If you want your certificates to be in a specific path you may provide it here. The default would create a directory calledcerts
inside of/etc/dehydrated
. -
HOOK=""
: Hooks are used to perform certain actions throughout the process of acquiring certificates. For example you would probably want one if you want to use thedns-01
method but this could also be handy to perform certain actions on i.e. a failed renewal or a successfull renewal like sending a mail and / or restarting certain services, linking or copying the cert to a certain folder, etc. For more details you may take a look at the provided example in/opt/dehydrated/docs/examples/hook.sh
.Please be aware, that dehydrated only allows for one (!) hook to be called.
If you want to acquire multiple certificates and / or a certificate with multiple SAN you may use the domains.txt inside of /etc/dehydrated
. This file may also be defined in your config file via DOMAINS_TXT=""
. Every line in this file represents a single certificate and may contain multiple (sub-)domains:
# This will create a certificate for multiple domains:
domain1.tld sub.domain1.tld domain2.tld sub.domain2.tld ...
# This will create a certificate for a single domain:
domain3.tld
In a mailcow context, what domains do I need a certificate for?
- You should get a certificate for the hostname (fqdn) your postfix instance runs on.
- If you want your clients to connect to hostnames like imap.domain1.tld, smtp.domain1.tld, ... you should include those in the same certificate.
- If your MX records differ from your hostname (i.e. mx.domain1.tld) you need to include those as well.
- If you want to provide a seperate (sub-)domain to serve your webmail instance you may include those as well. Though this is not needed, since you can specify a different certificate and key pair for each VHOST.
With the http-01
challenge type the ACME-protocol is checking if you are in control of a domain by accessing a verification file (token) on an URL similar to http://domain1.tld/.well-known/acme-challenge/some-token
. This will be done for every domain specified in your domains.txt or inside the command (dehydrated ... --domain domain1.tld ...)
NOTE: The DNS A record for each (sub-)domain in domains.txt must point to the server you are running dehydrated on!
Dehydrated provides this token to the path specified in the config variable WELLKNOWN=""
. The default in dehydrated is /var/www/dehydrated
, so we need to create this directory:
mkdir /var/www/dehydrated
Now we need to configure our webserver to serve requests to http://domain1.tld/.well-kown/acme-challenge/...
.
server {
[...]
location ^~ /.well-known/acme-challenge/ {
alias /var/www/dehydrated/;
default_type text/plain;
}
[...]
}
Alias /.well-known/acme-challenge /var/www/dehydrated
<Directory /var/www/dehydrated>
Options None
AllowOverride None
# Apache 2.x
<IfModule !mod_authz_core.c>
Order allow,deny
Allow from all
</IfModule>
# Apache 2.4
<IfModule mod_authz_core.c>
Require all granted
</IfModule>
</Directory>
NOTE: Don't forget to restart your webserver after you configured your VHOSTs.
For this type of verification you'll need a hook, that supports your DNS provider and deploys the challenges automatically via API calls. (For a not complete list of available hooks have a look here.)
If your DNS provider has no API support you could do this manually by creating or using a manual hook, which prints the challenges into your shell so you can update the records manually. The records should look something like this:
# For domain1.tld
_acme-challenge IN TXT <YOUR_TOKEN>
# For sub.domain.tld
_acme-challenge.sub IN TXT <YOUR_TOKEN>
Now that we have configured everything we're set to run the command for the first time. This will create your account with Let's Encrypt, generate a private key and create all the certificates with their respective keys specified in your domains.txt.
dehydrated -c
When the command completed successfull you should find your certificates and keys in the path defined in your config under CERTDIR=""
. The default would be /etc/dehydrated/certs/<DOMAIN1.TLD>/fullchain.pem
and /etc/dehydrated/certs/<DOMAIN1.TLD/privkey.pem
. Where <DOMAIN1.TLD>
is always the first entry of every line in your domains.txt.
Since Let's Encrypt only provides us with a certificate that is valid for 90 days we need to setup a CRON job that renews our certificates automaticly. Let's Encrypt allows a renewal 30 days before a certificate expires, so it should be sufficient to call our CRON job once a week:
crontab -e
@weekly dehydrated -c && systemctl reload nginx.service && systemctl restart postfix.service && systemctl restart dovecot.service