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/dehydratedSince 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/dehydratedI 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-stagingCA 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-01which 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 calledcertsinside 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-01method 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/dehydratedNow 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 -cWhen 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