Created
November 9, 2017 13:52
-
-
Save hrefhref/145713defa318653172cfedafa1faf6f to your computer and use it in GitHub Desktop.
dehydrated hook for dns validation with powerdns
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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