Projet

Général

Profil

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

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