source: monitoring/plugins/ids/check_shib_idp @ 3866

Last change on this file since 3866 was 3866, checked in by oschonef, 11 years ago
  • cosmetic fixes
  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 5.5 KB
Line 
1#!/usr/bin/perl
2#
3# $Id: check_shib_idp 3866 2013-10-23 17:56:29Z oschonef $
4#
5
6use strict;
7use warnings;
8use Getopt::Long;
9use LWP;
10use Crypt::OpenSSL::X509;
11use Date::Parse;
12use POSIX qw(mktime);
13use constant {
14    OK        => 0,
15    WARNING   => 1,
16    CRITICAL  => 2,
17    UNKNOWN   => 3,
18    DEPENDENT => 4,
19};
20use constant {
21    IDP  => 'idp',
22    JAVA => 'java',
23};
24my $CODE2STRING = {
25    0 => 'OK',
26    1 => 'WARNING',
27    2 => 'CRITICAL',
28    3 => 'UNKNOWN',
29    4 => 'DEPENDENT',
30};
31
32
33sub get_diff {
34    my $ts = shift;
35
36    my ($sec1, $min1, $hour1, $day1, $mon1, $year1) =
37        strptime($ts);
38    my ($sec2, $min2, $hour2, $day2, $mon2, $year2) =
39        gmtime(time());
40    my $t1 = mktime($sec1, $min1, $hour1, $day1, $mon1, $year1);
41    my $t2 = mktime($sec2, $min2, $hour2, $day2, $mon2, $year2);
42    return $t1 - $t2;
43}
44
45
46sub status {
47    my $code    = shift;
48    my $message = shift;
49
50    $message =~ s/\n*$//;
51    printf("%s: %s\n", $CODE2STRING->{$code}, $message);
52    exit $code;
53}
54
55
56my $host           = undef;
57my $url            = 'idp/status';
58my $use_ssl        = 0;
59my $max_clock_diff = 120;
60my $cert_warn_days = 31;
61my $timeout        = 10;
62my $verbose        = 0;
63my $memory_warn    = 80;
64my $memory_crit    = 95;
65
66
67my $result = GetOptions('H=s' => \$host,
68                        'u=s' => \$url,
69                        't=i' => \$timeout,
70                        'S'   => \$use_ssl,
71                        'D=i' => \$max_clock_diff,
72                        'C=i' => \$cert_warn_days,
73                        'v'   => \$verbose,
74                        'W=i'    => \$memory_warn,
75                        'X=i'    => \$memory_crit);
76if (!($result)) {
77    status(UNKNOWN, 'USAGE: -H <host> [-u <url>] [-t <timeout>] [-S] ' .
78           '[-D <clock skew>] [-C <age>] [-W <value] [-X <value>]');
79}
80
81
82if (!defined($host)) {
83    status(UNKNOWN, 'missing manadorty parameter -H <host>');
84}
85
86if (($memory_warn < 0) || ($memory_warn > 100)) {
87    status(UNKNOWN, 'parameter -W <value> (memory warning) ' .
88           'must be between 0 and 100');
89}
90
91if (($memory_crit < 0) || ($memory_crit > 100)) {
92    status(UNKNOWN, 'parameter -X <value> (memory critical) ' .
93           'must be between 0 and 100');
94}
95
96if ($memory_warn > $memory_crit) {
97    status(UNKNOWN, 'value for memory warning must be less than ' .
98           'value for memory critical');
99}
100
101
102#
103# arm timeout alarm
104#
105local $SIG{ALRM} = sub {
106    status(UNKNOWN, 'check timed out');
107};
108alarm $timeout;
109
110
111$url =~ s|^/+||g;
112$url =~ s|/+$||g;
113my $idp_status_url = sprintf('%s://%s/%s', ($use_ssl ? 'https' : 'http'),
114                                            $host,
115                                            $url);
116print STDERR "IDP URL: $idp_status_url\n" if ($verbose > 0);
117
118my $browser = LWP::UserAgent->new;
119my $response = $browser->get($idp_status_url);
120if ($response->is_success) {
121    my $code    = OK;
122    my $message = undef;
123    my $result = {};
124    eval {
125        LINE:
126        foreach my $line (split("\r*\n", $response->content)) {
127            if (($line =~ m/^#/) || $line eq '') {
128                next LINE;
129            }
130            if ($line =~ m/^(\w+):\s+(.*?)$/g) {
131                $result->{$1} = $2;
132            }
133        }
134    };
135    if ($@) {
136        status(CRITICAL, "error parsing response: " . $@);
137    }
138       
139    my $time = $result->{'current_time'};
140    my $diff = get_diff($time);
141    print STDERR "time: $time, difference: $diff\n" if ($verbose > 0);
142    if (abs($diff) > $max_clock_diff) {
143        status(CRITICAL,
144               sprintf('clock skew too large (IDP time: %s, skew %d)',
145                       $time, $diff));
146    }
147
148    my $mem_used = $result->{'used_memory'};
149    my $mem_max  = $result->{'maximum_memory'};
150    my $mem_percentage = -1.0;
151    if (defined($mem_used) || defined($mem_max)) {
152        $mem_used =~ s/MB$//;
153        $mem_max  =~ s/MB$//;
154        $mem_percentage = int(($mem_used * 10000) / $mem_max / 100);
155
156        printf("memory usage %s/%s (%d%%)\n",
157               $mem_used, $mem_max, $mem_percentage)
158            if ($verbose > 0);
159
160        if ($mem_percentage > $memory_crit) {
161            $code    = CRITICAL;
162            $message = sprintf('IDP is low on memory (%s MB/%s MB = %d%%)',
163                               $mem_used, $mem_max, $mem_percentage);
164        }
165        elsif ($mem_percentage > $memory_warn) {
166            $code    = WARNING;
167            $message = sprintf('IDP is running low on memory ' .
168                               '(%s MB/%s MB = %d%%)',
169                               $mem_used, $mem_max, $mem_percentage);
170        }
171    }
172
173
174    my $versions = {
175        IDP  => $result->{'idp_version'},
176        JAVA => $result->{'jdk_version'},
177    };
178
179
180    my $cert = undef;
181    eval {
182        my $cert_data = $result->{'default_signing_tls_key'};
183        $cert_data =~ s/(.{64})/$1\n/gs;
184        $cert = Crypt::OpenSSL::X509->new_from_string(
185            sprintf("-----BEGIN CERTIFICATE-----\n%s\n" .
186                    "-----END CERTIFICATE-----\n", $cert_data));
187    };
188    if ($@) {
189        status(UNKNOWN, "cannot parse certificate data: $@");
190    }
191   
192    print STDERR "Certificate: " . $cert->subject() . ", validUntil: " .
193        $cert->notAfter() . "\n" if ($verbose > 0);
194
195    if ($cert->checkend(0)) {
196        $code    = CRITICAL;
197        $message = sprintf('signing certificate is expired since %s',
198                           $cert->notAfter());
199    }
200    elsif ($cert->checkend($cert_warn_days * 86400)) {
201        my $expire_days = int(get_diff($cert->notAfter()) / 86400);
202        $code           = WARNING;
203        $message        = sprintf('signing certificate expires in %d day(s)',
204                                  $expire_days);
205    }
206
207    if ($code != OK) {
208        status($code, $message);
209    }
210    else {
211        status(OK, sprintf('Shibboleth IDP version %s ' .
212                           '(Java version %s, %d%% memory used)',
213                           $versions->{IDP}, $versions->{JAVA},
214                           $mem_percentage));
215    }
216}
217else {
218    my $status = $response->status_line || 'unknown';
219    status(CRITICAL, sprintf('error fetching status: %s', $status));
220}
221exit OK;
Note: See TracBrowser for help on using the repository browser.