#!/bin/sh # shellcheck shell=dash # -*- sh -*- : << =cut =head1 NAME whois - Plugin to monitor expiry dates of domains in the WHOIS database Though the plugin will be called every 5 minutes, it will keep a cache, and only query the WHOIS database C minutes. =head1 CONFIGURATION First, create a section in your munin-node configuration files. The domain envvar is mandatory, others are optional. Optionally, a specific WHOIS server to query for a given domain can be specified with the @WHOIS_SERVER suffix [whois] env.domains example.com example.org@whois.example.net env.extract_re s/PATTERN/REPL/ env.warning_days env.critical_days env.cache_expiry_mins C is a space-separated list of domains to be checked. The C will be used in C to extract the relevant expiry date. It default to C. Only lines for which a replacement has happened will be considered, and the pattern should take care to only output one line. While the default RegExp just finds a leader pattern and removes it, it is possible to write more complex logic to format the date. The extracted date needs to be in a format supported by C's C<--date> parameter. Then create a symlink to enable this plugin: ln -s /path/to/whois /etc/munin/plugins/ =head1 AUTHOR Olivier Mehani Copyright (C) 2020,2021 Olivier Mehani =head1 LICENSE SPDX-License-Identifier: GPL-3.0-or-later =head1 MAGIC MARKERS #%# family=manual =cut set -eu # shellcheck disable=SC1091 . "${MUNIN_LIBDIR}/plugins/plugin.sh" if [ "${MUNIN_DEBUG:-0}" = 1 ]; then set -x fi DOMAINS=${domains:-""} EXTRACT_RE=${extract_re:-'s/^.*[Ee]xpir.*: //'} WARNING=${warning_days:-7} CRITICAL=${critical_days:-3} CACHE_EXPIRY=${cache_expiry_mins:-60} # Args: domain name (optional, for title) graph_config() { cat << EOF graph_title Domain registration expiry graph_category network graph_vlabel days graph_args --units-exponent 0 EOF } # Args: domain name # Separated from graph_config so we can easily extend the plugin to support multiple domains. config() { local NAME local FIELDNAME for NAME in $DOMAINS do NAME="$(echo "${NAME}" | cut -d @ -f 1)" FIELDNAME="$(clean_fieldname "${NAME}")" cat << EOF ${FIELDNAME}.label ${NAME} ${FIELDNAME}.cdef ${FIELDNAME},86400,/ ${FIELDNAME}.warning ${WARNING}: ${FIELDNAME}.critical ${CRITICAL}: EOF done } # Args: domain name fetch() { local NAME local SERVER local FIELDNAME local CACHEFILE for NAME in $DOMAINS do SERVER='' if echo "${NAME}" | grep -q '@'; then SERVER="$(echo "${NAME}" | cut -d @ -f 2)" NAME="$(echo "${NAME}" | cut -d @ -f 1)" fi FIELDNAME="$(clean_fieldname "${NAME}")" CACHEFILE="${MUNIN_PLUGSTATE}/$(basename "${0}").${FIELDNAME}.cache" if [ -z "$(find "${CACHEFILE}" -mmin -"${CACHE_EXPIRY}" 2>/dev/null)" ]; then EXPIRY="$(whois "${NAME}" "${SERVER:+-h${SERVER}}" 2>/dev/null | sed -n "${EXTRACT_RE}p;T;q")" # T;q exits after printing the first match DELTA_TS=U if [ -n "${EXPIRY}" ]; then EXPIRY_TS="$(date +%s -d "${EXPIRY}")" NOW_TS="$(date +%s)" DELTA_TS=$((EXPIRY_TS-NOW_TS)) fi echo "${FIELDNAME}.value ${DELTA_TS}" > "${CACHEFILE}" fi cat "${CACHEFILE}" done } main() { local MODE="${1:-}" case "${MODE}" in 'config') graph_config config ;; *) fetch ;; esac } main "$@"