From f0479a9a7debfd317c969bac2743ac986929b324 Mon Sep 17 00:00:00 2001 From: Nazdravi Date: Sat, 31 Oct 2020 23:41:06 +0100 Subject: [PATCH] [ssl-certificate-expiry] host name verification + proxy connection (#1126) * optional verification of request to certificate hostname match (env.checkname yes) * optional openssl proxy usage (env.proxy PROXYHOST:PORT) --- plugins/ssl/ssl-certificate-expiry | 31 ++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/plugins/ssl/ssl-certificate-expiry b/plugins/ssl/ssl-certificate-expiry index 41f6fce3..8a1d1b31 100755 --- a/plugins/ssl/ssl-certificate-expiry +++ b/plugins/ssl/ssl-certificate-expiry @@ -23,6 +23,8 @@ To set warning and critical levels do like this: [ssl-certificate-expiry] env.services ... env.warning 30: + env.proxy PROXYHOST:PORT # optional, enables openssl operation over proxy + env.checkname yes # optional, checks if used servername is covered by certificate Alternatively, if you want to monitor hosts separately, you can create multiple symlinks named as follows. @@ -58,6 +60,7 @@ uncached updates after the cache file is older than an hour. * Pactrick Domack (ssl_) * Olivier Mehani (ssl-certificate-expiry) * Martin Schobert (check for intermediate certs) + * Arndt Kritzner (hostname verification and proxy usage) * Copyright (C) 2013 Patrick Domack * Copyright (C) 2017, 2019 Olivier Mehani @@ -122,8 +125,10 @@ print_expire_days() { # Wrap IPv6 addresses in square brackets echo "$host" | grep -q ':' && host="[$host]" - local s_client_args= - [ -n "$starttls" ] && s_client_args="-starttls $starttls" + local s_client_args='' + [ -n "$starttls" ] && s_client_args="$s_client_args -starttls $starttls" + [ -n "${proxy:-}" ] && s_client_args="$s_client_args -proxy $proxy" + [ -n "${checkname:-}" ] && [ "$checkname" = "yes" ] && s_client_args="$s_client_args -verify_hostname $host" # We extract and check the server certificate, # but the end date also depends on intermediate certs. Therefore @@ -138,11 +143,16 @@ print_expire_days() { # - get a list of the parse_valid_days_from_certificate # results and sort them + local openssl_call + local openssl_response # shellcheck disable=SC2086 - echo "" | openssl s_client \ - -servername "$host" -connect "${host}:${port}" \ - -showcerts \ - $s_client_args 2>/dev/null | \ + openssl_call="s_client -servername $host -connect ${host}:${port} -showcerts $s_client_args" + # shellcheck disable=SC2086 + openssl_response=$(echo "" | openssl ${openssl_call} 2>/dev/null) + if echo "$openssl_response" | grep -qi "Hostname mismatch"; then + echo "<>" + else + echo "$openssl_response" | \ awk '{ if ($0 == "-----BEGIN CERTIFICATE-----") cert="" else if ($0 == "-----END CERTIFICATE-----") print cert @@ -152,7 +162,7 @@ print_expire_days() { (printf '\n-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n' "$CERT") | \ parse_valid_days_from_certificate done | sort -n | head -n 1 - + fi } main() { @@ -168,9 +178,14 @@ main() { fi fieldname="$(clean_fieldname "$service")" valid_days=$(print_expire_days "$host" "$port" "$starttls") + extinfo="" [ -z "$valid_days" ] && valid_days="U" + if [ "$valid_days" = "<>" ]; then + extinfo="Error: hostname mismatch, " + valid_days="-1" + fi printf "%s.value %s\\n" "$fieldname" "$valid_days" - echo "${fieldname}.extinfo Last checked: $(date)" + echo "${fieldname}.extinfo ${extinfo}Last checked: $(date)" done }