1
0
Fork 0
scripts-admin-quickndirty-p.../nagios/check_whois
Chl 142d136d11 nagios: check_whois handles more TLD
.ru, .jp, .it + a fix for handling .fr answers.
2023-10-04 23:35:50 +02:00

227 lines
5.1 KiB
Bash
Executable file

#!/bin/sh
# Little custom script to check expiration date of DNS domains
# Default values
#RANGE_WARNING=":2592000" # 30 days
#RANGE_CRITICAL=":691200" # 8 days
THRESHOLD_WARNING="2592000" # 30 days
THRESHOLD_CRITICAL="691200" # 8 days
TIMESTAMP_NOW="$( date +%s )"
# Output
OUTPUT_EXIT_STATUS=0
OUTPUT_DETAIL_WARNING=""
OUTPUT_DETAIL_CRITICAL=""
OUTPUT_PERFDATA=""
PROGPATH=$( echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,' )
REVISION="0.1"
# Stop at the first non-catched error
set -e
# Include check_range()
. $PROGPATH/utils.sh
# No real need for this script but then you have to copy the status
# Not really clean...
#STATE_OK=0
#STATE_WARNING=1
#STATE_CRITICAL=2
#STATE_UNKNOWN=3
#STATE_DEPENDENT=4
#
# Help function
#
usage() {
cat <<EOF
Usage :
$0 [-w warning_threshold] [-c critical_threshold] domain1 [domain2] ...
Thresholds in seconds (or suffix by 'd' for days).
Default values:
warning_threshold : $THRESHOLD_WARNING
critical_threshold : $THRESHOLD_CRITICAL
EOF
}
#
# Days/Months/Hours to seconds convert function
#
convert_to_seconds() {
local UNIT VALUE
UNIT="$( echo "$1" | sed 's/.*\(.\)$/\1/;q' )"
VALUE="$( echo "$1" | sed 's/^\([0-9]*\).*/\1/;q' )"
case "$UNIT" in
'd')
# Unit is days
echo "$( expr "$VALUE" \* 86400 )"
;;
*)
echo "$1"
;;
esac
}
#
# Check if arg is an integer
# (copied from jilles @ http://stackoverflow.com/questions/806906/how-do-i-test-if-a-variable-is-a-number-in-bash )
#
is_int() {
case "$1" in
''|*[!0-9]*) return 1;;
*) return 0;;
esac
}
#
# Extract the date fs a timestamp rom the whois response
# (print 1 line max.)
# (exit status = 1 if problem)
#
extract_date_from_whois() {
local EXPIRATION_DATE
# We put each format on a dedicated line
# + filter only the first line
# Note : some sed implementations seems not to offer
# case-insensitive option, so we try not to
# use it for the moment.
# 1 - kernel.org, icann.org
# 2 - coca-cola.com (we try to ignore lines starting with space...)
# 3 - facebook.com (...but if there's nothing else, take it anyway)
# 4 - some databases with simple display (.se, .si)
# 5 - .it
# 6 - .ru
# 7 - .jp
# Add your own filter here :)
EXPIRATION_DATE="$( sed -n \
-e 's/^Registry Expiry Date: //p' \
-e '/^[^[:space:]]/s/.*\(xpiry\|xpiration\) Date:[[:space:]]\+//p' \
-e 's/.*\(xpiry\|xpiration\) Date:[[:space:]]\+//p' \
-e 's/^expires\?:[[:space:]]*//p' \
-e 's/^Expire Date:[[:space:]]*//p' \
-e 's/^paid-till:[[:space:]]*//p' \
-e 's/^\[Expires on\][[:space:]]*//p' \
| sed 'q'
)"
# Small protection against injection
if [ -n "$( echo "$EXPIRATION_DATE" | LANG=C sed -n '/^[a-zA-Z0-9:.\-]\{1,64\}$/p' )" ]; then
date --date="$EXPIRATION_DATE" +%s
fi
}
# Some early checks
if ! which whois >/dev/null 2>&1; then
echo "UNKNOWN: 'whois' command not found."
exit 1
fi
#
# Parameters management
#
while [ "$#" -gt 0 ]; do
while getopts hw:c: f; do
case "$f" in
'h')
usage
exit
;;
'w')
THRESHOLD_WARNING="$( convert_to_seconds "$OPTARG" )"
;;
'c')
THRESHOLD_CRITICAL="$( convert_to_seconds "$OPTARG" )"
;;
\?)
usage
exit 1
;;
esac
done
shift $( expr $OPTIND - 1 )
# Little checks
if ! is_int "$THRESHOLD_WARNING" || ! is_int "$THRESHOLD_CRITICAL"; then
echo "UNKNOWN invalid parameter : one of the threshold is not an integer."
exit $STATE_UNKNOWN
fi
# End of the options, we get the domain name
if [ -z "$1" ]; then
# No more options but no domain specified ? Weird but well...
break
fi
DOMAIN="$1"
shift
# get the expiration date for this domain
test -n "$EXPIRATION_DATE" && sleep 2 # trying not to flood the whois servers
EXPIRATION_DATE="$( whois "$DOMAIN" | extract_date_from_whois )"
if [ -z "$EXPIRATION_DATE" ]; then
# We couldn't get the date :-(
if [ "$OUTPUT_EXIT_STATUS" -eq "$STATE_OK" ]; then
OUTPUT_EXIT_STATUS="$STATE_UNKNOWN"
fi
OUTPUT_DETAIL_UNKNOWN="$OUTPUT_DETAIL_UNKNOWN $DOMAIN:could_not_get_date"
break
fi
# Dispatch in the OK/Warning/Critical boxes
OUTPUT_DOMAIN_DETAIL="$DOMAIN:$( date --date=@$EXPIRATION_DATE +%FT%T%z)"
if [ "$EXPIRATION_DATE" -le "$( expr "$TIMESTAMP_NOW" + "$THRESHOLD_CRITICAL" )" ]; then
# Domain is critical
OUTPUT_EXIT_STATUS="$STATE_CRITICAL"
OUTPUT_DETAIL_CRITICAL="$OUTPUT_DETAIL_CRITICAL $OUTPUT_DOMAIN_DETAIL"
elif [ "$EXPIRATION_DATE" -le "$( expr "$TIMESTAMP_NOW" + "$THRESHOLD_WARNING" )" ]; then
# Domain is warning
OUTPUT_DETAIL_WARNING="$OUTPUT_DETAIL_WARNING $OUTPUT_DOMAIN_DETAIL"
# we don't change if the status is already Critical
# (but we take precedence over Unknown)
if [ "$OUTPUT_EXIT_STATUS" -ne "$STATE_CRITICAL" ]; then
OUTPUT_EXIT_STATUS="$STATE_WARNING"
fi
else
# Domain is Ok
OUTPUT_DETAIL_OK="$OUTPUT_DETAIL_OK $OUTPUT_DOMAIN_DETAIL"
fi
done
# final output
case "$OUTPUT_EXIT_STATUS" in
"$STATE_OK")
echo "OK $OUTPUT_DETAIL_OK"
;;
"$STATE_WARNING")
echo "WARNING $OUTPUT_DETAIL_WARNING"
;;
"$STATE_CRITICAL")
echo "CRITICAL $OUTPUT_DETAIL_CRITICAL"
;;
"$STATE_UNKNOWN")
echo "UNKNOWN $OUTPUT_DETAIL_UNKNOWN"
;;
*)
echo "WTF"
;;
esac
exit "$OUTPUT_EXIT_STATUS"