This page is assumes using OpenDNSSEC to sign zones. Thanks to Willem Toorop and Ralph Dolmans at NLnet Labs for developing this automated solution!
An example configuration file is:
CA="https://acme-v01.api.letsencrypt.org/directory"
#CA="https://acme-staging.api.letsencrypt.org/directory"
LICENSE="https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf"
CERTDIR=/usr/local/etc/dehydrated/certs
CHALLENGETYPE="dns-01"
HOOK=/usr/local/etc/dehydrated/dnshook.sh
PRIVATE_KEY_RENEW="no"
PRIVATE_KEY_ROLLOVER="no"
CONTACT_EMAIL=alice@example.com
Private keys are then stored in
/usr/local/etc/dehydrated/certs/<domain>/privkey.pem
The SubjectAltNames are then enumerated in the file
/usr/local/etc/dehydrated/domains.txt
Add one line in this for each ‘group’ of names that should share a certificate e.g
example.com www.example.com example.org
example1.com www.example1.com example1.net
Then the challenge record needs to be provisioned in the corresponding zone in a record of the form
_acme-challenge.<domain name>
If you have many zones it can be helpful to use CNAMES to redirect to a single zone that can hold the acme_challenge records e.g. <domain>.acme.example.com
The domain acme.example.com is then hosted only on the server that also runs dehydrated.
A script can then be used to deploy and clean the challenge in this domain. An example script is included below
#!/bin/sh
zonefile=/usr/local/etc/dehydrated/acmezone
deploy_challenge() {
local DOMAIN="${1}" RDATA="${3}"
echo "$DOMAIN 10 TXT \"$RDATA\"" >> $zonefile
echo "$DOMAIN 10 TXT \"$RDATA\""
ldns-read-zone $zonefile > /dev/null
if [ $? -eq 0 ]; then
cp $zonefile ~/unsigned/acme.example.com
ods-signer sign acme.example.com
sleep .5
fi
}
clean_challenge() {
local DOMAIN="${1}" RDATA="${3}"
sed -i ".old" "/$DOMAIN 10 TXT \"$RDATA\"/d" $zonefile
ldns-read-zone $zonefile > /dev/null
if [ $? -eq 0 ]; then
cp $zonefile ~/unsigned/acme.example.com
ods-signer sign acme.example.com
fi
}
deploy_cert() {
local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}"
FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="${6}"
# nothing yet..
}
unchanged_cert() {
local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}"
FULLCHAINFILE="${4}" CHAINFILE="${5}"
# nothing yet..
}
HANDLER="$1"; shift
"$HANDLER" "$@"