From 9c54c3700cef02cad278ddaf46cb8e61bcbc8697 Mon Sep 17 00:00:00 2001 From: Fabio Rauber Date: Tue, 29 Jun 2021 17:00:51 -0300 Subject: [PATCH] Applied PowerDNS compatibility mod in new dehydrated-dns script --- Dockerfile | 3 +- dehydrated-dns.sh | 151 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 2 deletions(-) create mode 100755 dehydrated-dns.sh diff --git a/Dockerfile b/Dockerfile index 901c20b..c31e092 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,12 +20,11 @@ RUN apk add --no-cache --virtual .build-deps git build-base libffi-dev openssl-d && cd lexicon \ && git checkout tags/v3.3.17 \ && cd .. \ - && chmod a+x lexicon/examples/dehydrated.default.sh \ - && mv lexicon/examples/dehydrated.default.sh /usr/bin/dehydrated-dns \ && rm -rf /tmp/* \ && apk del .build-deps COPY config /etc/dehydrated/config +COPY dehydrated-dns.sh /usr/bin/dehydrated-dns COPY docker-entrypoint.sh / ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/dehydrated-dns.sh b/dehydrated-dns.sh new file mode 100755 index 0000000..8fa162f --- /dev/null +++ b/dehydrated-dns.sh @@ -0,0 +1,151 @@ +#!/usr/bin/env bash +# +# Example how to deploy a DNS challenge using lexicon + +set -e +set -u +set -o pipefail + +export PROVIDER_UPDATE_DELAY=${PROVIDER_UPDATE_DELAY:-"30"} +export PROVIDER=${PROVIDER:-"cloudflare"} + +function deploy_challenge { + local chain=($@) + for ((i=0; i < $#; i+=3)); do + local DOMAIN="${chain[i]}" TOKEN_FILENAME="${chain[i+1]}" TOKEN_VALUE="${chain[i+2]}" + + echo "deploy_challenge called: ${DOMAIN}, ${TOKEN_FILENAME}, ${TOKEN_VALUE}" + if [ "${PROVIDER,,}" == "powerdns" ]; then + lexicon $PROVIDER create ${DOMAIN} TXT --name="_acme-challenge.${DOMAIN}." --content="${TOKEN_VALUE}" --pdns-server ${LEXICON_POWERDNS_SERVER} + else + lexicon $PROVIDER create ${DOMAIN} TXT --name="_acme-challenge.${DOMAIN}." --content="${TOKEN_VALUE}" + fi + + done + + local DELAY_COUNTDOWN=$PROVIDER_UPDATE_DELAY + while [ $DELAY_COUNTDOWN -gt 0 ]; do + echo -ne "${DELAY_COUNTDOWN}\033[0K\r" + sleep 1 + : $((DELAY_COUNTDOWN--)) + done + + # This hook is called once for every domain chain that needs to be + # validated, including any alternative names you may have listed. + # + # Parameters: + # - DOMAIN + # The domain name (CN or subject alternative name) being + # validated. + # - TOKEN_FILENAME + # The name of the file containing the token to be served for HTTP + # validation. Should be served by your web server as + # /.well-known/acme-challenge/${TOKEN_FILENAME}. + # - TOKEN_VALUE + # The token value that needs to be served for validation. For DNS + # validation, this is what you want to put in the _acme-challenge + # TXT record. For HTTP validation it is the value that is expected + # be found in the $TOKEN_FILENAME file. +} + +function clean_challenge { + local chain=($@) + for ((i=0; i < $#; i+=3)); do + local DOMAIN="${chain[i]}" TOKEN_FILENAME="${chain[i+1]}" TOKEN_VALUE="${chain[i+2]}" + + echo "clean_challenge called: ${DOMAIN}, ${TOKEN_FILENAME}, ${TOKEN_VALUE}" + + if [ "${PROVIDER,,}" == "powerdns" ]; then + lexicon $PROVIDER delete ${DOMAIN} TXT --name="_acme-challenge.${DOMAIN}." --content="${TOKEN_VALUE}" --pdns-server ${LEXICON_POWERDNS_SERVER} + else + lexicon $PROVIDER delete ${DOMAIN} TXT --name="_acme-challenge.${DOMAIN}." --content="${TOKEN_VALUE}" + fi + + done + + # This hook is called after attempting to validate each domain + # chain, whether or not validation was successful. Here you + # can delete files or DNS records that are no longer needed. + # + # The parameters are the same as for deploy_challenge. +} + +function invalid_challenge() { + local DOMAIN="${1}" RESPONSE="${2}" + + echo "invalid_challenge called: ${DOMAIN}, ${RESPONSE}" + + # This hook is called if the challenge response has failed, so domain + # owners can be aware and act accordingly. + # + # Parameters: + # - DOMAIN + # The primary domain name, i.e. the certificate common + # name (CN). + # - RESPONSE + # The response that the verification server returned +} + +function deploy_cert { + local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" + + echo "deploy_cert called: ${DOMAIN}, ${KEYFILE}, ${CERTFILE}, ${FULLCHAINFILE}, ${CHAINFILE}" + + # This hook is called once for each certificate that has been + # produced. Here you might, for instance, copy your new certificates + # to service-specific locations and reload the service. + # + # Parameters: + # - DOMAIN + # The primary domain name, i.e. the certificate common + # name (CN). + # - KEYFILE + # The path of the file containing the private key. + # - CERTFILE + # The path of the file containing the signed certificate. + # - FULLCHAINFILE + # The path of the file containing the full certificate chain. + # - CHAINFILE + # The path of the file containing the intermediate certificate(s). +} + +function unchanged_cert { + local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" + + echo "unchanged_cert called: ${DOMAIN}, ${KEYFILE}, ${CERTFILE}, ${FULLCHAINFILE}, ${CHAINFILE}" + + # This hook is called once for each certificate that is still + # valid and therefore wasn't reissued. + # + # Parameters: + # - DOMAIN + # The primary domain name, i.e. the certificate common + # name (CN). + # - KEYFILE + # The path of the file containing the private key. + # - CERTFILE + # The path of the file containing the signed certificate. + # - FULLCHAINFILE + # The path of the file containing the full certificate chain. + # - CHAINFILE + # The path of the file containing the intermediate certificate(s). +} + +exit_hook() { + # This hook is called at the end of a dehydrated command and can be used + # to do some final (cleanup or other) tasks. + + : +} + +startup_hook() { + # This hook is called before the dehydrated command to do some initial tasks + # (e.g. starting a webserver). + + : +} + +HANDLER=$1; shift; +if [ -n "$(type -t $HANDLER)" ] && [ "$(type -t $HANDLER)" = function ]; then + $HANDLER "$@" +fi