diff options
Diffstat (limited to 'dehydrated/bin/dehydrated-nsupdate')
-rwxr-xr-x | dehydrated/bin/dehydrated-nsupdate | 103 |
1 files changed, 95 insertions, 8 deletions
diff --git a/dehydrated/bin/dehydrated-nsupdate b/dehydrated/bin/dehydrated-nsupdate index fa421ea..657cc48 100755 --- a/dehydrated/bin/dehydrated-nsupdate +++ b/dehydrated/bin/dehydrated-nsupdate @@ -45,30 +45,50 @@ esac if command -v kdig > /dev/null 2>&1 then # knot-dnsutils - DIG="kdig +noidn" + DIG_VARIANT="knot" elif command -v dig > /dev/null 2>&1 then # bind-dnsutils - DIG="dig +noidnout" + DIG_VARIANT="bind" else echo "'${HOOK}': need dig from bind-dnsutils or knot-dnsutils" >&2 exit 1 fi +case "${DIG_VARIANT}" in + knot) + DIG="kdig +noidn" + ;; + + bind) + DIG="dig +noidnout" + ;; +esac + # alternatives handling for nsupdate if command -v knsupdate > /dev/null 2>&1 then # knot-dnsutils - NSUPDATE="knsupdate" + NSUPDATE_VARIANT="knot" elif command -v nsupdate > /dev/null 2>&1 then # bind-dnsutils - NSUPDATE="nsupdate" + NSUPDATE_VARIANT="bind" else echo "'${HOOK}': need nsupdate from bind-dnsutils or knot-dnsutils" >&2 exit 1 fi +case "${NSUPDATE_VARIANT}" in + knot) + NSUPDATE="knsupdate" + ;; + + bind) + NSUPDATE="nsupdate" + ;; +esac + # config for FILE in /etc/default/dehydrated-nsupdate /etc/default/dehydrated-nsupdate.d/* do @@ -88,9 +108,9 @@ else TXT_RECORD="_acme-challenge.${DOMAIN}" fi -# find nameservers to update ZONE="${TXT_RECORD}" +# find all nameservers to update while true do NAMESERVERS="$(${DIG} +nocomments +noquestion NS "${ZONE}" 2>&1 | grep -v '^;' | awk '/NS/ { print $5 }')" @@ -104,15 +124,82 @@ do fi done -if [ -n "${TSIG_KEYFILE}" ] && [ -e "${TSIG_KEYFILE}" ] +NAMESERVERS_IPV6="" +NAMESERVERS_IPV4="" + +for NAMESERVER in ${NAMESERVERS} +do + if [ -n "$(${DIG} +nocomments +noquestion +short AAAA "${NAMESERVER}")" ] + then + NAMESERVERS_IPV6="${NAMESERVERS_IPV6} ${NAMESERVER}" + fi + + if [ -n "$(${DIG} +nocomments +noquestion +short A "${NAMESERVER}")" ] + then + NAMESERVERS_IPV4="${NAMESERVERS_IPV4} ${NAMESERVER}" + fi +done + +# filter nameservers by available IP protocol +NAMESERVERS="" + +if hostname -I | grep -qs ':' +then + NAMESERVERS="${NAMESERVERS} ${NAMESERVERS_IPV6}" +fi + +if hostname -I | grep -qs '\.' then - NSUPDATE_OPTIONS="-k ${TSIG_KEYFILE}" + NAMESERVERS="${NAMESERVERS} ${NAMESERVERS_IPV4}" fi +NAMESERVERS="$(echo "${NAMESERVERS}" | sed -e 's| |\n|g' | sort -u -V)" + # update nameservers for NAMESERVER in ${NAMESERVERS} do - echo -n " + sending '${HOOK_ACTION}' for ${TXT_RECORD} to ${NAMESERVER}..." + if [ -e "/etc/dehydrated/tsig/$(basename "${TXT_RECORD}" .).key" ] + then + # specific key per record + KEY="/etc/dehydrated/tsig/$(basename "${TXT_RECORD}" .).key" + elif [ -e "/etc/dehydrated/tsig/$(basename "${ZONE}" .).key" ] + then + # specific key per zone + KEY="/etc/dehydrated/tsig/$(basename "${ZONE}" .).key" + elif [ -e "/etc/dehydrated/tsig/$(basename "${NAMESERVER}" .).key" ] + then + # specific key per nameserver + KEY="/etc/dehydrated/tsig/$(basename "${NAMESERVER}" .).key" + elif [ -e "/etc/dehydrated/tsig.key" ] + then + # global key (filesystem) + KEY="/etc/dehydrated/tsig.key" + elif [ -n "${TSIG_KEYFILE}" ] && [ -e "${TSIG_KEYFILE}" ] + then + # global key (conffile) + KEY="${TSIG_KEYFILE}" + else + # no key + KEY="" + fi + + # ignoring comments to allow empty keyfiles to disable TSIG individually + TSIG="$(grep -sv '^#' "${KEY}" || true)" + + if [ -n "${KEY}" ] && [ -n "${TSIG}" ] + then + case "${NSUPDATE_VARIANT}" in + knot) + NSUPDATE_OPTIONS="-k ${KEY}" + ;; + + bind) + NSUPDATE_OPTIONS="-y $(cat "${KEY}")" + ;; + esac + fi + + echo -n " + sending '${HOOK_ACTION}' for ${TXT_RECORD} to ${NAMESERVER}.." # shellcheck disable=SC2086 echo "server ${NAMESERVER} |