# nagios check for debian security sync checks
#
# Copyright (c) 2008 Alexander Wirt <formorer@debian.org>
-# Copyright (c) 2009 Peter Palfrader <peter@palfrader.org>
+# Copyright (c) 2009, 2010, 2016 Peter Palfrader <peter@palfrader.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
print $fh " --verbose Be a little verbose.\n";
print $fh " --host hostname to check.\n";
print $fh " --path path to tracefile.\n";
+ print $fh " --unix tracefile has a unix timestamp.\n";
+ print $fh " --ssl use https.\n";
+ print $fh " --allow-skew=<foo>:<bar> if the newest timestamp is newer than <foo>secs\n";
+ print $fh " then the mirror sync is still ok, assuming the oldest\n";
+ print $fh " trace file is no older than <bar>\n";
print $fh "\n";
exit ($exit);
};
+# Work around LWP not being able to verify service certs directly
+my $ca_dir = '/etc/ssl/ca-debian';
+$ENV{'PERL_LWP_SSL_CA_PATH'} = $ca_dir if -d $ca_dir;
$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
'--help' => \$params->{'help'},
'--verbose' => \$params->{'verbose'},
'--version' => \$params->{'version'},
+ '--unix' => \$params->{'unix'},
+ '--ssl' => \$params->{'ssl'},
'--host=s' => \$params->{'host'},
'--path=s' => \$params->{'path'},
+ '--allow-skew=s' => \$params->{'skew'},
)) {
usage(*STDERR,1)
};
usage(*STDOUT,0) if ($params->{'help'});
usage(*STDERR,1) if (scalar @ARGV);
+if (defined $params->{'skew'}) {
+ if (not $params->{'skew'} =~ /^([0-9]+):([0-9]+)$/) {
+ print STDERR "Invalid allow-skew format\n";
+ usage(*STDERR,1);
+ };
+ $params->{'skew-new'} = $1;
+ $params->{'skew-old'} = $2;
+};
+
my $host = $params->{'host'};
my $path = $params->{'path'};
my @slaves;
print "Checking the following hosts:\n" . join("\n", @slaves) . "\n" if $params->{'verbose'};
my @critical;
+my $schema = $params->{'ssl'} ? 'https' : 'http';
foreach my $slave (@slaves) {
my $ua = LWP::UserAgent->new;
- $ua->proxy('http', "http://$slave");
- print "Requesting http://$host/$path from $slave\n" if $params->{'verbose'};
- my $response = $ua->get("http://$host/$path");
+ $ua->agent("dsa-check-mirrorsync");
+ $ua->timeout(10);
+ $ua->proxy('http', "$schema://$slave");
+ print "Requesting $schema://$host/$path from $slave\n" if $params->{'verbose'};
+ my $response = $ua->get("$schema://$host/$path");
if ($response->is_success) {
my $content = $response->content; # or whatever
my ($date, $foo, $bar) = split("\n", $content);
- my $synctime = str2time($date);;
- if (! defined $synctime) {
+ my $synctime;
+
+ if ($params->{'unix'}) {
+ if ($date =~ /^([0-9]+)$/) {
+ $synctime = $1;
+ }
+ } else {
+ $synctime = str2time($date);
+ }
+
+ if (defined $synctime) {
+ print "$slave last synced $synctime ", scalar(gmtime($synctime)), "\n" if $params->{'verbose'};
+ $status->{$slave}->{'synced'} = $synctime;
+ } else {
$synctime = 0;
$exitcode = $UNKNOWN;
push @exitstatus, "Cannot parse tracefile on $slave";
- };
- print "$slave last synced $synctime\n" if $params->{'verbose'};
- $status->{$slave}->{'synced'} = $synctime;
- }
- else {
+ }
+ } else {
push @exitstatus, "$slave broken: " . $response->status_line;
$status->{$slave}->{'error'} = $response->status_line;
+ $status->{$slave}->{'synced'} = 0;
$exitcode = $CRITICAL;
push @critical, $slave;
}
my %seen;
my $o_sync = scalar(grep !$seen{$_}++, map{$status->{$_}->{'synced'}} keys(%{$status}));
if ($o_sync > 1) {
- $exitcode = $CRITICAL;
- $o_sync -= 1;
my @mirrors = sort { $status->{$a}->{'synced'} <=> $status->{$b}->{'synced'} } keys %{$status};
- push @exitstatus, "$o_sync mirror(s) not in sync (from oldest to newest): ".
- join(",", splice(@mirrors,0,$o_sync));
+ my @not_most_recent = grep { $status->{$_}->{'synced'} <=> $status->{$mirrors[-1]}->{'synced'} } @mirrors;
+ $o_sync = scalar @not_most_recent;
+
+ my $newest = time - $status->{$mirrors[-1]}->{'synced'};
+ my $oldest = time - $status->{$mirrors[0]}->{'synced'};
+ my $skew_ok = ( defined $params->{'skew-new'} &&
+ defined $params->{'skew-old'} &&
+ $newest <= $params->{'skew-new'} &&
+ $oldest <= $params->{'skew-old'});
+
+ my $msg;
+ if ($skew_ok) {
+ $exitcode = $OK;
+ $msg = "$o_sync mirror(s) not in sync (from oldest to newest), but still within acceptable skew: ";
+ } else {
+ $exitcode = $CRITICAL;
+ $msg = "$o_sync mirror(s) not in sync (from oldest to newest): ";
+ };
+ push @exitstatus, $msg . join(", ", @not_most_recent);
} else {
- print "All mirrors unique\n" if $params->{'verbose'};
+ print "All mirrors on same sync timestamp\n" if $params->{'verbose'};
}
if ($exitcode == $CRITICAL) {
- print "CRITICAL: " . join(',',@exitstatus) . "\n";
+ print "CRITICAL: " . join(', ',@exitstatus) . "\n";
} elsif ($exitcode == $OK) {
- print "OK: all mirrors up2date\n";
+ if (scalar @exitstatus > 0) {
+ print "OK: " . join(', ',@exitstatus) . "\n";
+ } else {
+ print "OK: all mirrors up2date\n";
+ }
} else {
- print join(',',@exitstatus) . "\n";
+ print "UNKNOWN: ", join(', ',@exitstatus) . "\n";
}
foreach my $mirror (keys(%{$status})) {