#!/bin/sh : << =cut =head1 NAME certificate_file_expiry - check the certificate validity of your certificates = head1 CONFIGURATION Installing: Add list of your certificates prefixed by the type in munin plugin-conf.d For openvpn ca.crt and crl.pem [certificate_file_expiry] user root env.CERTS crl:/etc/openvpn/easy-rsa/keys/crl.pem x509:/etc/openvpn/easy-rsa/keys/ca.crt env.LOGARITHMIC yes For openvpn inline and certificates, as described here https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage#lbAV [certificate_file_expiry] user root env.CERTS openvpn_inline:/etc/openvpn/client.conf env.LOGARITHMIC yes For letsencrypt certificates [certificate_file_expiry] user root env.CERTS x509:/etc/letsencrypt/live/*/cert.pem Warning and Critical levels can also be configured with env variables like this: [certificate_file_expiry] ... # warn when certificate will be invalid within 5 days env.warning 5: # for this certificate warn us 10 days before because it takes longer to renew env._etc_letsencrypt_live_example_com_cert_pem_warning 10: # critical when certificate will be invalid within 1 day env.critical 1: env.CERTS should be a space separated list of patterns prefixed by the type of certificate to check and a colon. All types of certificates that openssl supports as standard commands and have a validity output are supported (e.g. x509, crl). A special type is openvpn_inline where the plugin gets the certificates directly from the openvpn conf file in between the \n...\n and \n...\n lines and checks those with openssl x509. File patterns can be a single file (e.g. /etc/openvpn/easy-rsa/keys/crl.pem) or a pattern that matches multiple files (e.g. /etc/letsencrypt/live/*/cert.pem). env.warning and env.critical are configurable values for the warning and critical levels according to http://guide.munin-monitoring.org/en/latest/tutorial/alert.html?highlight=warning#syntax-of-warning-and-critical env.LOGARITHMIC "yes" enables the logarithmic display of values which is useful if some of your certs are relatively long lived in respect to the warning level. e.g. a ca.crt that is valid for 10 years together with a crl.pem that is valid for only a few months combined with warning levels of 5 days. default is "yes" to disable set it to "no". =head1 Dependencies Dependencies: openssl =head1 AUTHOR andreas perhab - andreas.perhab@wt-io-it.at (https://www.wt-io-it.at/) =head1 LICENSE GPLv2 =cut . "$MUNIN_LIBDIR/plugins/plugin.sh" LOGARITHMIC=${LOGARITHMIC:-yes} if [ "$1" = "config" ] ; then echo "graph_title Certificate validity" if [ "$LOGARITHMIC" = "yes" ] ; then graph_args="--logarithmic --units=si" fi echo "graph_args --base 1000 $graph_args" echo "graph_vlabel days" echo "graph_category security" fi # by default when certificate is only valid for 5 days or less emit a warning warning=${warning:-5:} # by default when certificate is only valid for 1 day or less emit a critical critical=${critical:-1:} now=$(date +%s) get_validity() { local file local openssl_type local validity_line local validity_str_value local validity_timestamp local validity_seconds openssl_type=$1 file=$2 if [ "$file" != "-" ] ; then validity_line=$(/usr/bin/openssl "$openssl_type" -text -noout -in "$file" | grep -E '(Next Update|Not After)') else # when file is set to -- read from stdin validity_line=$(/usr/bin/openssl "$openssl_type" -text -noout | grep -E '(Next Update|Not After)') fi validity_str_value=${validity_line#*:} validity_timestamp=$(date --date="$validity_str_value" +%s) validity_seconds=$((validity_timestamp - now)) echo "$validity_seconds" | awk '{ print ($1 / 86400) }' } print_config_lines() { name=$1 label=$2 echo "${name}.label ${label}" print_warning "$name" print_critical "$name" } get_openvpn_inline_cert() { file=$1 type=$2 # print content between and lines (ca and cert) awk 'BEGIN{content=0}/^<\/'"$type"'>$/{content=0}(content==1){ print $0 }/^<'"$type"'>$/{content=1}' < "$file" } for cert in ${CERTS}; do cert_type=${cert%:*} cert_pattern=${cert#*:} for cert_file in $cert_pattern; do if [ "$cert_type" = "openvpn_inline" ] ; then for type in "ca" "cert"; do cert_name=$(clean_fieldname "$cert_file-$type") if [ "$1" = "config" ] ; then print_config_lines "$cert_name" "${cert_file} ${type}" elif [ "$1" = "" ] ; then echo "${cert_name}.value $(get_openvpn_inline_cert "$cert_file" "$type" | get_validity "x509" "-")" fi done else cert_name=$(clean_fieldname "$cert_file") if [ "$1" = "config" ] ; then print_config_lines "$cert_name" "${cert_file}" elif [ "$1" = "" ] ; then echo "${cert_name}.value $(get_validity "$cert_type" "$cert_file")" fi fi done done