root / plugins / ssl / certbot_certs @ 2f7d9407
Historique | Voir | Annoter | Télécharger (3,89 ko)
| 1 |
#!/usr/bin/perl |
|---|---|
| 2 |
# -*- perl -*- |
| 3 |
|
| 4 |
=encoding utf8 |
| 5 |
|
| 6 |
=head1 NAME |
| 7 |
|
| 8 |
certbot_certs - Munin plugin to certbot (letsencrypt) certificate expiry |
| 9 |
|
| 10 |
=head1 APPLICABLE SYSTEMS |
| 11 |
|
| 12 |
Servers running certbot certificates. This script auto-discovers the current set of certificates |
| 13 |
|
| 14 |
=head1 CONFIGURATION |
| 15 |
|
| 16 |
This script requires root permissions to run, in your munin-node configuration: |
| 17 |
|
| 18 |
[certbot_certs] |
| 19 |
user root |
| 20 |
|
| 21 |
=head1 CAPABILITIES |
| 22 |
|
| 23 |
This plugin supports L<DIRTYCONFIG|http://guide.munin-monitoring.org/en/latest/plugin/protocol-dirtyconfig.html> |
| 24 |
|
| 25 |
=head1 LICENSE |
| 26 |
|
| 27 |
Copyright (C) 2018 J.T.Sage (jtsage@gmail.com) |
| 28 |
|
| 29 |
This program is free software: you can redistribute it and/or modify |
| 30 |
it under the terms of the GNU General Public License as published by |
| 31 |
the Free Software Foundation, either version 3 of the License, or |
| 32 |
any later version. |
| 33 |
|
| 34 |
This program is distributed in the hope that it will be useful, |
| 35 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 36 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 37 |
GNU General Public License for more details. |
| 38 |
|
| 39 |
You should have received a copy of the GNU General Public License |
| 40 |
along with this program. If not, see L<http://www.gnu.org/licenses/>. |
| 41 |
|
| 42 |
=head1 MAGIC MARKERS |
| 43 |
|
| 44 |
#%# family=manual |
| 45 |
#%# capabilities= |
| 46 |
|
| 47 |
=cut |
| 48 |
|
| 49 |
use warnings; |
| 50 |
use strict; |
| 51 |
use Munin::Plugin; |
| 52 |
use Date::Parse; |
| 53 |
use POSIX; |
| 54 |
|
| 55 |
if ( defined($ARGV[0]) && $ARGV[0] eq "autoconf" ) {
|
| 56 |
if ( -e "/usr/bin/openssl" ) {
|
| 57 |
print "no (Root User Required)\n"; |
| 58 |
} else {
|
| 59 |
print "no (OpenSSL Not Found)\n"; |
| 60 |
} |
| 61 |
exit; |
| 62 |
} |
| 63 |
|
| 64 |
|
| 65 |
my %thecerts = get_data(); |
| 66 |
|
| 67 |
|
| 68 |
if ( defined($ARGV[0]) && $ARGV[0] eq "config" ) {
|
| 69 |
# Do the config step for each set of graphs |
| 70 |
do_config(%thecerts); |
| 71 |
|
| 72 |
# If dirtyconfig is not supported, or turned off, exit here. Otherwise, continue to fetch section |
| 73 |
if ( !defined($ENV{'MUNIN_CAP_DIRTYCONFIG'}) || !$ENV{'MUNIN_CAP_DIRTYCONFIG'} ) { exit 0; }
|
| 74 |
} |
| 75 |
|
| 76 |
# Do the fetch step for each set of graphs |
| 77 |
do_values(%thecerts); |
| 78 |
|
| 79 |
|
| 80 |
|
| 81 |
sub do_config {
|
| 82 |
print "graph_title LetsEncrypt Certificate Expiry\n"; |
| 83 |
print "graph_args --upper-limit 90 -l 0\n"; |
| 84 |
print "graph_vlabel days\n"; |
| 85 |
print "graph_category security\n"; |
| 86 |
print "graph_info This graph shows the number of days until certificate expiry\n"; |
| 87 |
|
| 88 |
my ( %certs ) = @_; |
| 89 |
|
| 90 |
foreach my $key ( keys %certs ) {
|
| 91 |
print $certs{$key}{"safename"} . ".label " . $certs{$key}{"name"} . "\n";
|
| 92 |
print $certs{$key}{"safename"} . ".info " . $certs{$key}{"info"} . "\n";
|
| 93 |
print $certs{$key}{"safename"} . ".warning 29:\n";
|
| 94 |
print $certs{$key}{"safename"} . ".critical 15:\n";
|
| 95 |
} |
| 96 |
} |
| 97 |
|
| 98 |
sub do_values {
|
| 99 |
my ( %certs ) = @_; |
| 100 |
|
| 101 |
foreach my $key ( keys %certs ) {
|
| 102 |
print $certs{$key}{"safename"} . ".value " . $certs{$key}{"expdays"} . "\n";
|
| 103 |
} |
| 104 |
} |
| 105 |
|
| 106 |
sub get_data {
|
| 107 |
my $runtime = time(); |
| 108 |
my %cert_files; |
| 109 |
# Get Renewal Files |
| 110 |
opendir(DIR, "/etc/letsencrypt/renewal"); |
| 111 |
my @renew_files = grep(/\.conf$/,readdir(DIR)); |
| 112 |
closedir(DIR); |
| 113 |
|
| 114 |
# Each renewal file |
| 115 |
foreach my $file (@renew_files) {
|
| 116 |
my @this_renew = `cat /etc/letsencrypt/renewal/$file`; |
| 117 |
|
| 118 |
my $cert_name = $file; |
| 119 |
$cert_name =~ s/\.conf//; |
| 120 |
|
| 121 |
my $safe_name = $cert_name; |
| 122 |
$safe_name =~ s/\./_/g; |
| 123 |
|
| 124 |
|
| 125 |
$cert_files{$cert_name}{"name"} = $cert_name;
|
| 126 |
$cert_files{$cert_name}{"safename"} = $safe_name;
|
| 127 |
|
| 128 |
# cert is listed |
| 129 |
foreach my $line ( @this_renew ) {
|
| 130 |
if ( $line =~ /cert = (.+?)$/ ) {
|
| 131 |
$cert_files{$cert_name}{"cert"} = $1;
|
| 132 |
} |
| 133 |
} |
| 134 |
|
| 135 |
# use openssl for the info |
| 136 |
my @ssl_info = `openssl x509 -noout -in $cert_files{$cert_name}{"cert"} -text -certopt no_subject,no_header,no_version,no_serial,no_signame,no_validity,no_issuer,no_pubkey,no_sigdump,no_aux -enddate`;
|
| 137 |
|
| 138 |
# parse for SAN and expiry |
| 139 |
foreach my $line ( @ssl_info ) {
|
| 140 |
if ( $line =~ /notAfter=(.+?)$/ ) {
|
| 141 |
$cert_files{$cert_name}{"expdate"} = $1;
|
| 142 |
$cert_files{$cert_name}{"expdays"} = floor((str2time($1) - $runtime)/(60*60*24));
|
| 143 |
} |
| 144 |
if ( $line =~ /(DNS:.+?)$/ ) {
|
| 145 |
my $san_line = $1; |
| 146 |
$san_line =~ s/DNS://g; |
| 147 |
$cert_files{$cert_name}{"info"} = $san_line;
|
| 148 |
} |
| 149 |
} |
| 150 |
} |
| 151 |
|
| 152 |
return %cert_files; |
| 153 |
|
| 154 |
} |
| 155 |
|
| 156 |
|
