Skip to content

Instantly share code, notes, and snippets.

@rmetzler
Forked from anapsix/check_dns.sh
Created September 14, 2021 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmetzler/97c18c4460b2301fee0b31d50f888e9b to your computer and use it in GitHub Desktop.
Save rmetzler/97c18c4460b2301fee0b31d50f888e9b to your computer and use it in GitHub Desktop.
Watch for DNS changes and reload NGINX (or do something else)
#!/usr/bin/env bash
#
## example running it from cron
# MAILTO=""
# SHELL=/bin/bash
# VERBOSE=1
# CMD_ON_FAILURE='/etc/init.d/nginx reload'
# * * * * * root timeout -k 2 5 /tmp/check_dns.sh upstream.server.com 2>>/var/log/check_dns.log
# * * * * * root sleep 10 && sed -e :a -e '$q;N;501,$D;ba' -i /var/log/check_dns.log
#
set -u
set -o pipefail
CHECK_HOSTNAME="${1:?hostname required as single argument}"
: ${CMD_ON_FAILURE:=unset}
TEMP_FILE="/tmp/${CHECK_HOSTNAME//./_}.md5"
DATETIME_NOW="$(date)"
# exit codes
# 0: check successful, dns did not change
# 1: catch-all failure, something went wrong, missing argument?
# 2: check failed, dns changed
# 3: check failed, nothing to compare to, missing previous check file
# 4: dns resolution failed, do nothing
# 5: cannot write to temp file, do nothing
# 6: failed to run CMD_ON_FAILURE
# caveat:
# if CMD_ON_FAILURE is defined, exit code 3 will not fire,
# instead, exit code of CMD_ON_FAILURE will be returned
verbose() {
[[ ${VERBOSE:-0} == "1" ]] && echo >&2 "[${DATETIME_NOW}]: $@" || true
}
check_record() {
verbose "Getting DNS resolution of \"${CHECK_HOSTNAME}\".."
host ${CHECK_HOSTNAME} | grep -v NXDOMAIN | sort
}
record_md5() {
verbose "Recording MD5 of DNS resolution of \"${CHECK_HOSTNAME}\".."
if ! touch ${TEMP_FILE} 2>/dev/null; then
verbose "Cannot write TEMP_FILE (${TEMP_FILE}), exiting.."
exit 5
fi
echo "$@" | md5sum > ${TEMP_FILE}
}
check_md5() {
verbose "Verifying MD5 of DNS resolution of \"${CHECK_HOSTNAME}\".."
echo "$@" | md5sum --status -c ${TEMP_FILE}
}
run_cmd_on_failure() {
if [[ ${CMD_ON_FAILURE} != "unset" ]]; then
verbose "Executing \"${CMD_ON_FAILURE}\".."
exec -- ${CMD_ON_FAILURE}
fi
}
## do stuff
record_data=$(check_record)
if [ $? -ne 0 ]; then
verbose "DNS resolution failed, bad hostname or timeout? exiting.."
exit 4
fi
if [ -e ${TEMP_FILE} ]; then
if ! check_md5 "${record_data}"; then
verbose "DNS change detected!"
record_md5 "${record_data}"
run_cmd_on_failure
exit 2
else
verbose "DNS remains unchanged!"
exit 0
fi
else
verbose "Nothing to compare with, MD5 file for ${CHECK_HOSTNAME} is not present (\"${TEMP_FILE}\")"
record_md5 "${record_data}"
run_cmd_on_failure
exit 3
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment