Merge pull request #1293 from ap-wtioit/master-improve_certificate_file_expiry_github

certificate_file_expiry: enable monitoring inline openvpn certificates
This commit is contained in:
Lars Kruse 2022-02-26 23:12:09 +01:00 committed by GitHub
commit a92de3b8dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 82 additions and 14 deletions

View File

@ -15,6 +15,14 @@ For openvpn ca.crt and crl.pem
env.CERTS crl:/etc/openvpn/easy-rsa/keys/crl.pem x509:/etc/openvpn/easy-rsa/keys/ca.crt
env.LOGARITHMIC yes
For openvpn inline <ca> and <cert> 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]
@ -32,8 +40,11 @@ Warning and Critical levels can also be configured with env variables like this:
# 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).
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 <ca>\n...\n</ca> and <cert>\n...\n</cert> 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).
@ -44,6 +55,9 @@ env.LOGARITHMIC "yes" enables the logarithmic display of values which is useful
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".
env.IGNORE_UNEXPANDED_PATTERNS "yes" ignores patterns that did not expand to any files. this is useful to define one
config that handles multiple types of certs where only one pattern is used. default is "no".
=head1 Dependencies
Dependencies: openssl
@ -61,6 +75,7 @@ GPLv2
. "$MUNIN_LIBDIR/plugins/plugin.sh"
LOGARITHMIC=${LOGARITHMIC:-yes}
IGNORE_UNEXPANDED_PATTERNS=${IGNORE_UNEXPANDED_PATTERNS:-no}
if [ "$1" = "config" ] ; then
echo "graph_title Certificate validity"
@ -72,23 +87,76 @@ if [ "$1" = "config" ] ; then
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 <type> and </type> 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
cert_name=$(clean_fieldname "$cert_file")
if [ "$1" = "config" ] ; then
echo "${cert_name}.label ${cert_file}"
print_warning "$cert_name"
print_critical "$cert_name"
elif [ "$1" = "" ] ; then
validity=$(/usr/bin/openssl "$cert_type" -text -noout -in "$cert_file" | grep -E '(Next Update|Not After)')
validity=${validity#*:}
validity=$(date --date="$validity" +%s)
validity=$((validity - now))
validity=$(echo "$validity" | awk '{ print ($1 / 86400) }')
echo "${cert_name}.value $validity"
# note: if file contains a * (e.g. /etc/letsencrypt/live/*/cert.pem) it might be an unexpanded pattern
# to supress errors see IGNORE_UNEXPANDED_PATTERNS above
# shellcheck disable=SC2063
if [ "$IGNORE_UNEXPANDED_PATTERNS" = "yes" ] \
&& [ "$cert_file" = "$cert_pattern" ] \
&& ! [ -e "$cert_file" ] \
&& echo "$cert_file" | grep -q "*" ; then
# skip unexpanded patterns when IGNORE_UNEXPANDED_PATTERNS is set to yes
continue
fi
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