Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / ssl / ssl-certificate-expiry @ 793b75b9

Historique | Voir | Annoter | Télécharger (4,1 ko)

1 59f057f8 Olivier Mehani
#!/bin/sh -u
2 a4c30808 Olivier Mehani
# -*- sh -*-
3 793b75b9 Olivier Mehani
# shellcheck disable=SC2039
4 a4c30808 Olivier Mehani
5
: << =cut
6
7
=head1 NAME
8
9 59f057f8 Olivier Mehani
ssl-certificate-expiry - Plugin to monitor Certificate expiration on multiple services and ports
10 a4c30808 Olivier Mehani
11
=head1 CONFIGURATION
12
13 81e19668 Olivier Mehani
  [ssl-certificate-expiry]
14 33239697 Olivier Mehani
    env.services www.service.tld blah.example.net_PORT
15 a4c30808 Olivier Mehani
16
To set warning and critical levels do like this:
17
18 81e19668 Olivier Mehani
  [ssl-certificate-expiry]
19 a4c30808 Olivier Mehani
    env.services ...
20
    env.warning 30:
21
22 47ef2182 Olivier Mehani
Alternatively, if you want to monitor hosts separately, you can create multiple symlinks named as follows.
23
24 81e19668 Olivier Mehani
  ssl-certificate-expiry_HOST_PORT
25 47ef2182 Olivier Mehani
26
For example:
27
28 81e19668 Olivier Mehani
  ssl-certificate-expiry_www.example.net
29
  ssl-certificate-expiry_www.example.org_443
30
  ssl-certificate-expiry_192.0.2.42_636
31
  ssl-certificate-expiry_2001:0DB8::badc:0fee_485
32 47ef2182 Olivier Mehani
33 59f057f8 Olivier Mehani
=head2 Cron setup
34 a4c30808 Olivier Mehani
35 59f057f8 Olivier Mehani
To avoid having to run the SSL checks during the munin-update, it is possible
36
to run it from cron, and save a cachefile to be read during the update, This is
37
particularly useful when checking a large number of certificates, or when some
38
of the hosts are slow.
39 a4c30808 Olivier Mehani
40 59f057f8 Olivier Mehani
To do so, add a cron job running the plugin with cron as the argument:
41
42
   */5 * * * * <user> /usr/sbin/munin-run/ssl-certificate-expiry cron
43
44
<user> should be the user that has write permission to the MUNIN_PLUGSTATE.
45
46
=head1 AUTHORS
47
48
 * Pactrick Domack (ssl_)
49
 * Olivier Mehani (ssl-certificate-expiry)
50
51
 * Copyright (C) 2013 Patrick Domack <patrickdk@patrickdk.com>
52
 * Copyright (C) 2017, 2019 Olivier Mehani <shtrom+munin@ssji.net>
53 a4c30808 Olivier Mehani
54
=head1 LICENSE
55
56
=cut
57
58 e7eb2886 Lars Kruse
# shellcheck disable=SC1090
59 a4c30808 Olivier Mehani
. "${MUNIN_LIBDIR}/plugins/plugin.sh"
60
61 59f057f8 Olivier Mehani
if [ "${MUNIN_DEBUG:-0}" = 1 ]; then
62 a4c30808 Olivier Mehani
    set -x
63
fi
64
65 81e19668 Olivier Mehani
HOSTPORT=${0##*ssl-certificate-expiry_}
66 59f057f8 Olivier Mehani
CACHEFILE="${MUNIN_PLUGSTATE}/$(basename "${0}").cache"
67 47ef2182 Olivier Mehani
68
if [ "${HOSTPORT}" != "${0}" ] \
69
	&& [ ! -z "${HOSTPORT}" ]; then
70
	services="${HOSTPORT}"
71
fi
72
73 e7eb2886 Lars Kruse
74
# Read data including a certificate from stdin and output the (fractional) number of days left
75
# until the expiry of this certificate. The output is empty if parsing failed.
76
parse_valid_days_from_certificate() {
77 793b75b9 Olivier Mehani
    local input_data
78
    local valid_until_string
79
    local valid_until_epoch
80
    local now_epoch
81
    local input_data
82 e7eb2886 Lars Kruse
    input_data=$(cat)
83
    if echo "$input_data" | grep -q -- "-----BEGIN CERTIFICATE-----"; then
84
        valid_until_string=$(echo "$input_data" | openssl x509 -noout -enddate \
85
            | grep "^notAfter=" | cut -f 2 -d "=")
86
        if [ -n "$valid_until_string" ]; then
87
            valid_until_epoch=$(date --date="$valid_until_string" +%s)
88
            if [ -n "$valid_until_epoch" ]; then
89
                now_epoch=$(date +%s)
90
                # calculate the number of days left
91
                echo "$valid_until_epoch" "$now_epoch" | awk '{ print(($1 - $2) / (24 * 3600)); }'
92
            fi
93
        fi
94
    fi
95
}
96
97
98
print_expire_days() {
99 793b75b9 Olivier Mehani
    local host="$1"
100
    local port="$2"
101 e7eb2886 Lars Kruse
102
    # Wrap IPv6 addresses in square brackets
103
    echo "$host" | grep -q ':' && host="[$host]"
104
105
    echo "" | openssl s_client -CApath /etc/ssl/certs \
106
            -servername "$host" -connect "${host}:${port}" 2>/dev/null \
107
        | parse_valid_days_from_certificate
108
}
109
110 59f057f8 Olivier Mehani
main() {
111
    for service in $services; do
112
	if echo "$service" | grep -q "_"; then
113
	    host=$(echo "$service" | cut -f 1 -d "_")
114
	    port=$(echo "$service" | cut -f 2 -d "_")
115
	else
116
	    host=$service
117
	    port=443
118
	fi
119
	fieldname="$(clean_fieldname "$service")"
120
	valid_days=$(print_expire_days "$host" "$port")
121
	[ -z "$valid_days" ] && valid_days="U"
122
	printf "%s.value %s\\n" "$fieldname" "$valid_days"
123
    done
124
}
125 e7eb2886 Lars Kruse
126 59f057f8 Olivier Mehani
case ${1:-} in
127 a4c30808 Olivier Mehani
    config)
128
	echo "graph_title SSL Certificates Expiration"
129
	echo 'graph_args --base 1000'
130
	echo 'graph_vlabel days left'
131
	echo 'graph_category security'
132 59f057f8 Olivier Mehani
	echo "graph_info This graph shows the numbers of days before certificate expiry"
133 a4c30808 Olivier Mehani
	for service in $services; do
134
	    fieldname=$(clean_fieldname "$service")
135 47ef2182 Olivier Mehani
	    echo "${fieldname}.label $(echo "${service}" | sed 's/_/:/')"
136 59f057f8 Olivier Mehani
	    print_thresholds "${fieldname}" warning critical
137 a4c30808 Olivier Mehani
	done
138
139
	exit 0
140
	;;
141 59f057f8 Olivier Mehani
    cron)
142
	TMP=$(mktemp "${CACHEFILE}.XXXXXXXX")
143
	trap 'rm -f "${TMP}"' EXIT
144
	main > "${TMP}"
145
	chmod 0644 "${TMP}"
146
	mv "${TMP}" "${CACHEFILE}"
147
148
	exit 0
149
	;;
150 a4c30808 Olivier Mehani
esac
151
152 59f057f8 Olivier Mehani
if [ -e "${CACHEFILE}" ]; then
153
	cat "${CACHEFILE}"
154
	rm "${CACHEFILE}"
155
	exit 0
156
fi
157 a4c30808 Olivier Mehani
158 59f057f8 Olivier Mehani
main