+#!/usr/bin/env bash
+
+#
+# check_clamav_signatures - Nagios plugin to monitor ClamAV signatures are up to date.
+#
+# Released under the MIT License.
+#
+# https://github.com/tommarshall/nagios-check-clamav-signatures
+#
+
+VERSION=0.1.0
+OK=0
+WARNING=1
+CRITICAL=2
+UNKNOWN=3
+CLAM_LIB_DIR=/var/lib/clamav
+NUMERICAL_REGEX='^[0-9]+$'
+
+#
+# Output version.
+#
+
+version() {
+ echo "check_clamav_signatures $VERSION"
+}
+
+#
+# Output usage information.
+#
+
+usage() {
+ echo 'Usage: ./check_clamav_signatures [options]'
+}
+
+#
+# Output help information.
+#
+
+help() {
+ usage
+ cat <<-EOF
+
+ Examples:
+ ./check_clamav_signatures
+
+ Options:
+ -p, --path <path> path to ClamAV lib directory, if not $CLAM_LIB_DIR
+ -V, --version output version
+ -h, --help output help information
+
+ For more information, see https://github.com/tommarshall/nagios-check-clamav-signatures
+
+EOF
+}
+
+#
+# Parse argv.
+#
+
+while test $# -ne 0; do
+ ARG=$1; shift
+ case $ARG in
+ -p|--path) CLAM_LIB_DIR=$1; shift ;;
+ -V|--version) version; exit ;;
+ -h|--help) help; exit ;;
+ *)
+ echo "UNKNOWN: Unrecognised argument: $ARG"
+ usage >&2
+ exit $UNKNOWN
+ ;;
+ esac
+done
+
+#
+# Showtime.
+#
+
+# ensure we have executable dependencies
+for dependency in cut host grep sigtool sed; do
+ if ! hash $dependency >/dev/null 2>&1; then
+ echo "UNKNOWN: Missing dependency: ${dependency}"
+ exit $UNKNOWN
+ fi
+done
+
+# ensure the clam lib dir exists
+if [ ! -d "$CLAM_LIB_DIR" ]; then
+ echo "UNKNOWN: Unable to locate ClamAV lib directory"
+ exit $UNKNOWN
+fi
+
+# ensure we have a daily signatures file
+if [ -e ${CLAM_LIB_DIR}/daily.cld ]; then
+ DAILY_SIGNATURES_PATH="${CLAM_LIB_DIR}/daily.cld"
+elif [ -e ${CLAM_LIB_DIR}/daily.cvd ]; then
+ DAILY_SIGNATURES_PATH="${CLAM_LIB_DIR}/daily.cvd"
+else
+ echo "UNKNOWN: Unable to locate installed daily signatures"
+ exit $UNKNOWN
+fi
+
+# ensure we have a main signatures file
+if [ -e ${CLAM_LIB_DIR}/main.cvd ]; then
+ MAIN_SIGNATURES_PATH="${CLAM_LIB_DIR}/main.cvd"
+elif [ -e ${CLAM_LIB_DIR}/main.cld ]; then
+ MAIN_SIGNATURES_PATH="${CLAM_LIB_DIR}/main.cld"
+else
+ echo "UNKNOWN: Unable to locate installed main signatures"
+ exit $UNKNOWN
+fi
+
+# extract the daily signatures version
+INSTALLED_DAILY_VERSION=$(sigtool -i ${DAILY_SIGNATURES_PATH} 2>/dev/null | grep Version | sed -e 's/Version: //')
+if ! [[ $INSTALLED_DAILY_VERSION =~ $NUMERICAL_REGEX ]]; then
+ echo "UNKNOWN: Unable to establish installed daily signatures version"
+ exit $UNKNOWN
+fi
+
+# extract the main signatures version
+INSTALLED_MAIN_VERSION=$(sigtool -i ${MAIN_SIGNATURES_PATH} 2>/dev/null | grep Version | sed -e 's/Version: //')
+if ! [[ $INSTALLED_MAIN_VERSION =~ $NUMERICAL_REGEX ]]; then
+ echo "UNKNOWN: Unable to establish installed main signatures version"
+ exit $UNKNOWN
+fi
+
+# query the DNS record
+DNS_TXT_RECORD=$(host -t txt current.cvd.clamav.net)
+if [ $? -ne 0 ]; then
+ echo "UNKNOWN: DNS query to current.cvd.clamav.net failed"
+ exit $UNKNOWN
+fi
+
+# extract the current daily signatures version from the DNS TXT record
+CURRENT_DAILY_VERSION=$(echo $DNS_TXT_RECORD | cut -d : -f 3)
+if ! [[ $CURRENT_DAILY_VERSION =~ $NUMERICAL_REGEX ]]; then
+ echo "UNKNOWN: Unable to establish current daily signatures version from DNS query"
+ exit $UNKNOWN
+fi
+
+# extract the current main signatures version from the DNS TXT record
+CURRENT_MAIN_VERSION=$(echo $DNS_TXT_RECORD | cut -d : -f 2)
+if ! [[ $CURRENT_MAIN_VERSION =~ $NUMERICAL_REGEX ]]; then
+ echo "UNKNOWN: Unable to establish current main signatures version from DNS query"
+ exit $UNKNOWN
+fi
+
+# determine the difference between the current and installed versions
+DAILY_VERSION_DELTA=$((CURRENT_DAILY_VERSION-INSTALLED_DAILY_VERSION))
+MAIN_VERSION_DELTA=$((CURRENT_MAIN_VERSION-INSTALLED_MAIN_VERSION))
+
+if [ $DAILY_VERSION_DELTA -gt 0 -o $MAIN_VERSION_DELTA -gt 0 ]; then
+ echo "CRITICAL: Signatures expired;" \
+ "daily version: ${INSTALLED_DAILY_VERSION} (${DAILY_VERSION_DELTA} behind)," \
+ "main version: ${INSTALLED_MAIN_VERSION} (${MAIN_VERSION_DELTA} behind)"
+ exit $CRITICAL
+fi
+
+echo "OK: Signatures up to date;"\
+ "daily version: ${INSTALLED_DAILY_VERSION}," \
+ "main version: ${INSTALLED_MAIN_VERSION}"
+exit $OK