Skip to content

Instantly share code, notes, and snippets.

@hrefhref
Created November 9, 2017 13:52
Show Gist options
  • Save hrefhref/145713defa318653172cfedafa1faf6f to your computer and use it in GitHub Desktop.
Save hrefhref/145713defa318653172cfedafa1faf6f to your computer and use it in GitHub Desktop.
dehydrated hook for dns validation with powerdns
#!/usr/bin/env bash
set -e
set -u
set -o pipefail
umask 077
mysql_base="powerdns"
mysql_host="localhost"
mysql_user="powerdns"
mysql_pass=""
pdns_slaves="212.129.35.122 71.19.148.32"
pdns_secret=""
# Wait this value in seconds at max for all nameservers to be ready
# with the deployed challange or fail if they are not
dns_sync_timeout_secs=90
export pw_file="$HOME/.letsencrypt_pdns_my.cnf"
export mysql_default_opts="--defaults-extra-file=$pw_file --host=$mysql_host --user=$mysql_user --silent"
# write the mysql password to file, do not specify it the command line(insecure)
touch $pw_file
chmod 600 $pw_file
cat >$pw_file <<EOF
[mysql]
password=$mysql_pass
EOF
domain="${2}"
token="${4}"
timestamp=$(date +%s)
IFS='.' read -a myarray_domain <<< "$domain"
root_domain="${myarray_domain[*]: -2:1}.${myarray_domain[*]: -1:1}"
done="no"
function mysql_exec { mysql $mysql_default_opts "${@}"; }
if [[ "$1" = "deploy_challenge" ]]; then
id="$(mysql_exec -N -e "SELECT id FROM $mysql_base.domains WHERE name='$root_domain';")"
soa="$(mysql_exec -N -e "SELECT content FROM $mysql_base.records WHERE domain_id='$id' AND type='SOA'")"
idSoa="$(mysql_exec -N -e "SELECT id FROM $mysql_base.records WHERE domain_id='$id' AND type='SOA'")"
IFS=' ' read -r -a soArray <<< "$soa"
soArray[2]=$((soArray[2]+1))
soaNew="$( IFS=$' '; echo "${soArray[*]}" )"
mysql_exec -e "UPDATE $mysql_base.records SET content='$soaNew' WHERE id='$idSoa'"
mysql_exec -e "INSERT INTO $mysql_base.records (domain_id,name,type,content,ttl,prio,change_date) VALUES ('$id', '_acme-challenge.$domain','TXT','$token','5','0','$timestamp')"
echo "Updated DB, waiting for slaves update"
for slave in $pdns_slaves; do
pdns_control --remote-address=$slave --secret=$pdns_secret retrieve $root_domain
done
sleep 5
nameservers="$(dig -t ns +short ${domain#*.})"
nameservers="ns0.random.sh"
# challenge_deployed=0
failed_servers=0
for((timeout_counter=0;$timeout_counter<$dns_sync_timeout_secs;failed_servers=0,timeout_counter++)); do
for nameserver in $nameservers;do
if ! dig @$nameserver +short -t TXT _acme-challenge.$domain | grep -- "$token" > /dev/null; then
failed_servers=1
fi
done
[ "$failed_servers" == 0 ] && { challenge_deployed=1 ; break ; }
sleep 1
printf "."
done
if [ "$challenge_deployed" == "1" ]; then
done="yes"
else
echo -e "\n\nERROR:"
echo "Challenge could not be deployed to all nameservers. Timeout of $dns_sync_timeout_secs "
echo "seconds reached. If your slave servers need more time to synchronize, increase value "
echo "of variable dns_sync_timeout_secs in file $0."
exit 1
fi
fi
if [[ "$1" = "clean_challenge" ]]; then
mysql_exec -e "DELETE FROM $mysql_base.records WHERE content = '$token' AND type = 'TXT'"
done="yes"
fi
if [[ "${1}" = "deploy_cert" ]]; then
domain="${2}"
privkey="${3}"
cert="${4}"
chain="${5}"
cp $privkey "/root/ssl/${domain}.key"
cp $chain "/root/ssl/${domain}.pem"
done="yes"
fi
if [[ "$1" = "unchanged_cert" ]]; then
done="yes"
fi
if [[ ! "${done}" = "yes" ]]; then
echo "Skipping hook ${1}"
exit 0
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment