+++ /dev/null
-#!/usr/bin/perl -Tw
-
-# $Id: nagios-check-apt-updates 352 2008-05-20 21:36:54Z weasel $
-
-# nagios check for debian (security) updates,
-# based on net-snmp glue to security updates via apt-get.
-# Copyright (C) 2004 SILVER SERVER Gmbh
-# Copyright (C) 2004, 2005, 2006, 2007, 2008 Peter Palfrader
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-
-use strict;
-use English;
-use Getopt::Long;
-use IO::Handle;
-use IPC::Open2;
-use IPC::Open3;
-
-$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
-delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
-
-my $APT = '/usr/bin/apt-get';
-my $VERBOSE;
-
-sub do_check($$$$$$) {
- my ($pre_command, $timeout, $noupdate, $name, $updates_security, $updates_other) = @_;
- my $fh;
- my $pid;
- my @command;
-
- unless ($noupdate) {
- print STDERR "Running $APT update in $name\n" if $VERBOSE;
- @command = ($APT, 'update');
- unshift @command, @$pre_command;
- $fh = new IO::Handle;
- $pid = open3(\*STDIN, $fh, $fh, @command) or die ("Cannot run $APT update in $name: $!\n");
- local $SIG{ALRM} = sub { die "Timeout for apt-get update.\n" };
- alarm $timeout;
- my @ignore=<$fh>;
- alarm 0;
- close $fh;
- waitpid $pid, 0;
- if ($CHILD_ERROR) { # program failed
- die("$APT update returned with non-zero exit code in $name: ".($CHILD_ERROR / 256)."\n");
- };
- };
-
- print STDERR "Running $APT --simulate upgrade in $name\n" if $VERBOSE;
- @command = ($APT, qw{--simulate upgrade});
- unshift @command, @$pre_command;
- $fh = new IO::Handle;
- $pid = open2($fh, \*STDIN, @command) or die ("Cannot run $APT --simulate upgrade | sort -u in $name: $!\n");
- local $SIG{ALRM} = sub { die "Timeout for apt-get --simulate upgrade.\n" };
- alarm $timeout;
- my @lines=<$fh>;
- close $fh;
- alarm 0;
- waitpid $pid, 0;
- if ($CHILD_ERROR) { # program failed
- die("$APT --simulate upgrade | sort -u returned with non-zero exit code in $name: ".($CHILD_ERROR / 256)."\n");
- };
-
- @lines = sort {$a cmp $b} @lines;
- my %uniq;
- @lines = grep {!$uniq{$_}++} @lines;
-
- print STDERR "Processing information for $name\n" if $VERBOSE;
- for my $line (@lines) {
- if ($line =~ m/^Inst\s+(\S+)\s+/) {
- my $package = $1;
- if ($line =~ m/^Inst\s+\S+\s+.*security/i) {
- push @$updates_security, $package.($name ne '/' ? "($name)" : '');
- } else {
- push @$updates_other, $package.($name ne '/' ? "($name)" : '');
- };
- }
- }
-}
-
-
-
-my $VERSION = '0.0.3 - $Rev: 352 $';
-my $use_sudo = 1;
-my $params;
-
-# nagios exit codes
-my $OK = 0;
-my $WARNING = 1;
-my $CRITICAL = 2;
-my $UNKNOWN = 3;
-
-$params->{'chroots'} = [];
-$params->{'vservers'} = [];
-$params->{'timeout'} = 20;
-Getopt::Long::config('bundling');
-if (!GetOptions (
- '--help' => \$params->{'help'},
- '--version' => \$params->{'version'},
- '--sudo' => \$params->{'sudo'},
- '--noupdate' => \$params->{'noupdate'},
- '--nosudo' => \$params->{'nosudo'},
- '--verbose' => \$params->{'verbose'},
- '--warnifupdates' => \$params->{'warnifupdates'},
- '--timeout=i' => \$params->{'timeout'},
- '--chroot=s' => $params->{'chroots'},
- '--vserver=s' => $params->{'vservers'}
- )) {
- die ("Usage: $PROGRAM_NAME [--help|--version] [--sudo|--nosudo] [--timeout=<timeout>] [--verbose]\n");
-};
-if ($params->{'help'}) {
- print "nagios-check-apt-updates $VERSION\n";
- print "Usage: $PROGRAM_NAME [--help|--version] [--sudo|--nosudo] [--verbose]\n";
- print "Reports packages to upgrade, updating the list if necessary.\n";
- print "\n";
- print " --help Print this short help.\n";
- print " --version Report version number.\n";
- print " --sudo Use sudo to call apt-get (default).\n";
- print " --noupdate Do not run apt-get update first.\n";
- print " --nosudo Do not use sudo to call apt-get.\n";
- print " --warnifupdates Exit with a WARNING status if any updates are available.\n";
- print " --timeout=<timeout> Timeout in seconds for each of the two apt-get runs.\n";
- print " --verbose Be a little verbose.\n";
- print " --chroot=<path> Run check in path.\n";
- print " --vserver=<vserver> Run check in vserver.\n";
- print "\n";
- print "Note that for --sudo (default) you will need entries in /etc/sudoers like these:\n";
- print "nagios ALL=(ALL) NOPASSWD: /usr/bin/apt-get update\n";
- print "nagios ALL=(ALL) NOPASSWD: /usr/bin/apt-get --simulate upgrade\n";
- print "nagios ALL=(ALL) NOPASSWD: /usr/sbin/chroot /chroot-ia32 /usr/bin/apt-get update\n";
- print "nagios ALL=(ALL) NOPASSWD: /usr/sbin/chroot /chroot-ia32 /usr/bin/apt-get --simulate upgrade\n";
- print "nagios ALL=(ALL) NOPASSWD: /usr/sbin/vserver phpserver exec /usr/bin/apt-get update\n";
- print "nagios ALL=(ALL) NOPASSWD: /usr/sbin/vserver phpserver exec /usr/bin/apt-get --simulate upgrade\n";
- print "\n";
- exit (0);
-};
-if ($params->{'version'}) {
- print "nagios-check-apt-updates $VERSION\n";
- print "nagios check for availability of debian (security) updates\n";
- print "Copyright (c) 2004 SILVER SERVER Gmbh\n";
- print "Copyright (c) 2004,2005 Peter Palfrader <peter\@palfrader.org>\n";
- exit (0);
-};
-if ($params->{'sudo'} && $params->{'nosudo'}) {
- die ("$PROGRAM_NAME: --sudo and --nosudo are mutually exclusive.\n");
-};
-if ($params->{'sudo'}) {
- $use_sudo = 1;
-};
-if ($params->{'nosudo'}) {
- $use_sudo = 0;
-};
-if (scalar @{$params->{'chroots'}} == 0 && scalar @{$params->{'vservers'}} == 0) {
- $params->{'chroots'} = ['/'];
-};
-$VERBOSE = $params->{'verbose'};
-
-
-$SIG{'__DIE__'} = sub {
- print STDERR @_;
- exit $UNKNOWN;
-};
-
-
-my @updates_security;
-my @updates_other;
-
-
-# Make sure chroot paths are nice;
-my @chroots = ();
-for my $root (@{$params->{'chroots'}}) {
- if ($root =~ m#^(/[a-zA-Z0-9/.-]*)$#) {
- push @chroots, $1;
- } else {
- die ("Chroot path $root is not nice.\n");
- };
-};
-for my $root (@chroots) {
- my @pre_command = ();
- unshift @pre_command, 'chroot', $root if ($root ne '/');
- unshift @pre_command, 'sudo' if $use_sudo;
- do_check(\@pre_command, $params->{'timeout'}, $params->{'noupdate'}, $root, \@updates_security, \@updates_other);
-}
-
-# Make sure vserver names are nice;
-my @vservers = ();
-for my $vserver (@{$params->{'vservers'}}) {
- if ($vserver =~ m#^([a-zA-Z0-9.-]+)$#) {
- push @vservers, $1;
- } else {
- die ("Vserver name $vserver is not nice.\n");
- };
-};
-for my $vserver (@vservers) {
- my @pre_command = ();
- unshift @pre_command, '/usr/sbin/vserver', $vserver, 'exec';
- unshift @pre_command, 'sudo' if $use_sudo;
- do_check(\@pre_command, $params->{'timeout'}, $params->{'noupdate'}, $vserver, \@updates_security, \@updates_other);
-}
-
-
-
-
-my $exit = $OK;
-
-my $updateinfo;
-if (@updates_security) {
- $updateinfo .= 'Security updates ('.(scalar @updates_security).'): '.join(', ', @updates_security)."; ";
- $exit = $CRITICAL;
-}
-if (@updates_other) {
- $updateinfo .= 'Other Updates ('.(scalar @updates_other).'): '.join(', ', @updates_other)."; ";
- $exit = $WARNING if ($params->{'warnifupdates'} and $exit == $OK);
-};
-$updateinfo = 'No updates available' unless defined $updateinfo;
-
-
-print $updateinfo,"\n";
-exit $exit;
--- /dev/null
+#!/bin/sh
+
+# Check that debian-admin is in /etc/aliases for root.
+# Peter Palfrader, 2008
+
+#my %ERRORS = ( OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => -1 );
+
+set -e
+err=0
+
+log() {
+ if [ "$0" == "ok" ] && [ "$err" == 0 ]; then
+ err=0
+ elif [ "$1" == "warn" ] && [ "$err" -lt 1 ]; then
+ err=1
+ elif [ "$1" == "critical" ] && [ "$err" -lt 2 ]; then
+ err=2
+ elif [ "$1" == "unknown" ] && [ "$err" == 0 ]; then
+ err=3
+ fi
+ if [ "`eval echo \\$$1`" = "" ]; then
+ eval $1="\"$2\""
+ else
+ eval $1="\"`eval echo \\$$1`; $2\""
+ fi
+}
+
+
+check_aliases() {
+ if ! [ -e /etc/aliases ]; then
+ log unknown "/etc/aliases not found"
+ return
+ fi
+
+ if egrep '^root:.*debian-admin@debian.org' /etc/aliases > /dev/null; then
+ log ok "debian-admin found in aliases"
+ return
+ fi
+
+ log warn "debian-admin not found in root entry in aliases"
+}
+
+check_ldap_conf() {
+ if ! [ -e /etc/ldap/ldap.conf ]; then
+ log unknown "/etc/ldap/ldap.conf not found"
+ return
+ fi
+
+ if egrep '^URI.*ldap://db.debian.org' /etc/ldap/ldap.conf > /dev/null &&
+ egrep '^BASE.*dc=debian,dc=org' /etc/ldap/ldap.conf > /dev/null &&
+ egrep '^TLS_CACERT.*/etc/ssl/certs/spi-cacert-2008.pem' /etc/ldap/ldap.conf > /dev/null &&
+ egrep '^TLS_REQCERT.*hard' /etc/ldap/ldap.conf > /dev/null ; then
+ log ok "ldap.conf configured properly"
+ return
+ fi
+
+ log warn "ldap.conf does not have URI, BASE, TLS_CACERT, TLS_REQCERT all configured correctly"
+}
+
+check_aliases
+check_ldap_conf
+
+[ "$critical" = "" ] || echo -n "Critical: $critical; "
+[ "$warn" = "" ] || echo -n "Warning: $warn; "
+[ "$unknown" = "" ] || echo -n "Unknown: $unknown; "
+[ "$ok" = "" ] || echo -n "OK: $ok"
+echo
+exit $err
--- /dev/null
+#!/usr/bin/perl -w
+
+# Check the status of da-backup backups
+# Copyright 2007 Stephen Gran <sgran@debian.org>
+# Copyright 2008 Peter Palfrader
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+use strict;
+use warnings;
+use English;
+use Getopt::Long;
+use Fcntl qw(:seek);
+
+my $DABACKUP_CONF = '/etc/da-backup.conf';
+my $MAX_AGE = 30*60*60;
+my $TOO_FRESH = 5*60;
+my %CODE = (
+ 'UNDEF' => -1,
+ 'OK' => 0,
+ 'WARNING' => 1,
+ 'CRITICAL' => 2,
+ 'UNKNOWN' => 3
+);
+$SIG{__DIE__ } = sub() {
+ print shift;
+ exit $CODE{'UNKNOWN'};
+};
+
+
+my $EXITCODE = 'UNDEF';
+my %MESSAGE = ();
+
+sub problem($$$) {
+ my ($code, $msg, $resource) = @_;
+ $MESSAGE{$msg} = [] unless defined $MESSAGE{$msg};
+ push @{$MESSAGE{$msg}}, $resource;
+ $EXITCODE = ($CODE{$code} > $CODE{$EXITCODE}) ? $code : $EXITCODE;
+};
+
+
+sub help($$) {
+ my ($exitcode, $fd) = @_;
+ version ($fd, 0);
+ print $fd "Usage: $PROGRAM_NAME --help\n";
+ print $fd "Usage: $PROGRAM_NAME";
+ exit $exitcode
+};
+
+my $params = {};
+
+Getopt::Long::config('bundling');
+if (!GetOptions (
+ 'h|help' => \$params->{'help'},
+ )) {
+ die ("$PROGRAM_NAME: Usage: $PROGRAM_NAME [-fwhv]\n");
+};
+
+help(0, *STDOUT) if $params->{'help'};
+help(1, *STDERR) if scalar @ARGV > 0;
+
+
+unless (-e $DABACKUP_CONF) {
+ if (-e '/etc/da-backup') {
+ print "WARNING: No $DABACKUP_CONF, but we have /etc/da-backup/\n";
+ exit $CODE{'WARNING'};
+ };
+ if (-e '/var/log/da-backup') {
+ print "WARNING: No $DABACKUP_CONF, but we have /var/log/da-backup/\n";
+ exit $CODE{'WARNING'};
+ };
+ print "OK: da-backup not installed\n";
+ exit $CODE{'OK'};
+};
+
+my $confdir;
+my $logdir;
+
+open (FH, "< $DABACKUP_CONF") or die ("Cannot open $DABACKUP_CONF: $!\n");
+while (<FH>) {
+ if (/confdir=(.*)/) {
+ $confdir = $1;
+ } elsif (/logdir=(.*)/) {
+ $logdir = $1;
+ };
+};
+
+die ("No confdir found in $DABACKUP_CONF") unless defined $confdir;
+die ("No logdir found in $DABACKUP_CONF") unless defined $logdir;
+
+opendir(DIR, $confdir) or die ("Cannot opendir $confdir: $!\n");
+my %conffiles = map {$_ => 1} grep { !/^\./ && !/\.bak$/} readdir(DIR);
+closedir(DIR);
+
+opendir(DIR, $logdir) or die ("Cannot opendir $logdir: $!\n");
+my %logfiles = map {$_ => 1} grep { !/^\./ && !/\.[0-9]+(\.gz)?$/} readdir(DIR);
+closedir(DIR);
+
+if (scalar keys %conffiles == 0) {
+ print "WARNING: da-backup installed but no backups configured\n";
+ exit $CODE{'WARNING'};
+};
+
+for my $f (keys %conffiles) {
+ unless (exists $logfiles{$f}) {
+ problem('WARNING', 'no log', $f);
+ }
+}
+
+FILE:
+for my $f (sort {$a cmp $b} keys %logfiles) {
+ unless (exists $conffiles{$f}) {
+ problem('WARNING', 'no config', $f);
+ next;
+ }
+
+ my @stat = stat("$logdir/$f") or die ("Cannot stat $logdir/$f: $!\n");
+ my $age = time - $stat[10];
+
+ if ($age < $TOO_FRESH) { # File is too new, let's use the old one
+ if (-e "$logdir/$f.0") {
+ $f .= ".0";
+ my @stat = stat("$logdir/$f") or die ("Cannot stat $logdir/$f: $!\n");
+ $age = time - $stat[10];
+ };
+ };
+
+ if ($age < 0) {
+ problem('WARNING', 'future timestamp', $f);
+ next;
+ } elsif ($age > $MAX_AGE) {
+ my $hage;
+
+ if ($age > 48 * 3600) {
+ $hage = sprintf("%d days", $age / 24 / 3600);
+ } else {
+ $hage = sprintf("%d hours", $age / 3600);
+ };
+ problem('WARNING', 'old', "$f ($hage)");
+ next;
+ };
+
+ open(FH, "< $logdir/$f") or die ("Cannot open $logdir/$f: $!\n");
+ sysseek(FH, -1024, SEEK_END); # just try it - doesn't matter if it fails
+ my $last2 = '';
+ my $last = '';
+ while (<FH>) {
+ chomp;
+ if (/^sent\s+\d+\s+bytes\s+received\s+\d+\s+bytes\s+[\d\.]+\s+bytes\/sec$/) {
+ problem('OK', 'probably ok', $f);
+ close(FH);
+ next FILE;
+ };
+ $last2 = $last;
+ $last = $_;
+ };
+ problem('CRITICAL', 'FAILED', "$f ($last2 $last)");
+};
+
+my $msg = join("; ", map {"$_: ".join(', ', @{$MESSAGE{$_}}) } (sort {$a cmp $b} keys %MESSAGE));
+print $EXITCODE, ": ", $msg, "\n";
+exit $CODE{$EXITCODE};
--- /dev/null
+#!/bin/sh
+
+# some tests weasel uses to check if da-backup is properly configured:
+# Copyright 2008 Peter Palfrader
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+set -e
+set -u
+
+err=0
+
+log() {
+ if [ "$1" == "warn" ] && [ "$err" -lt 1 ]; then
+ err=1
+ elif [ "$1" == "critical" ] && [ "$err" -lt 2 ]; then
+ err=2
+ elif [ "$1" == "unknown" ] && [ "$err" == 0 ]; then
+ err=3
+ fi
+}
+
+cd /etc/da-backup-manager
+
+# check that the files have proper names
+for i in *; do
+ s=`cat "$i" | awk -F = '$1=="source" {print $2}'`
+ if [ "$s" = "master.debian.org/debian" ] && [ "$i" = "listarchive" ]; then
+ # historical exception
+ continue
+ fi
+ if [ "`echo $s | tr / -`" != "$i" ]; then
+ log warn
+ echo "Mismatch: Filename $i but backup source $s"
+ fi
+done
+
+# and that source == destination everywhere
+for i in *; do
+ s=`cat $i | awk -F = '$1=="source"{print $2}'`
+ d=`cat $i | awk -F = '$1=="destination"{print $2}'`
+ if [ "$d" != "$s" ]; then
+ log warn
+ echo "source != dest in $i. ($s != $d)"
+ fi
+done
+
+# check that everything that has an entry in authorized_keys has one in /etc/da-backup-manager
+rsync_targets=`tempfile`
+backup_manager_sources=`tempfile`
+trap "rm -f '$rsync_targets' '$backup_manager_sources'" 0 1 2 5 15
+cat /root/.ssh/authorized_keys |
+ grep '^command=' |
+ sed -e 's/",no-por.*//' -e 's/.*--ignore-errors . //' -e 's#/org/backup.debian.org/staging/##' |
+ sort > "$rsync_targets"
+grep -h source /etc/da-backup-manager/* |
+ sed -e 's/source=//' |
+ sort > "$backup_manager_sources"
+if ! diff "$rsync_targets" "$backup_manager_sources" > /dev/null; then
+ log warn
+ echo "authorized_keys vs. /etc/da-backup-manage mismatch:"
+ diff "$rsync_targets" "$backup_manager_sources"
+fi
+
+# check that everything listed as either source or destination by da-backup-manager does exist - if stuff is new it might still be missing tho
+for i in `awk -F = '$1=="source" {print $2}' /etc/da-backup-manager/* `; do
+ if ! [ -d "/org/backup.debian.org/staging/$i" ]; then
+ log warn
+ echo "Warning: source $i does not exist"
+ fi
+done
+for i in ` awk -F = '$1=="destination"{print $2}' /etc/da-backup-manager/* `; do
+ if ! [ -d "/org/backup.debian.org/backups/$i" ]; then
+ log warn
+ echo "Warning: destination $i does not exist (if it is new, it takes a day)"
+ fi
+done
+
+# check that everything that does exist has an entry in da-backup-manager
+cd /org/backup.debian.org/staging
+for i in */*; do
+ if ! [ -d "$i" ]; then
+ log warn
+ echo "WTF: staging/$i is not a dir"
+ continue
+ fi
+ if ! grep "source=$i" /etc/da-backup-manager/* > /dev/null; then
+ log warn
+ echo "staging/$i is not listed anywhere in /etc/da-backup-manager"
+ fi
+done
+cd /org/backup.debian.org/backups
+for i in */*; do
+ if ! [ -d "$i" ]; then
+ log warn
+ echo "WTF: backups/$i is not a dir"
+ continue
+ fi
+ if ! grep "destination=$i" /etc/da-backup-manager/* > /dev/null; then
+ log warn
+ echo "backups/$i is not listed anywhere in /etc/da-backup-manager"
+ fi
+done
+
+if [ "$err" = 0 ]; then
+ echo "da-backup seems to be properly configured"
+fi
+exit $err
--- /dev/null
+#!/usr/bin/perl -w
+
+# check _physical_ disk status of disks on HP smart array controllers
+# requires hpacucli
+#
+# does _not_ check raid status. use arrayprobe for that.
+
+# Copyright (c) 2008 Peter Palfrader <peter@palfrader.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+use strict;
+
+# nagios exit codes
+my %CODE = (
+ 'OK' => 0,
+ 'WARNING' => 1,
+ 'CRITICAL' => 2,
+ 'UNKNOWN' => 3
+);
+
+my $EXITCODE = 'OK';
+
+$SIG{'__DIE__'} = sub {
+ print STDERR @_;
+ exit $CODE{'UNKNOWN'};
+};
+
+sub runcmd($) {
+ my ($cmd) = @_;
+ $cmd = "sudo hpacucli $cmd";
+ open(FH, $cmd."|") or die ("Cannot run $cmd: $!");
+ my @lines = <FH>;
+ close FH;
+ die ("no results from $cmd\n") if (scalar @lines == 0);
+ return \@lines;
+}
+
+sub record($) {
+ my ($newexit) = @_;
+ die "code $newexit not defined\n" unless defined $CODE{$newexit};
+
+ if ($CODE{$newexit} > $CODE{$EXITCODE}) {
+ $EXITCODE = $newexit;
+ };
+}
+
+
+my $ctrlallshow = runcmd("controller all show");
+my @controllers;
+for (@$ctrlallshow) {
+ chomp;
+ next if /^$/;
+ if (/in Slot ([0-9]+) /) {
+ push @controllers, $1;
+ next;
+ };
+ die ("Cannot read line '$_' gotten from hpacucli controller all show\n");
+};
+
+if (scalar @controllers == 0) {
+ print "UNKNONW: No smartarray controllers found with hpacucli\n";
+ exit $CODE{'UNKNOWN'}
+};
+
+my @resultstr;
+
+for my $slot (sort @controllers) {
+ my $pds = runcmd("controller slot=$slot pd all show");
+ my @drives;
+ my $nodrives = 0;
+ my %status;
+ for (@$pds) {
+ chomp;
+ next if /^$/;
+ next if (/^\S.*in Slot $slot/);
+ next if /^ *array [A-Z]$/;
+ if (/^ *(array [A-Z]) \(Failed\)$/) {
+ record('CRITICAL');
+ push @{$status{'Failed'}}, $1;
+ } elsif (/^Error: The specified controller does not have any physical drives on it.$/) {
+ $nodrives = 1;
+ } elsif (/^ *physicaldrive (\S+) .* (OK|Predictive Failure|Failed|Rebuilding)(?:, spare)?\)$/) {
+ my $drive = $1;
+ my $status = $2;
+ push @{$status{$status}}, $drive;
+ if ($status eq 'OK') {
+ } elsif ($status eq 'Predictive Failure' ||
+ $status eq 'Rebuilding') {
+ record('WARNING');
+ } elsif ($status eq 'Failed') {
+ record('CRITICAL');
+ } else {
+ record('UNKNOWN');
+ };
+ push @drives, $drive;
+ } else {
+ die ("Cannot read line '$_' gotten from hpacucli controller slot=$slot pd all show\n");
+ };
+ };
+
+ # Check that all drives have the proper transfer speed.
+ # sometimes stuff breaks and they fall back to 10mb/sec.
+ for my $drive (@drives) {
+ # skip drives that are known to have failed
+ next if (exists $status{'Failed'} && grep {$drive eq $_} @{$status{'Failed'}});
+ my $type;
+ if ($drive =~ /^[0-9]+:[0-9]+$/) { # scsi drives
+ $type = 'SCSI';
+ } elsif ($drive =~ /^[0-9]+I:[0-9]+:[0-9]+$/) { # SAS
+ $type = 'SAS';
+ } else {
+ # I'm not going to run pass arguments of unknown form to the shell..
+ warn ("Unknown diskdrive ID $drive\n");
+ next;
+ }
+
+ my $pd = runcmd("controller slot=$slot pd $drive show");
+ while (defined $pd->[0] && !($pd->[0] =~ /physicaldrive/)) {
+ shift @$pd;
+ };
+ shift @$pd;
+ my %value;
+ for (@$pd) {
+ if (m/^\s*(.*?):\s*(.*?)\s*$/) {
+ $value{$1} = $2;
+ }
+ }
+
+ my $key;
+ my $expected;
+ if ($type eq 'SCSI') {
+ $key = 'Transfer Speed';
+ if (!defined $value{'Transfer Mode'}) {
+ record('WARNING');
+ push @{$status{'unknown transfer mode'}}, $drive;
+ next;
+ } elsif ($value{'Transfer Mode'} eq 'Ultra 3 Wide') {
+ $expected = '160 MB/Sec';
+ } elsif ($value{'Transfer Mode'} eq 'Ultra 320 Wide') {
+ $expected = '320 MB/Sec';
+ } else {
+ record('WARNING');
+ push @{$status{'unknown transfer mode'}}, $drive."(".$value{'Transfer Mode'}.")";
+ next;
+ };
+ } elsif ($type eq 'SAS') {
+ $key = 'PHY Transfer Rate';
+ if ($value{'PHY Count'} eq '2') {
+ $expected = '3.0GBPS, Unknown';
+ } else {
+ $expected = '3.0GBPS';
+ }
+ } else {
+ warn "Should not be here. Do not know what to do with type '$type'\n";
+ next;
+ }
+
+ if (!defined $value{$key}) {
+ record('WARNING');
+ push @{$status{'unknown transfer speed'}}, $drive;
+ } elsif ($value{$key} ne $expected) {
+ record('WARNING');
+ push @{$status{'bad transfer speed'}}, $drive."(".$value{$key}.")";
+ };
+ };
+
+ if ($nodrives && scalar keys %status > 0) {
+ push @resultstr, "Slot $slot: have no drives but status results?";
+ record('UNKNOWN');
+ next;
+ } elsif ($nodrives) {
+ push @resultstr, "Slot $slot: no drives";
+ next;
+ };
+
+ my $cst = runcmd("controller slot=$slot show status");
+ for (@$cst) {
+ chomp;
+ next if /^$/;
+ next if (/^\S.*in Slot $slot/);
+ if (/^ *(.*) Status: (.*)$/) {
+ my $system = $1;
+ my $status = $2;
+ push @{$status{$status}}, $system;
+ if ($status ne 'OK') {
+ record('WARNING');
+ };
+ } else {
+ die ("Cannot read line '$_' gotten from hpacucli controller slot=$slot show status\n");
+ };
+ };
+
+ my $status = join(" - ", (map { $_.": ".join(", ", @{$status{$_}}) } keys %status));
+ push @resultstr, "Slot $slot: $status";
+};
+
+print "$EXITCODE: ", join(" --- ", @resultstr), "\n";
+exit $CODE{$EXITCODE};
--- /dev/null
+#!/usr/bin/perl -w
+
+# nagios check for debian security sync checks
+#
+# Copyright (c) 2008 Alexander Wirt <formorer@debian.org>
+# Copyright (c) 2009 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA
+
+use LWP::UserAgent;
+use Socket;
+use strict;
+use Date::Parse;
+use Getopt::Long;
+use Date::Parse;
+use Date::Format;
+use File::Basename;
+use English;
+use warnings;
+
+
+sub usage($$) {
+ my ($fh, $exit) = @_;
+ my $basename = basename($PROGRAM_NAME);
+ my $VERSION = '0.1';
+
+ print $fh "$basename $VERSION\n";
+ print $fh "Usage: $basename [--help|--version] [--verbose]\n";
+ print $fh "\n";
+ print $fh " --help Print this short help.\n";
+ print $fh " --version Report version number.\n";
+ print $fh " --verbose Be a little verbose.\n";
+ print $fh " --host hostname to check.\n";
+ print $fh " --path path to tracefile.\n";
+ print $fh "\n";
+ exit ($exit);
+};
+
+
+$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
+delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
+
+my $params;
+
+$params->{'host'} = 'security.debian.org'; #which host to check
+$params->{'path'} = 'project/trace/security-master.debian.org';
+
+my $OK = 0;
+my $WARNING = 1;
+my $CRITICAL = 2;
+my $UNKNOWN = 3;
+
+if (!GetOptions (
+ '--help' => \$params->{'help'},
+ '--verbose' => \$params->{'verbose'},
+ '--version' => \$params->{'version'},
+ '--host=s' => \$params->{'host'},
+ '--path=s' => \$params->{'path'},
+ )) {
+ usage(*STDERR,1)
+};
+usage(*STDOUT,0) if ($params->{'help'});
+usage(*STDERR,1) if (scalar @ARGV);
+
+my $host = $params->{'host'};
+my $path = $params->{'path'};
+my @slaves;
+my $status;
+my @exitstatus;
+my $exitcode = $OK;
+
+@slaves = gethostbyname($params->{'host'}) or die "Can't resolve " . $params->{'host'} .": $!\n";
+@slaves = map { inet_ntoa($_) } @slaves[4 .. $#slaves];
+print "Checking the following hosts:\n" . join("\n", @slaves) . "\n" if $params->{'verbose'};
+
+my @critical;
+
+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");
+
+
+ if ($response->is_success) {
+ my $content = $response->content; # or whatever
+ my ($date, $foo, $bar) = split("\n", $content);
+ my $synctime = str2time($date);;
+ print "$slave last synced $synctime\n" if $params->{'verbose'};
+ $status->{$slave}->{'synced'} = $synctime;
+ }
+ else {
+ push @exitstatus, "$slave broken: " . $response->status_line;
+ $status->{$slave}->{'error'} = $response->status_line;
+ $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));
+} else {
+ print "All mirrors unique\n" if $params->{'verbose'};
+}
+
+if ($exitcode == $CRITICAL) {
+ print "CRITICAL: " . join(',',@exitstatus) . "\n";
+} elsif ($exitcode == $OK) {
+ print "OK: all mirrors up2date\n";
+}
+
+foreach my $mirror (keys(%{$status})) {
+ if ($status->{$mirror}->{'error'}) {
+ print "$mirror broken: " . $status->{$mirror}->{'error'} . "\n";
+ } else {
+ print "$mirror last synced: " . localtime($status->{$mirror}->{'synced'}) ."\n";
+ }
+}
+
+exit $exitcode;
--- /dev/null
+#!/usr/bin/perl
+
+# dsa-check-packages
+
+# checks for obsolete/local and upgradeable packages.
+#
+# packages for the obsolete/local check can be ignored, by
+# listing their full name in /etc/nagios/obsolete-packages-ignore
+# or by having a regex (starting a line with "/") that matches
+# the packagename in said file.
+#
+# Takes one optional argument, the location of the ignore file.
+
+
+# Copyright (C) 2008, 2009 Peter Palfrader <peter@palfrader.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+use strict;
+use warnings;
+use English;
+
+my $IGNORE = "/etc/nagios/obsolete-packages-ignore";
+
+my %CODE = (
+ 'OK' => 0,
+ 'WARNING' => 1,
+ 'CRITICAL' => 2,
+ 'UNKNOWN' => 3
+);
+my $EXITCODE = 'OK';
+sub record($) {
+ my ($newexit) = @_;
+ die "code $newexit not defined\n" unless defined $CODE{$newexit};
+
+ if ($CODE{$newexit} > $CODE{$EXITCODE}) {
+ $EXITCODE = $newexit;
+ };
+}
+
+
+
+sub get_packages {
+ $ENV{'COLUMNS'} = 1000;
+ $ENV{'LC_ALL'} = 'C';
+ open(F, "dpkg -l|") or die ("Cannot run dpkg: $!\n");
+ my @lines = <F>;
+ close(F);
+ chomp(@lines);
+
+ shift @lines while ($lines[0] !~ /\+\+\+/);
+ shift @lines;
+
+ my %pkgs;
+ for my $line (@lines) {
+ my ($state, $pkg, $version, undef) = split(/ */, $line);
+ $pkgs{$state}{$pkg} = { 'installed' => $version }
+ }
+
+ my $installed = $pkgs{'ii'};
+ delete $pkgs{'ii'};
+
+ open my $olderr, ">&STDERR" or die "Can't dup STDERR: $!";
+ open STDERR, ">/dev/null" or die "Can't dup STDOUT: $!";
+
+ open (F, "apt-cache policy ".(join(" ", keys(%$installed)))." |") or die ("Cannot run apt-cache policy: $!\n");
+ @lines = <F>;
+ close(F);
+ chomp(@lines);
+ open STDERR, ">&", $olderr or die "Can't dup OLDERR: $!";
+
+ my $line;
+ my $pkgname = undef;
+ while (defined($line = shift @lines)) {
+ if ($line =~ /^([^ ]*):$/) {
+ $pkgname = $1;
+ } elsif ($line =~ /^ +Installed: (.*)$/) {
+ # etch dpkg -l does not print epochs, so use this info, it's better
+ $installed->{$pkgname}{'installed'} = $1;
+ } elsif ($line =~ /^ +Candidate: (.*)$/) {
+ $installed->{$pkgname}{'candidate'} = $1;
+ } elsif ($line =~ /^ +\*\*\*/) {
+ my @l;
+ @l = split(/ +/, $line);
+ $line = shift @lines;
+ @l = split(/ +/, $line);
+ $installed->{$pkgname}{'origin'} = $l[2];
+ }
+ }
+
+ my (%current, %obsolete, %outofdate);
+ for my $pkgname (keys %$installed) {
+ my $pkg = $installed->{$pkgname};
+
+ unless (defined($pkg->{'candidate'}) && defined($pkg->{'origin'})) {
+ $obsolete{$pkgname} = $pkg;
+ next;
+ }
+
+ if ($pkg->{'candidate'} ne $pkg->{'installed'}) {
+ $outofdate{$pkgname} = $pkg;
+ next;
+ };
+ if ($pkg->{'origin'} eq '/var/lib/dpkg/status') {
+ $obsolete{$pkgname} = $pkg;
+ next;
+ }
+ $current{$pkgname} = $pkg;
+ }
+
+ $pkgs{'current'} = \%current;
+ $pkgs{'outofdate'} = \%outofdate;
+ $pkgs{'obsolete'} = \%obsolete;
+ return \%pkgs;
+}
+
+sub load_ignores {
+ my ($ignorefile, $require_file) = @_;
+
+ my @ignores;
+ if (!$require_file and ! -e $ignorefile) {
+ return \@ignores;
+ }
+
+ open (F, "< $ignorefile") or die ("Cannot open $ignorefile: $!\n");
+ @ignores = <F>;
+ close F;
+ chomp(@ignores);
+ return \@ignores;
+}
+
+sub check_ignore {
+ my ($pkg, $ignores) = @_;
+
+ my $ignore_this = 0;
+ for my $ignore (@$ignores) {
+ my $ig = $ignore;
+ return 1 if ($ig eq $pkg);
+ if (substr($ig,0,1) eq '/') {
+ substr($ig, 0, 1, '');
+ $ig =~ s,/$,,;
+ return 1 if ($pkg =~ /$ig/);
+ }
+ }
+ return 0
+}
+
+sub filter_ignored {
+ my ($packages, $ignores) = @_;
+
+ my $obs = $packages->{'obsolete'};
+
+ my (%ignored, %bad);
+ for my $pkg (keys %$obs) {
+ if (check_ignore($pkg, $ignores)) {
+ $ignored{$pkg} = $obs->{$pkg};
+ } else {
+ $bad{$pkg} = $obs->{$pkg};
+ };
+ }
+ delete $packages->{'obsolete'};
+ $packages->{'obsolete'} = \%bad;
+ $packages->{'obsolete-ignored'} = \%ignored;
+};
+
+sub usage {
+ my ($fd, $exit) = @_;
+ print $fd "Usage: $PROGRAM_NAME [<ignorefile>]\n";
+ exit $exit;
+}
+
+my $ignorefile = $IGNORE;
+my $ignorefile_userset = 0;
+usage(\*STDERR, 1) if (@ARGV > 1);
+if (@ARGV == 1) {
+ usage(\*STDOUT, 0) if ($ARGV[0] eq "-h");
+ usage(\*STDOUT, 0) if ($ARGV[0] eq "--help");
+ $ignorefile = $ARGV[0];
+ $ignorefile_userset = 1;
+};
+
+my $ignores = load_ignores($ignorefile, $ignorefile_userset);
+my $packages = get_packages();
+
+filter_ignored($packages, $ignores);
+
+
+
+my @reportform = (
+ { 'key' => 'obsolete',
+ 'listpackages' => 1,
+ 'long' => "%d local or obsolete packages: %s",
+ 'short' => "%d obs",
+ 'status' => 'WARNING' },
+ { 'key' => 'outofdate',
+ 'listpackages' => 1,
+ 'long' => "%d out of date packages: %s",
+ 'short' => "%d updates",
+ 'status' => 'WARNING' },
+ { 'key' => 'current',
+ 'listpackages' => 0,
+ 'long' => "%d packages current.",
+ 'short' => "%d ok",
+ 'status' => 'OK' },
+ { 'key' => 'obsolete-ignored',
+ 'listpackages' => 1,
+ 'long' => "%d whitelisted local or obsolete packages: %s",
+ 'short' => "%d obs(ignored)",
+ 'status' => 'OK' },
+ { 'key' => 'rc',
+ 'listpackages' => 1,
+ 'long' => "%d packages removed but not purged: %s",
+ 'short' => "%d rc",
+ 'status' => 'OK' },
+ { 'key' => 'hi',
+ 'listpackages' => 1,
+ 'long' => "%d packages on hold: %s",
+ 'short' => "%d hi",
+ 'status' => 'OK' },
+ { 'key' => 'pc',
+ 'listpackages' => 1,
+ 'long' => "%d packages requested to be purged but conffiles still installed: %s",
+ 'short' => "%d pc",
+ 'status' => 'WARNING' },
+ );
+
+my @longout;
+my @shortout;
+for my $form (@reportform) {
+ my $pkgs = $packages->{$form->{'key'}};
+ delete $packages->{$form->{'key'}};
+ my $num = scalar keys %$pkgs;
+ next unless ($num > 0);
+ if ($form->{'listpackages'}) {
+ my $list = join(", ", keys %$pkgs);
+ push @longout, sprintf($form->{'long'}, $num, $list);
+ } else {
+ push @longout, sprintf($form->{'long'}, $num);
+ };
+ push @shortout, sprintf($form->{'short'}, $num);
+ record($form->{'status'});
+};
+if (scalar keys %$packages) {
+ record('WARNING');
+ unshift @shortout, "unk: ".join(", ", keys %$packages);
+ for my $status (sort {$b cmp $a} keys %$packages) {
+ my $pkgs = $packages->{$status};
+ my $list = join(", ", keys %$pkgs);
+ unshift @longout, "Unknown package status $status: $list";
+ };
+}
+
+my $shortout = $EXITCODE.": ".join(", ", @shortout);
+my $longout = join("\n", @longout);
+
+print $shortout,"\n";
+print $longout,"\n";
+
+exit $CODE{$EXITCODE};
--- /dev/null
+#!/usr/bin/env ruby
+
+require 'optparse'
+
+class CheckPuppet
+
+ VERSION = '0.1'
+ script_name = File.basename($0)
+
+ # default options
+ OPTIONS = {
+ :statefile => "/var/lib/puppet/state/state.yaml",
+ :interval => 60,
+ }
+
+ o = OptionParser.new do |o|
+ o.set_summary_indent(' ')
+ o.banner = "Usage: #{script_name} [OPTIONS]"
+ o.define_head "The check_puppet Nagios plug-in checks that the specified " +
+ "puppet state file is no older than specified interval."
+ o.separator ""
+ o.separator "Mandatory arguments to long options are mandatory for " +
+ "short options too."
+
+ o.on("-s", "--statefile=statefile", String, "The state file",
+ "Default: #{OPTIONS[:statefile]}") { |OPTIONS[:statefile]| }
+ o.on("-i", "--interval=value", Integer,
+ "Default: #{OPTIONS[:interval]} minutes") { |OPTIONS[:interval]| }
+
+ o.separator ""
+ o.on_tail("-h", "--help", "Show this help message.") do
+ puts o
+ exit
+ end
+
+ o.parse!(ARGV)
+ end
+
+ def check_state
+
+ # Set variables
+ curt = Time.now
+ intv = OPTIONS[:interval] * 60
+
+ # Check file time
+ @modt = 0
+ begin
+ @modt = File.mtime("#{OPTIONS[:statefile]}")
+ rescue
+ @file = 3
+ end
+
+ diff = (curt - @modt).to_i
+
+ @file = 2
+ @file = 0 if diff <= intv
+
+ end
+
+ def output_status
+
+ case @file
+ when 0
+ state = "state file status okay updated on " + @modt.strftime("%m/%d/%Y at %H:%M:%S")
+ when 2
+ state = "state file is missing or older than #{OPTIONS[:interval]} minutes"
+ when 3
+ state = "state file status unknown"
+ end
+
+ case @file
+ when 0
+ status = "OK"
+ exitcode = 0
+ when 2
+ status = "CRITICAL"
+ exitcode = 2
+ when 3
+ status = "UNKNOWN"
+ exitcide = 3
+ end
+
+ puts "PUPPET " + status + ": " + state
+ exit(exitcode)
+ end
+end
+
+cp = CheckPuppet.new
+cp.check_state
+cp.output_status
+
--- /dev/null
+#!/usr/bin/perl -Tw
+
+# Copyright (C) 2006 Peter Palfrader <peter@palfrader.org>
+
+# Need to allow /usr/local/bin/tw_cli info c0 u0 status in sudoers:
+#
+# nagios ALL=(ALL) NOPASSWD: /usr/local/bin/tw_cli info c0 u0 status
+#
+
+use strict;
+use English;
+use Getopt::Long;
+
+$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
+delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
+
+my $TW_CLI = '/usr/local/bin/tw_cli';
+my $SVN_REVISION_STRING = '$Rev: 313 $';
+my ($SVN_REVISION) = ($SVN_REVISION_STRING =~ /([0-9]+)/);
+ $SVN_REVISION = 'unknown' unless defined $SVN_REVISION;
+my $VERSION = '0.0.0.'.$SVN_REVISION;
+
+# nagios exit codes
+my $UNKNOWN = -1;
+my $OK = 0;
+my $WARNING = 1;
+my $CRITICAL = 2;
+
+my $params = {
+ 'no-sudo' => 0,
+ 'controller' => 0,
+ 'unit' => 0
+ };
+
+Getopt::Long::config('bundling');
+if (!GetOptions (
+ '--help' => \$params->{'help'},
+ '--version' => \$params->{'version'},
+ '--verbose' => \$params->{'verbose'},
+ '--controller=i' => \$params->{'controller'},
+ '--unit=i' => \$params->{'unit'},
+ '--no-sudo' => \$params->{'no-sudo'},
+ )) {
+ die ("$PROGRAM_NAME: Usage: $PROGRAM_NAME [--help|--version] [--verbose] [--no-sudo] [--controller=<n>] [--unit=<n>]\n");
+};
+if ($params->{'help'}) {
+ print "$PROGRAM_NAME: Usage: $PROGRAM_NAME [--help|--version] [--verbose] [--no-sudo] [--controller=<n>] [--unit=<n>]\n";
+ print "Checks status of 3ware raid arrays.\n";
+ exit (0);
+};
+if ($params->{'version'}) {
+ print "nagios-check-raid-3ware $VERSION\n";
+ print "nagios check for 3ware raids\n";
+ print "Copyright (c) 2006 Peter Palfrader <peter\@palfrader.org>\n";
+ exit (0);
+};
+
+$SIG{'__DIE__'} = sub {
+ print STDERR @_;
+ exit $UNKNOWN;
+};
+
+unless (-e $TW_CLI) {
+ print "Cannot find '$TW_CLI'.\n";
+ exit $UNKNOWN;
+};
+
+my $sudo = $params->{'no-sudo'} ? '' : 'sudo ';
+my $command = "$sudo $TW_CLI info c$params->{'controller'} u$params->{'unit'} status";
+print STDERR "Running $command\n" if $params->{'verbose'};
+open (TW, "$command|") or die ("Cannot run $command: $!\n");
+my @tw=<TW>;
+close TW;
+if ($CHILD_ERROR) { # program failed
+ die("$command returned with non-zero exit code: ".($CHILD_ERROR / 256)."\n");
+};
+
+
+my $exit = $UNKNOWN;
+my $msg = '';
+for my $line (@tw) {
+ chomp $line;
+ next if $line =~ /^$/;
+ my ($device, $status) = $line =~ m#^(/c[0-9]+/u[0-9]+) status = ([A-Z]+)$#;
+ unless (defined($device) && defined($status)) {
+ print "Cannot parse line '$line'\n";
+ exit $UNKNOWN;
+ };
+ if ($status eq 'OK' ||
+ $status eq 'VERIFYING') {
+ $msg .= ($msg eq '' ? '' : '; '). "$device: $status";
+ $exit = $exit > $OK ? $exit : $OK;
+ } elsif ($status eq 'DEGRADED') {
+ $msg .= ($msg eq '' ? '' : '; '). "$device: $status";
+ $exit = $exit > $CRITICAL ? $exit : $CRITICAL;
+ } elsif ($status eq 'OFFLINE') {
+ $msg .= ($msg eq '' ? '' : '; '). "$device: $status";
+ $exit = $exit > $CRITICAL ? $exit : $CRITICAL;
+ } else {
+ $msg .= ($msg eq '' ? '' : '; '). "$device: UNKNOWN STATUS '$status'";
+ $exit = $exit > $UNKNOWN ? $exit : $UNKNOWN;
+ };
+};
+
+if ($msg eq '') {
+ $msg = "No devices found";
+ die ("exit is not UNKNOWN but $exit") if ($exit != $UNKNOWN);
+}
+
+print $msg,"\n";
+exit $exit;
--- /dev/null
+#!/usr/bin/perl
+
+# downloaded as check_areca from
+# http://www.nagiosexchange.org/cgi-bin/page.cgi?g=1486.html;d=1
+# on 20081001 by weasel.
+#
+# local changes: fix path to areca_cli
+
+#####################################################
+#Program to check the areca RAID controller for the status of the RAID
+#Created: 2007-11-27
+#Version: 1.1.0
+#Revised: 2008-07-23
+#Revised by: Erinn Looney-Triggs
+#Author: Erinn Looney-Triggs
+#Changelog:
+#1.1: Fixed issue with newer versions of the Areca CLI > 1.72 and
+#fixed a problem where the RAID name contained spaces
+#(Reported by Daniel Philipp). Also did a bit of cleanup.
+#####################################################
+
+use Carp;
+use English qw( -no_match_vars );
+use Getopt::Long; #Grab command line switches
+use Pod::Usage;
+use strict; #Do it right
+use warnings;
+
+$ENV{PATH} = '/usr/local/bin:/usr/bin:'; #Safer path
+my $areca_cli = '/usr/local/sbin/areca-cli';
+my $timeout = '10'; #Default timeout of 10 seconds
+my $VERSION = '1.1.0'; #Version number
+
+#Nagios plugin return values, in english
+my $OK = '0';
+my $WARNING = '1';
+my $CRITICAL = '2';
+my $UNKNOWN = '3';
+
+GetOptions( 'areca_cli|A=s' => \$areca_cli,
+ 'man' => sub { pod2usage(3) },
+ 'timeout|t=i' => \$timeout,
+ 'usage' => sub { pod2usage(1) },
+ 'version' => sub { VersionMessage() },
+ 'help' => sub { pod2usage(1) },
+);
+
+sanity_checks();
+parse_areca( check_areca() );
+
+sub check_areca{
+ my @output;
+
+ #Timer operation. Times out after $timeout seconds.
+ eval {
+
+ #Set the alarm and set the timeout
+ local $SIG{ALRM} = sub { die "alarm\n" };
+ alarm $timeout;
+
+ #Run the command
+ @output = `sudo $areca_cli vsf info`;
+ if ($?){
+ print "Command: cli vsf info failed, "
+ . "$OS_ERROR $CHILD_ERROR, aborting!\n";
+ exit $CRITICAL;
+ }
+
+ #Reset the alarm if successful
+ alarm 0;
+ };
+
+ #Test return value and exit if eval caught the alarm
+ if ($EVAL_ERROR) {
+ if ( $EVAL_ERROR eq "alarm\n" ) {
+ print "Operation timed out after $timeout seconds.\n";
+ exit $CRITICAL;
+ }
+ else {
+ print "An unknown error has occured: $EVAL_ERROR \n";
+ exit $UNKNOWN;
+ }
+ }
+
+ return @output;
+}
+
+sub parse_areca{
+ my @output = @_;
+
+ my $abnormal; #Holds count of non-normal returns
+
+ my @pertinent_lines = grep (/\s\d+\s/, @output);
+
+ for my $line (@pertinent_lines){
+ #Strip of leading spaces
+ $line =~ s/^\s+//;
+
+ #Split the line into discrete parts
+ my ( $number, $level, $capacity, $state, )
+ = (split (/\s+/, "$line"))[0,-4,-3,-1];
+
+ #If the state is normal continue on in loop
+ if (lc $state eq "normal"){
+ print "|Controller number: $number RAID level: $level "
+ . "Capacity: $capacity State: $state| ";
+ }
+
+ #If state is abnormal continue on in loop but add 1 to $abnormal
+ else{
+ print "|Controller number: $number RAID level: $level "
+ . "Capacity: $capacity State: $state| ";
+ $abnormal++;
+ }
+ }
+
+ #If any abnormalities exist ext with a critical error.
+ if ($abnormal){
+ exit $CRITICAL;
+ }
+ else {
+ exit $OK;
+ }
+
+ return; #This should never be reached
+}
+
+sub sanity_checks{
+ if (! -e $areca_cli){
+ print "$areca_cli does not exist, aborting!\n";
+ exit $CRITICAL;
+ }
+ if (! -x $areca_cli){
+ print "$areca_cli is not executable by the running user, aborting!\n";
+ exit $CRITICAL;
+ }
+
+ return; #This should never be reached
+}
+
+#Version message information displayed in both --version and --help
+sub main::VersionMessage {
+
+ print <<"EOF";
+This is version $VERSION of check_areca.
+
+Copyright (c) 2007-2008 Erinn Looney-Triggs (erinn.looneytriggs\@gmail.com).
+All rights reserved.
+
+This module is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License.
+See http://www.fsf.org/licensing/licenses/gpl.html
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+EOF
+
+ exit 1;
+}
+
+__END__
+
+=head1 NAME
+
+check_areca - Checks the status of an Areca RAID via the Areca CLI utility.
+
+=head1 VERSION
+
+This documentation refers to check_areca version 1.1.0
+
+=head1 USAGE
+
+check_areca.pl
+
+=head1 REQUIRED ARGUMENTS
+
+None
+
+=head1 OPTIONS
+
+ --areca_cli (-A) Set the location of the Areca cli executable.
+ --help Display usage information.
+ --man Display the entire POD documentation
+ --timeout (-t) Sets the timeout, defaults to 10 seconds.
+ --usage Display usage information (same as --help)
+ --version Display the version number
+
+
+=head1 DESCRIPTION
+
+This is a Nagios plugin that runs the Areca CLI to check the status of the
+RAID controller. It then parses the resultant exit information and
+passes the output to NRPE.
+
+=head1 DIAGNOSTICS
+
+=head2 Command: cli vsf info failed, aborting!
+
+For some reason the command trying to be run failed. Try running it by hand
+and seeing if it runs properly.
+
+=head2 Operation timed out after <timeout> seconds.
+
+Running the command failed after a certain amount of time (defaults to 10
+seconds). Try using the --timeout (-t) switch and increasing the timeout
+threshold. Also try running the command by hand and see if it is hanging.
+
+=head2 An unknown error has occurred:
+
+Just what it says, running the cli command threw an unknown error and the
+process died. Run the CLI command by hand and see if you receive proper
+output.
+
+=head2 <areca cli> does not exist, aborting!
+
+The binary that the script is looking to run does not exist. By default
+check_areca looks in /usr/local/areca/bin/ for the cli. However, you can
+change this default by setting the --areca_cli (-A) flag from the command
+line
+
+=head2 <areca cli> is not executable by the running user, aborting!
+
+The cli program was found but it is not executable by the current user,
+usually this is the nagios user.
+
+=head1 CONFIGURATION AND ENVIRONMENT
+
+The Areca cli program should be available on the system. By default
+check_areca looks in /usr/local/areca/bin/cli for the cli. You can set the
+location using the --areca_cli (-A) flag from the command line.
+
+It is helpful to have an Areca RAID controller on the system being checked.
+
+=head1 DEPENDENCIES
+
+ check_areca depends on the following modules:
+ POSIX Standard Perl 5.8 module
+ Getopt::Long Standard Perl 5.8 module
+ Pod::USAGE Standard Perl 5.8 module
+
+=head1 INCOMPATIBILITIES
+
+None known yet.
+
+=head1 BUGS AND LIMITATIONS
+
+Bugs, never heard of 'em ;).
+If you encounter any bugs let me know. (erinn.looneytriggs@gmail.com)
+
+=head1 AUTHOR
+
+Erinn Looney-Triggs (erinn.looneytriggs@gmail.com)
+
+=head1 LICENCE AND COPYRIGHT
+
+Copyright (c) 2007-2008 Erinn Looney-Triggs (erinn.looneytriggs@gmail.com).
+All rights reserved.
+
+This module is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License.
+See L<http://www.fsf.org/licensing/licenses/gpl.html>.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- /dev/null
+#!/bin/sh
+
+# Nagios check for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
+#
+# Some background information on the driver is available at
+# http://home.germany.net/100-120220/mylex/DAC960.README
+#
+# Written 2008 Peter Palfrader
+
+if [ -e /proc/rd/status ]; then
+ status=`cat /proc/rd/status`
+ if [ "$status" = "OK" ]; then
+ echo "OK: all DAC960 controllers operating normally; no (non-standby) failures have occurred"
+ exit 0;
+ else
+ echo "CRITICAL: proc/rd/status is $status"
+ exit 2;
+ fi;
+else
+ echo "UNKNOWN: No DAC960 controllers in the system"
+ exit 3;
+fi
--- /dev/null
+#!/usr/bin/perl -Tw
+
+# Copyright (C) 2008 Peter Palfrader <peter@palfrader.org>
+
+# Need to allow /usr/local/bin/tw_cli info c0 u0 status in sudoers:
+#
+# nagios ALL=(ALL) NOPASSWD: /usr/sbin/mpt-status -s
+#
+
+use strict;
+use English;
+use Getopt::Long;
+
+$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
+delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
+
+my $MPT_STATUS = '/usr/sbin/mpt-status';
+
+# nagios exit codes
+my $UNKNOWN = -1;
+my $OK = 0;
+my $WARNING = 1;
+my $CRITICAL = 2;
+
+$SIG{'__DIE__'} = sub {
+ print STDERR @_;
+ exit $UNKNOWN;
+};
+
+unless (-e $MPT_STATUS) {
+ print "Cannot find '$MPT_STATUS'.\n";
+ exit $UNKNOWN;
+};
+
+my $command = "sudo $MPT_STATUS -s";
+open (MPT, "$command|") or die ("Cannot run $command: $!\n");
+my @tw=<MPT>;
+close MPT;
+if ($CHILD_ERROR) { # program failed
+ die("$command returned with non-zero exit code: ".($CHILD_ERROR / 256)."\n");
+};
+
+
+my $exit = $UNKNOWN;
+my $msg = '';
+for my $line (@tw) {
+ chomp $line;
+ next if $line =~ /^$/;
+ my ($device, $num, $status) = $line =~ m#^(log_id|vol_id|phys_id)\s+([0-9]+)\s+(.*)$#;
+ unless (defined($device) && defined($num) && defined($status)) {
+ print "Cannot parse line '$line'\n";
+ exit $UNKNOWN;
+ };
+ if ($status eq 'OPTIMAL' ||
+ $status eq 'ONLINE') {
+ $msg .= ($msg eq '' ? '' : '; '). "$device $num: $status";
+ $exit = $exit > $OK ? $exit : $OK;
+ } else {
+ $msg .= ($msg eq '' ? '' : '; '). "$device $num: $status";
+ $exit = $exit > $CRITICAL ? $exit : $CRITICAL;
+ };
+};
+
+if ($msg eq '') {
+ $msg = "No devices found";
+ die ("exit is not UNKNOWN but $exit") if ($exit != $UNKNOWN);
+}
+
+print $msg,"\n";
+exit $exit;
--- /dev/null
+#!/usr/bin/perl -w
+# ------------------------------------------------------------------------------
+# File Name: chech_raid.pl
+# Author: Thomas Nilsen - Norway
+# Date: 14/06/2003
+# Version: 0.1
+# Description: This script will check to see if any software raid
+# devices are down.
+# Email: thomas.nilsen@doc-s.co.uk
+# WWW: www.doc-s.co.uk
+# ------------------------------------------------------------------------------
+# Copyright 2003 (c) Thomas Nilsen
+# Credits go to Ethan Galstad for coding Nagios
+# License GPL
+# ------------------------------------------------------------------------------
+# Date Author Reason
+# ---- ------ ------
+# 2008-03-31 Peter Palfrader Return warning on running resync
+# 2007-11-07 Peter Palfrader Return unknown if /proc/mdstat does not exist
+# 05/10/2004 Peter Palfrader Make it work without that 'use util (vars)'
+# 14/06/2003 TN Initial Release
+# - Format of mdstat assumed to be "2 line" per
+# device with [??] on the second line.
+# ------------------------------------------------------------------------------
+
+use strict;
+use warnings;
+use Getopt::Long;;
+use vars qw($opt_V $opt_h $opt_t $opt_F $PROGNAME);
+use lib '/usr/local/nagios/libexec/';
+my $TIMEOUT=15;
+my %ERRORS = ( OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => -1 );
+
+
+$PROGNAME="check_raid";
+
+sub print_help ();
+sub print_usage ();
+
+$ENV{'PATH'}='';
+$ENV{'BASH_ENV'}='';
+$ENV{'ENV'}='';
+my ( $line, $stat, $state ,@device, $msg, $status, $timeout);
+
+$stat="/proc/mdstat";
+
+#Option checking
+Getopt::Long::Configure('bundling');
+$status = GetOptions(
+ "V" => \$opt_V, "version" => \$opt_V,
+ "h" => \$opt_h, "help" => \$opt_h,
+ "F" => \$opt_F, "filename" => \$opt_F,
+ "t" => \$opt_t, "timeout" => \$opt_t);
+# Version
+if ($opt_V) {
+ print($PROGNAME,': $Revision: 0.1 $');
+ exit $ERRORS{'OK'};
+}
+# Help
+if ($opt_h) {
+ print_help();
+ exit $ERRORS{'OK'};
+}
+# Filename supplied
+if ($opt_F) {
+ $opt_F = shift;
+ $stat = $1 if ($opt_F =~ /^(.*)$/);
+
+ if ( ! -r $stat ) {
+ print "Invalid mdstat file: $opt_F\n";
+ exit $ERRORS{'UNKNOWN'};
+ }
+}
+
+$timeout = $TIMEOUT;
+($opt_t) && ($opt_t =~ /^([0-9]+)$/) && ($timeout = $1);
+
+# Just in case of problems, let's not hang Nagios
+$SIG{'ALRM'} = sub {
+ print ("ERROR: No response (alarm)\n");
+ exit $ERRORS{'UNKNOWN'};
+};
+alarm($timeout);
+
+# Start checking the file...
+open (FH, $stat) or print("UNKNOWN: Cannot open $stat: $!\n"), exit $ERRORS{'UNKNOWN'};
+
+my @failed = ();
+my @resyncing = ();
+my $device = '';
+
+# Now check the mdstat file..
+while (<FH>) {
+ $line = $_;
+ if ($line =~ /^(md\S*) /) {
+ $device = $1;
+ } elsif( $line =~ / \[_|_\]|U_|_U /) {
+ push @failed, $device;
+ }
+ elsif ( $line =~ / resync /) {
+ # [==>..................] resync = 10.3% (15216320/146994624) finish=2153.2min speed=1018K/sec
+ my ($percent) = ($line =~ m# resync = ([0-9.]+%)#);
+ my ($finish) = ($line =~ m# finish=([0-9.]+min)#);
+ my ($speed) = ($line =~ m# speed=([0-9.]+K/sec)#);
+ push @resyncing, "$device ($percent done, finish in $finish at $speed)";
+ }
+}
+close (FH);
+
+if (scalar @failed > 0) {
+ if (scalar @failed == 1) {
+ print "CRITICAL - Device $failed[0] has failed.\n";
+ } else {
+ print "CRITICAL - Devices ".join(", ", @failed)." have failed.\n"
+ };
+ exit $ERRORS{'CRITICAL'};
+} elsif (scalar @resyncing > 0 ) {
+ print "WARNING: Resyncing: ".(join "; ", @resyncing)."\n";
+ exit $ERRORS{'WARNING'};
+} else {
+ print "OK - All devices are online\n";
+ exit $ERRORS{'OK'};
+};
+
+
+sub print_usage () {
+ print "Usage: $PROGNAME -t <timeout> -F <filename>\n";
+}
+
+sub print_help () {
+ print_revision($PROGNAME,'$Revision: 0.1 $');
+ print "Copyright (c) 2003 Thomas Nilsen/Karl DeBisschop\n";
+ print "\n";
+ print_usage();
+ print "Checks the mdstat file for errors on any configured software raid.\n
+-t ( --timeout=INTEGER)
+ Seconds before script times out (default: 10)\n
+-F ( --filename=FILE)
+ Full path and name to mdstat file (usually '/proc/mdstat') \n\n";
+}
--- /dev/null
+#!/bin/bash
+
+# Check if the running kernel has the same version string as the on-disk
+# kernel image.
+
+# Copyright 2008 Peter Palfrader
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+OK=0;
+WARNING=1;
+CRITICAL=2;
+UNKNOWN=3;
+
+get_offset() {
+ local file needle
+
+ file="$1"
+ needle="$2"
+ perl -e '
+ undef $/;
+ $i = index(<>, "'"$needle"'");
+ if ($i < 0) {
+ exit 1;
+ };
+ print $i,"\n"' < "$file"
+}
+
+get_image() {
+ local image GZHDR1 GZHDR2 off
+
+ image="$1"
+
+ GZHDR1="\x1f\x8b\x08\x00"
+ GZHDR2="\x1f\x8b\x08\x08"
+
+ off=`get_offset "$image" $GZHDR1`
+ [ "$?" != "0" ] && off="-1"
+ if [ "$off" -eq "-1" ]; then
+ off=`get_offset "$image" $GZHDR2`
+ [ "$?" != "0" ] && off="-1"
+ fi
+ if [ "$off" -eq "0" ]; then
+ zcat < "$image"
+ return
+ elif [ "$off" -ne "-1" ]; then
+ (dd ibs="$off" skip=1 count=0 && dd bs=512k) < "$image" 2>/dev/null | zcat 2>/dev/null
+ return
+ fi
+
+ echo "ERROR: Unable to extract kernel image." 2>&1
+ exit 1
+}
+
+searched=""
+for on_disk in \
+ "/boot/vmlinuz-`uname -r`"\
+ "/boot/vmlinux-`uname -r`"; do
+
+ if [ -e "$on_disk" ]; then
+ on_disk_version="`get_image "$on_disk" | strings | grep 'Linux version' | head -n1`"
+ [ -z "$on_disk_version" ] || break
+ on_disk_version="`cat "$on_disk" | strings | grep 'Linux version' | head -n1`"
+ [ -z "$on_disk_version" ] || break
+
+ echo "UNKNOWN: Failed to get a version string from image $on_disk"
+ exit $UNKNOWN
+ fi
+ searched="$searched $on_disk"
+done
+
+if ! [ -e "$on_disk" ]; then
+ echo "WARNING: Did not find a kernel image (checked$searched) - I have no idea which kernel I am running"
+ exit $WARNING
+fi
+
+
+running_version="`cat /proc/version`"
+if [ -z "$running_version" ] ; then
+ echo "UNKNOWN: Failed to get a version string from running system"
+ exit $UNKNOWN
+fi
+
+if [ "$running_version" != "$on_disk_version" ]; then
+ echo "WARNING: Running kernel does not match on-disk kernel image: [$running_version != $on_disk_version]"
+ exit $WARNING
+else
+ echo "OK: Running kernel matches on disk image: [$running_version]"
+ exit $OK
+fi
--- /dev/null
+#!/usr/bin/perl -w
+
+# check_samhain.pl - check to see how many policy violations are reported
+# by the samhain file integrity checker.
+#
+# Copyright Rainer Wichmann (2004)
+# Copyright Martin Zobel-Helas (2008)
+#
+# License Information:
+# 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+############################################################################
+
+# -------------------------------------------------------------------[ Uses ]--
+
+use strict;
+use Getopt::Long;
+use vars qw($PROGNAME $SAMHAIN $opt_V $opt_h $opt_v $verbose $opt_w $opt_c $opt_t $status $msg $state $retval);
+use lib "/usr/lib/nagios/plugins";
+use utils qw(%ERRORS &print_revision);
+
+#my $TIMEOUT = 15;
+#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4);
+#sub print_revision ($$);
+
+# ----------------------------------------------------[ Function Prototypes ]--
+
+sub print_help ();
+sub print_usage ();
+sub process_arguments ();
+
+# ------------------------------------------------------------[ Environment ]--
+
+$ENV{'PATH'}='';
+$ENV{'BASH_ENV'}='';
+$ENV{'ENV'}='';
+
+# -----------------------------------------------------------------[ Global ]--
+
+$PROGNAME = "dsa-check-samhain";
+$SAMHAIN = "/usr/sbin/samhain";
+
+# ----------------------------------------------------------------[ options ]--
+
+Getopt::Long::Configure('bundling');
+$status = process_arguments();
+if ($status){
+ print "ERROR: processing arguments\n";
+ exit $ERRORS{"UNKNOWN"};
+}
+
+# ----------------------------------------------------------------[ timeout ]--
+
+$SIG{'ALRM'} = sub {
+ print ("ERROR: timed out waiting for $SAMHAIN\n");
+ exit $ERRORS{"WARNING"};
+};
+alarm($opt_t);
+
+# ----------------------------------------------------------[ start samhain ]--
+
+if ( defined $SAMHAIN && -x $SAMHAIN ) {
+ if (! open (SHPIPE, "/usr/bin/sudo $SAMHAIN -t check --foreground -p err -s none -l none -m none 2>&1 | " ) ) {
+ print "ERROR: could not popen $SAMHAIN \n";
+ exit $ERRORS{'UNKNOWN'};
+ }
+}else{
+ print "ERROR: Could not find samhain executable!\n";
+ exit $ERRORS{'UNKNOWN'};
+}
+
+# ---------------------------------------------------------[ read from pipe ]--
+
+$status = 0;
+
+while (<SHPIPE>) {
+ if (/POLICY/) {
+ ++$status;
+ print $_ if $verbose;
+ }
+}
+
+if ($status < $opt_w) {
+ $msg = "OK: $status policy violations (threshold $opt_w/$opt_c)";
+ $state = $ERRORS{'OK'};
+} elsif ($status >= $opt_w && $status < $opt_c) {
+ $msg = "WARNING: $status policy violations (threshold w=$opt_w)";
+ $state = $ERRORS{'WARNING'};
+} else {
+ $msg = "CRITICAL: $status policy violations (threshold w=$opt_w)";
+ $state = $ERRORS{'CRITICAL'};
+}
+
+# -------------------------------------------------------------[ close pipe ]--
+
+close (SHPIPE);
+
+# declare an error if we also get a non-zero return code from samhain
+
+if ( $? ) {
+ $retval = $? / 256;
+ if ( $! ) {
+ print "Error closing $SAMHAIN: $!\n" if $verbose;
+ } else {
+ print "$SAMHAIN returned exit status $retval\n" if $verbose;
+ }
+ if ($state == $ERRORS{"CRITICAL"}) {
+ $state = $ERRORS{"CRITICAL"};
+ } else {
+ print "ERROR: $SAMHAIN exit status $retval\n";
+ exit $ERRORS{'UNKNOWN'};
+ }
+}
+
+# -------------------------------------------------------------------[ exit ]--
+
+print "$msg | 'policy violations'=$status;$opt_w;$opt_c\n";
+exit $state;
+
+
+# ------------------------------------------------------------[ Subroutines ]--
+
+sub process_arguments(){
+ GetOptions
+ ("V" => \$opt_V, "version" => \$opt_V,
+ "h" => \$opt_h, "help" => \$opt_h,
+ "v" => \$opt_v, "verbose" => \$opt_v,
+ "w=i" => \$opt_w, "warning=i" => \$opt_w,
+ "c=i" => \$opt_c, "critical=i" => \$opt_c,
+ "t=i" => \$opt_t, "timeout=i" => \$opt_t
+ );
+
+ if ($opt_V) {
+ print_revision($PROGNAME,'$Revision: 1.0 $ ');
+ exit $ERRORS{'OK'};
+ }
+
+ if ($opt_h) {
+ print_help();
+ exit $ERRORS{'OK'};
+ }
+
+ if (defined $opt_v ){
+ $verbose = $opt_v;
+ }
+
+ unless (defined $opt_t) {
+ $opt_t = $utils::TIMEOUT ; # default timeout
+ # $opt_t = $TIMEOUT ;
+ }
+
+ unless (defined $opt_w) {
+ $opt_w = 1;
+ }
+
+ unless (defined $opt_c) {
+ $opt_c = 1;
+ }
+
+ if ( $opt_w > $opt_c) {
+ print "Warning cannot be greater than Critical!\n";
+ exit $ERRORS{'UNKNOWN'};
+ }
+
+ return $ERRORS{'OK'};
+}
+
+sub print_usage () {
+ print "Usage: $PROGNAME [-w <warn>] [-c <crit>] [-t <timeout>]\n";
+}
+
+sub print_help () {
+ print_revision($PROGNAME, '$Revision: 1.0 $');
+ print "Copyright (c) 2004 Rainer Wichmann
+
+This plugin checks the number of policy violations reported by the
+samhain file intgrity checker
+
+";
+ print_usage();
+ print "
+-w, --warning=INTEGER
+ Minimum number of policy violations for which a WARNING status will result
+-c, --critical=INTEGER
+ Minimum number of policy violations for which a CRITICAL status will result
+-t, --timeout=SECONDS
+ The number of seconds after which a the plugin will timeout
+-v, --verbose
+ Verbose output
+-h, --help
+ Show this help message
+-V, --version
+ Show the version of the plugin
+
+";
+}
+
+#sub print_revision ($$) {
+# my $commandName = shift;
+# my $pluginRevision = shift;
+# $pluginRevision =~ s/^\$Revision: //;
+# $pluginRevision =~ s/ \$\s*$//;
+# print "$commandName (samhain 2.2.3) $pluginRevision\n";
+#}
--- /dev/null
+#!/usr/bin/ruby
+
+# Copyright 2006 Peter Palfrader
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+require 'resolv'
+require 'optparse'
+require 'yaml'
+
+NAGIOS_STATUS = { :OK => 0, :WARNING => 1, :CRITICAL => 2, :UNKNOWN => -1 };
+@verbose = 0;
+@additional_nameservers = []
+
+def show_help(parser, code=0, io=STDOUT)
+ program_name = File.basename($0, '.*')
+ io.puts "Usage: #{program_name} [options] <domainname> [<domainname> ...]"
+ io.puts parser.summarize
+ exit(code)
+end
+ARGV.options do |opts|
+ opts.on_tail("-h", "--help" , "Display this help screen") { show_help(opts) }
+ opts.on("-v", "--verbose" , String, "Be verbose") { @verbose += 1 }
+ opts.on("-a", "--add=HOST" , String, "Also check SOA on <nameserver>") { |val| @additional_nameservers << val }
+ opts.parse!
+end
+show_help(ARGV.options, 1, STDERR) if ARGV.length == 0
+
+warnings = []
+oks = []
+
+dns = Resolv::DNS.new
+ARGV.each{ |domain|
+ serial = []
+ nameservers = dns.getresources(domain, Resolv::DNS::Resource::IN::NS)
+ nameservernames = nameservers.collect{ |ns| ns.name.to_s }
+ nameservernames = nameservernames.concat @additional_nameservers
+ nameservernames.each{ |nameserver|
+ puts "Testing nameserver #{nameserver} for #{domain}" if @verbose > 0
+ arecords = dns.getresources(nameserver, Resolv::DNS::Resource::IN::A)
+ warnings << "Nameserver #{nameserver} for #{domain} has #{arecords.length} A records" if arecords.length != 1
+ arecords.each{ |a|
+ puts " Nameserver #{nameserver} is at #{a.address}" if @verbose > 0
+ begin
+ resolver = Resolv::DNS.new({:nameserver => a.address.to_s})
+ soas = resolver.getresources(domain, Resolv::DNS::Resource::IN::SOA)
+ rescue SystemCallError => e
+ warnings << "Could not resolve #{domain} on #{nameserver}: #{e.message}"
+ else
+ resolver.close
+ warnings << "Nameserver #{nameserver} for #{domain} returns #{soas.length} SOAs" if soas.length != 1
+ soas.each{ |soa|
+ puts " Nameserver #{nameserver} returns serial #{soa.serial} for #{domain}" if @verbose > 0
+ serial << soa.serial unless serial.include? soa.serial
+ }
+ end
+ }
+ }
+ case serial.length
+ when 0
+ warnings << "Found no serials for #{domain}"
+ when 1
+ oks << "#{domain} is at #{serial.first}"
+ else
+ warnings << "Nameservers disagree on serials for #{domain}: found #{serial.join(', ')}" if serial.length != 1
+ end
+}
+dns.close
+
+if warnings.length > 0
+ puts warnings.join('; ')
+ exit NAGIOS_STATUS[:WARNING]
+else
+ puts oks.join('; ')
+ exit NAGIOS_STATUS[:OK]
+end
--- /dev/null
+#!/usr/bin/ruby
+
+# Relay the status of a check that was previously run and which stored
+# its result in a file to nagios.
+#
+# Copyright 2008 Peter Palfrader
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+require 'resolv'
+require 'optparse'
+
+NAGIOS_STATUS = { "OK" => 0, "WARNING" => 1, "CRITICAL" => 2, "UNKNOWN" => 3 }
+UNITS_TO_SECONDS = { 's' => 1, 'm' => 60, 'h' => 60*60, 'd' => 24*60*60 }
+
+def show_help(parser, code=0, io=STDOUT)
+ program_name = File.basename($0, '.*')
+ io.puts "Usage: #{program_name} [options] <statusfile>"
+ io.puts parser.summarize
+ exit(code)
+end
+
+max_age = "26h"
+ARGV.options do |opts|
+ opts.on_tail("-h", "--help" , "Display this help screen") { show_help(opts) }
+ opts.on("-a", "--age=AGE" , String, "maximum age, in seconds (or use Nm, Nh or Nd) - default is 26h") { |max_age| }
+ opts.parse!
+end
+show_help(ARGV.options, 1, STDERR) if ARGV.length != 1
+
+statusfile = ARGV.shift
+
+# find out what the max age is that we accept
+unless (m = /^([0-9]+)([smhd])?$/.match max_age)
+ STDERR.puts "Invalid age #{age}."
+ show_help(ARGV.options, 1, STDERR) if ARGV.length != 1
+end
+max_age = m[1].to_i * UNITS_TO_SECONDS[m[2] ? m[2] : 's']
+
+# let's see if it exists
+unless File.exists? statusfile
+ puts "UNKNOWN: #{statusfile} does not exist."
+ exit NAGIOS_STATUS['UNKNOWN']
+end
+
+
+mtime = File.stat(statusfile).mtime
+if mtime + max_age < Time.now
+ puts "WARNING: #{statusfile} is old: #{mtime}"
+ exit NAGIOS_STATUS['WARNING']
+end
+
+status = File.new(statusfile)
+returnvalue = status.readline.chomp
+
+unless NAGIOS_STATUS.has_key? returnvalue
+ puts "UNKNOWN: #{statusfile} has invalid return value: #{returnvalue}"
+ exit NAGIOS_STATUS['UNKNOWN']
+end
+
+status.readlines.each do |line|
+ print line
+end
+exit NAGIOS_STATUS[returnvalue]
--- /dev/null
+#!/usr/bin/perl -w
+
+use strict;
+my %CODE = (
+ 'UNDEF' => -1,
+ 'OK' => 0,
+ 'WARNING' => 1,
+ 'CRITICAL' => 2,
+ 'UNKNOWN' => 3
+);
+
+my $f;
+
+$SIG{__DIE__ } = sub() {
+ print shift;
+ exit $CODE{'UNKNOWN'};
+};
+
+if ( -e "/var/lib/misc/thishost/passwd.tdb" ) {
+ $f = "/var/lib/misc/thishost/passwd.tdb";
+} else {
+ my $hostname = `hostname -f`;
+ chomp $hostname;
+ $hostname =~ m/^([a-z]+(?:\.[a-z]+)+)$/;
+ die "Weird hostname '$hostname'\n" unless defined $1;
+ $hostname = $1;
+ if ( -e "/var/lib/misc/$hostname/passwd.tdb" ) {
+ $f = "/var/lib/misc/$hostname/passwd.tdb";
+ };
+};
+
+die "Could not find passwd.tdb" unless defined $f;
+
+my @stat = stat($f) or die ("Cannot stat $f: $!\n");
+my $age = time - $stat[10];
+my $hage;
+if ($age > 48 * 3600) {
+ $hage = sprintf("%.1f days", $age / 24 / 3600);
+} elsif ($age > 3600) {
+ $hage = sprintf("%.1f hours", $age / 3600);
+} else {
+ $hage = sprintf("%d minutes", $age / 60);
+};
+
+if ($age > 60*60) {
+ print "WARNING: ud-ldap info is $hage old\n";
+ exit $CODE{'WARNING'};
+};
+print "OK: ud-ldap info is $hage old\n";
+exit $CODE{'OK'};
* Replaces/Conflicts dsa-nagios-nrpe-config.
* Update description.
* No longer install nrpe_dsa.cfg.
+ * Move files into specific directories in source.
- -- Peter Palfrader <weasel@debian.org> Tue, 31 Mar 2009 19:15:45 +0200
+ -- Peter Palfrader <weasel@debian.org> Tue, 31 Mar 2009 19:19:14 +0200
dsa-nagios-nrpe-config (68) unstable; urgency=low
dh_clean -k
dh_installdirs
- install -m 755 dsa-check-hpacucli $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-raid-areca $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-raid-dac960 $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-raid-mpt $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-raid-sw $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-raid-3ware $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-running-kernel $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-config $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-dabackup $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-dabackup-server $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-udldap-freshness $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-statusfile $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-samhain $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-mirrorsync $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-soas $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
-
- install -m 755 dsa-check-puppet $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 755 dsa-check-packages $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins
- install -m 644 obsolete-packages-ignore $(CURDIR)/debian/dsa-nagios-nrpe-config/etc/nagios
-
- install -m 755 apt-status-check $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/share/dsa
- install -m 755 weak-ssh-keys-check $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/share/dsa
-
- install -m 755 dsa-update-apt-status $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/sbin
- install -m 755 dsa-update-samhain-status $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/sbin
+ for f in `ls -1 checks/*`; do \
+ install -m 755 $$f $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/lib/nagios/plugins; \
+ done
+
+ for f in `ls -1 etc/*`; do \
+ install -m 644 $$f $(CURDIR)/debian/dsa-nagios-nrpe-config/etc/nagios; \
+ done
+
+ for f in `ls -1 share/*`; do \
+ install -m 755 $$f $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/share/dsa; \
+ done
+
+ for f in `ls -1 sbin/*`; do \
+ install -m 755 $$f $(CURDIR)/debian/dsa-nagios-nrpe-config/usr/sbin; \
+ done
binary-indep: install
+++ /dev/null
-#!/bin/sh
-
-# Check that debian-admin is in /etc/aliases for root.
-# Peter Palfrader, 2008
-
-#my %ERRORS = ( OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => -1 );
-
-set -e
-err=0
-
-log() {
- if [ "$0" == "ok" ] && [ "$err" == 0 ]; then
- err=0
- elif [ "$1" == "warn" ] && [ "$err" -lt 1 ]; then
- err=1
- elif [ "$1" == "critical" ] && [ "$err" -lt 2 ]; then
- err=2
- elif [ "$1" == "unknown" ] && [ "$err" == 0 ]; then
- err=3
- fi
- if [ "`eval echo \\$$1`" = "" ]; then
- eval $1="\"$2\""
- else
- eval $1="\"`eval echo \\$$1`; $2\""
- fi
-}
-
-
-check_aliases() {
- if ! [ -e /etc/aliases ]; then
- log unknown "/etc/aliases not found"
- return
- fi
-
- if egrep '^root:.*debian-admin@debian.org' /etc/aliases > /dev/null; then
- log ok "debian-admin found in aliases"
- return
- fi
-
- log warn "debian-admin not found in root entry in aliases"
-}
-
-check_ldap_conf() {
- if ! [ -e /etc/ldap/ldap.conf ]; then
- log unknown "/etc/ldap/ldap.conf not found"
- return
- fi
-
- if egrep '^URI.*ldap://db.debian.org' /etc/ldap/ldap.conf > /dev/null &&
- egrep '^BASE.*dc=debian,dc=org' /etc/ldap/ldap.conf > /dev/null &&
- egrep '^TLS_CACERT.*/etc/ssl/certs/spi-cacert-2008.pem' /etc/ldap/ldap.conf > /dev/null &&
- egrep '^TLS_REQCERT.*hard' /etc/ldap/ldap.conf > /dev/null ; then
- log ok "ldap.conf configured properly"
- return
- fi
-
- log warn "ldap.conf does not have URI, BASE, TLS_CACERT, TLS_REQCERT all configured correctly"
-}
-
-check_aliases
-check_ldap_conf
-
-[ "$critical" = "" ] || echo -n "Critical: $critical; "
-[ "$warn" = "" ] || echo -n "Warning: $warn; "
-[ "$unknown" = "" ] || echo -n "Unknown: $unknown; "
-[ "$ok" = "" ] || echo -n "OK: $ok"
-echo
-exit $err
+++ /dev/null
-#!/usr/bin/perl -w
-
-# Check the status of da-backup backups
-# Copyright 2007 Stephen Gran <sgran@debian.org>
-# Copyright 2008 Peter Palfrader
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-use strict;
-use warnings;
-use English;
-use Getopt::Long;
-use Fcntl qw(:seek);
-
-my $DABACKUP_CONF = '/etc/da-backup.conf';
-my $MAX_AGE = 30*60*60;
-my $TOO_FRESH = 5*60;
-my %CODE = (
- 'UNDEF' => -1,
- 'OK' => 0,
- 'WARNING' => 1,
- 'CRITICAL' => 2,
- 'UNKNOWN' => 3
-);
-$SIG{__DIE__ } = sub() {
- print shift;
- exit $CODE{'UNKNOWN'};
-};
-
-
-my $EXITCODE = 'UNDEF';
-my %MESSAGE = ();
-
-sub problem($$$) {
- my ($code, $msg, $resource) = @_;
- $MESSAGE{$msg} = [] unless defined $MESSAGE{$msg};
- push @{$MESSAGE{$msg}}, $resource;
- $EXITCODE = ($CODE{$code} > $CODE{$EXITCODE}) ? $code : $EXITCODE;
-};
-
-
-sub help($$) {
- my ($exitcode, $fd) = @_;
- version ($fd, 0);
- print $fd "Usage: $PROGRAM_NAME --help\n";
- print $fd "Usage: $PROGRAM_NAME";
- exit $exitcode
-};
-
-my $params = {};
-
-Getopt::Long::config('bundling');
-if (!GetOptions (
- 'h|help' => \$params->{'help'},
- )) {
- die ("$PROGRAM_NAME: Usage: $PROGRAM_NAME [-fwhv]\n");
-};
-
-help(0, *STDOUT) if $params->{'help'};
-help(1, *STDERR) if scalar @ARGV > 0;
-
-
-unless (-e $DABACKUP_CONF) {
- if (-e '/etc/da-backup') {
- print "WARNING: No $DABACKUP_CONF, but we have /etc/da-backup/\n";
- exit $CODE{'WARNING'};
- };
- if (-e '/var/log/da-backup') {
- print "WARNING: No $DABACKUP_CONF, but we have /var/log/da-backup/\n";
- exit $CODE{'WARNING'};
- };
- print "OK: da-backup not installed\n";
- exit $CODE{'OK'};
-};
-
-my $confdir;
-my $logdir;
-
-open (FH, "< $DABACKUP_CONF") or die ("Cannot open $DABACKUP_CONF: $!\n");
-while (<FH>) {
- if (/confdir=(.*)/) {
- $confdir = $1;
- } elsif (/logdir=(.*)/) {
- $logdir = $1;
- };
-};
-
-die ("No confdir found in $DABACKUP_CONF") unless defined $confdir;
-die ("No logdir found in $DABACKUP_CONF") unless defined $logdir;
-
-opendir(DIR, $confdir) or die ("Cannot opendir $confdir: $!\n");
-my %conffiles = map {$_ => 1} grep { !/^\./ && !/\.bak$/} readdir(DIR);
-closedir(DIR);
-
-opendir(DIR, $logdir) or die ("Cannot opendir $logdir: $!\n");
-my %logfiles = map {$_ => 1} grep { !/^\./ && !/\.[0-9]+(\.gz)?$/} readdir(DIR);
-closedir(DIR);
-
-if (scalar keys %conffiles == 0) {
- print "WARNING: da-backup installed but no backups configured\n";
- exit $CODE{'WARNING'};
-};
-
-for my $f (keys %conffiles) {
- unless (exists $logfiles{$f}) {
- problem('WARNING', 'no log', $f);
- }
-}
-
-FILE:
-for my $f (sort {$a cmp $b} keys %logfiles) {
- unless (exists $conffiles{$f}) {
- problem('WARNING', 'no config', $f);
- next;
- }
-
- my @stat = stat("$logdir/$f") or die ("Cannot stat $logdir/$f: $!\n");
- my $age = time - $stat[10];
-
- if ($age < $TOO_FRESH) { # File is too new, let's use the old one
- if (-e "$logdir/$f.0") {
- $f .= ".0";
- my @stat = stat("$logdir/$f") or die ("Cannot stat $logdir/$f: $!\n");
- $age = time - $stat[10];
- };
- };
-
- if ($age < 0) {
- problem('WARNING', 'future timestamp', $f);
- next;
- } elsif ($age > $MAX_AGE) {
- my $hage;
-
- if ($age > 48 * 3600) {
- $hage = sprintf("%d days", $age / 24 / 3600);
- } else {
- $hage = sprintf("%d hours", $age / 3600);
- };
- problem('WARNING', 'old', "$f ($hage)");
- next;
- };
-
- open(FH, "< $logdir/$f") or die ("Cannot open $logdir/$f: $!\n");
- sysseek(FH, -1024, SEEK_END); # just try it - doesn't matter if it fails
- my $last2 = '';
- my $last = '';
- while (<FH>) {
- chomp;
- if (/^sent\s+\d+\s+bytes\s+received\s+\d+\s+bytes\s+[\d\.]+\s+bytes\/sec$/) {
- problem('OK', 'probably ok', $f);
- close(FH);
- next FILE;
- };
- $last2 = $last;
- $last = $_;
- };
- problem('CRITICAL', 'FAILED', "$f ($last2 $last)");
-};
-
-my $msg = join("; ", map {"$_: ".join(', ', @{$MESSAGE{$_}}) } (sort {$a cmp $b} keys %MESSAGE));
-print $EXITCODE, ": ", $msg, "\n";
-exit $CODE{$EXITCODE};
+++ /dev/null
-#!/bin/sh
-
-# some tests weasel uses to check if da-backup is properly configured:
-# Copyright 2008 Peter Palfrader
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-set -e
-set -u
-
-err=0
-
-log() {
- if [ "$1" == "warn" ] && [ "$err" -lt 1 ]; then
- err=1
- elif [ "$1" == "critical" ] && [ "$err" -lt 2 ]; then
- err=2
- elif [ "$1" == "unknown" ] && [ "$err" == 0 ]; then
- err=3
- fi
-}
-
-cd /etc/da-backup-manager
-
-# check that the files have proper names
-for i in *; do
- s=`cat "$i" | awk -F = '$1=="source" {print $2}'`
- if [ "$s" = "master.debian.org/debian" ] && [ "$i" = "listarchive" ]; then
- # historical exception
- continue
- fi
- if [ "`echo $s | tr / -`" != "$i" ]; then
- log warn
- echo "Mismatch: Filename $i but backup source $s"
- fi
-done
-
-# and that source == destination everywhere
-for i in *; do
- s=`cat $i | awk -F = '$1=="source"{print $2}'`
- d=`cat $i | awk -F = '$1=="destination"{print $2}'`
- if [ "$d" != "$s" ]; then
- log warn
- echo "source != dest in $i. ($s != $d)"
- fi
-done
-
-# check that everything that has an entry in authorized_keys has one in /etc/da-backup-manager
-rsync_targets=`tempfile`
-backup_manager_sources=`tempfile`
-trap "rm -f '$rsync_targets' '$backup_manager_sources'" 0 1 2 5 15
-cat /root/.ssh/authorized_keys |
- grep '^command=' |
- sed -e 's/",no-por.*//' -e 's/.*--ignore-errors . //' -e 's#/org/backup.debian.org/staging/##' |
- sort > "$rsync_targets"
-grep -h source /etc/da-backup-manager/* |
- sed -e 's/source=//' |
- sort > "$backup_manager_sources"
-if ! diff "$rsync_targets" "$backup_manager_sources" > /dev/null; then
- log warn
- echo "authorized_keys vs. /etc/da-backup-manage mismatch:"
- diff "$rsync_targets" "$backup_manager_sources"
-fi
-
-# check that everything listed as either source or destination by da-backup-manager does exist - if stuff is new it might still be missing tho
-for i in `awk -F = '$1=="source" {print $2}' /etc/da-backup-manager/* `; do
- if ! [ -d "/org/backup.debian.org/staging/$i" ]; then
- log warn
- echo "Warning: source $i does not exist"
- fi
-done
-for i in ` awk -F = '$1=="destination"{print $2}' /etc/da-backup-manager/* `; do
- if ! [ -d "/org/backup.debian.org/backups/$i" ]; then
- log warn
- echo "Warning: destination $i does not exist (if it is new, it takes a day)"
- fi
-done
-
-# check that everything that does exist has an entry in da-backup-manager
-cd /org/backup.debian.org/staging
-for i in */*; do
- if ! [ -d "$i" ]; then
- log warn
- echo "WTF: staging/$i is not a dir"
- continue
- fi
- if ! grep "source=$i" /etc/da-backup-manager/* > /dev/null; then
- log warn
- echo "staging/$i is not listed anywhere in /etc/da-backup-manager"
- fi
-done
-cd /org/backup.debian.org/backups
-for i in */*; do
- if ! [ -d "$i" ]; then
- log warn
- echo "WTF: backups/$i is not a dir"
- continue
- fi
- if ! grep "destination=$i" /etc/da-backup-manager/* > /dev/null; then
- log warn
- echo "backups/$i is not listed anywhere in /etc/da-backup-manager"
- fi
-done
-
-if [ "$err" = 0 ]; then
- echo "da-backup seems to be properly configured"
-fi
-exit $err
+++ /dev/null
-#!/usr/bin/perl -w
-
-# check _physical_ disk status of disks on HP smart array controllers
-# requires hpacucli
-#
-# does _not_ check raid status. use arrayprobe for that.
-
-# Copyright (c) 2008 Peter Palfrader <peter@palfrader.org>
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-use strict;
-
-# nagios exit codes
-my %CODE = (
- 'OK' => 0,
- 'WARNING' => 1,
- 'CRITICAL' => 2,
- 'UNKNOWN' => 3
-);
-
-my $EXITCODE = 'OK';
-
-$SIG{'__DIE__'} = sub {
- print STDERR @_;
- exit $CODE{'UNKNOWN'};
-};
-
-sub runcmd($) {
- my ($cmd) = @_;
- $cmd = "sudo hpacucli $cmd";
- open(FH, $cmd."|") or die ("Cannot run $cmd: $!");
- my @lines = <FH>;
- close FH;
- die ("no results from $cmd\n") if (scalar @lines == 0);
- return \@lines;
-}
-
-sub record($) {
- my ($newexit) = @_;
- die "code $newexit not defined\n" unless defined $CODE{$newexit};
-
- if ($CODE{$newexit} > $CODE{$EXITCODE}) {
- $EXITCODE = $newexit;
- };
-}
-
-
-my $ctrlallshow = runcmd("controller all show");
-my @controllers;
-for (@$ctrlallshow) {
- chomp;
- next if /^$/;
- if (/in Slot ([0-9]+) /) {
- push @controllers, $1;
- next;
- };
- die ("Cannot read line '$_' gotten from hpacucli controller all show\n");
-};
-
-if (scalar @controllers == 0) {
- print "UNKNONW: No smartarray controllers found with hpacucli\n";
- exit $CODE{'UNKNOWN'}
-};
-
-my @resultstr;
-
-for my $slot (sort @controllers) {
- my $pds = runcmd("controller slot=$slot pd all show");
- my @drives;
- my $nodrives = 0;
- my %status;
- for (@$pds) {
- chomp;
- next if /^$/;
- next if (/^\S.*in Slot $slot/);
- next if /^ *array [A-Z]$/;
- if (/^ *(array [A-Z]) \(Failed\)$/) {
- record('CRITICAL');
- push @{$status{'Failed'}}, $1;
- } elsif (/^Error: The specified controller does not have any physical drives on it.$/) {
- $nodrives = 1;
- } elsif (/^ *physicaldrive (\S+) .* (OK|Predictive Failure|Failed|Rebuilding)(?:, spare)?\)$/) {
- my $drive = $1;
- my $status = $2;
- push @{$status{$status}}, $drive;
- if ($status eq 'OK') {
- } elsif ($status eq 'Predictive Failure' ||
- $status eq 'Rebuilding') {
- record('WARNING');
- } elsif ($status eq 'Failed') {
- record('CRITICAL');
- } else {
- record('UNKNOWN');
- };
- push @drives, $drive;
- } else {
- die ("Cannot read line '$_' gotten from hpacucli controller slot=$slot pd all show\n");
- };
- };
-
- # Check that all drives have the proper transfer speed.
- # sometimes stuff breaks and they fall back to 10mb/sec.
- for my $drive (@drives) {
- # skip drives that are known to have failed
- next if (exists $status{'Failed'} && grep {$drive eq $_} @{$status{'Failed'}});
- my $type;
- if ($drive =~ /^[0-9]+:[0-9]+$/) { # scsi drives
- $type = 'SCSI';
- } elsif ($drive =~ /^[0-9]+I:[0-9]+:[0-9]+$/) { # SAS
- $type = 'SAS';
- } else {
- # I'm not going to run pass arguments of unknown form to the shell..
- warn ("Unknown diskdrive ID $drive\n");
- next;
- }
-
- my $pd = runcmd("controller slot=$slot pd $drive show");
- while (defined $pd->[0] && !($pd->[0] =~ /physicaldrive/)) {
- shift @$pd;
- };
- shift @$pd;
- my %value;
- for (@$pd) {
- if (m/^\s*(.*?):\s*(.*?)\s*$/) {
- $value{$1} = $2;
- }
- }
-
- my $key;
- my $expected;
- if ($type eq 'SCSI') {
- $key = 'Transfer Speed';
- if (!defined $value{'Transfer Mode'}) {
- record('WARNING');
- push @{$status{'unknown transfer mode'}}, $drive;
- next;
- } elsif ($value{'Transfer Mode'} eq 'Ultra 3 Wide') {
- $expected = '160 MB/Sec';
- } elsif ($value{'Transfer Mode'} eq 'Ultra 320 Wide') {
- $expected = '320 MB/Sec';
- } else {
- record('WARNING');
- push @{$status{'unknown transfer mode'}}, $drive."(".$value{'Transfer Mode'}.")";
- next;
- };
- } elsif ($type eq 'SAS') {
- $key = 'PHY Transfer Rate';
- if ($value{'PHY Count'} eq '2') {
- $expected = '3.0GBPS, Unknown';
- } else {
- $expected = '3.0GBPS';
- }
- } else {
- warn "Should not be here. Do not know what to do with type '$type'\n";
- next;
- }
-
- if (!defined $value{$key}) {
- record('WARNING');
- push @{$status{'unknown transfer speed'}}, $drive;
- } elsif ($value{$key} ne $expected) {
- record('WARNING');
- push @{$status{'bad transfer speed'}}, $drive."(".$value{$key}.")";
- };
- };
-
- if ($nodrives && scalar keys %status > 0) {
- push @resultstr, "Slot $slot: have no drives but status results?";
- record('UNKNOWN');
- next;
- } elsif ($nodrives) {
- push @resultstr, "Slot $slot: no drives";
- next;
- };
-
- my $cst = runcmd("controller slot=$slot show status");
- for (@$cst) {
- chomp;
- next if /^$/;
- next if (/^\S.*in Slot $slot/);
- if (/^ *(.*) Status: (.*)$/) {
- my $system = $1;
- my $status = $2;
- push @{$status{$status}}, $system;
- if ($status ne 'OK') {
- record('WARNING');
- };
- } else {
- die ("Cannot read line '$_' gotten from hpacucli controller slot=$slot show status\n");
- };
- };
-
- my $status = join(" - ", (map { $_.": ".join(", ", @{$status{$_}}) } keys %status));
- push @resultstr, "Slot $slot: $status";
-};
-
-print "$EXITCODE: ", join(" --- ", @resultstr), "\n";
-exit $CODE{$EXITCODE};
+++ /dev/null
-#!/usr/bin/perl -w
-
-# nagios check for debian security sync checks
-#
-# Copyright (c) 2008 Alexander Wirt <formorer@debian.org>
-# Copyright (c) 2009 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-
-use LWP::UserAgent;
-use Socket;
-use strict;
-use Date::Parse;
-use Getopt::Long;
-use Date::Parse;
-use Date::Format;
-use File::Basename;
-use English;
-use warnings;
-
-
-sub usage($$) {
- my ($fh, $exit) = @_;
- my $basename = basename($PROGRAM_NAME);
- my $VERSION = '0.1';
-
- print $fh "$basename $VERSION\n";
- print $fh "Usage: $basename [--help|--version] [--verbose]\n";
- print $fh "\n";
- print $fh " --help Print this short help.\n";
- print $fh " --version Report version number.\n";
- print $fh " --verbose Be a little verbose.\n";
- print $fh " --host hostname to check.\n";
- print $fh " --path path to tracefile.\n";
- print $fh "\n";
- exit ($exit);
-};
-
-
-$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
-delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
-
-my $params;
-
-$params->{'host'} = 'security.debian.org'; #which host to check
-$params->{'path'} = 'project/trace/security-master.debian.org';
-
-my $OK = 0;
-my $WARNING = 1;
-my $CRITICAL = 2;
-my $UNKNOWN = 3;
-
-if (!GetOptions (
- '--help' => \$params->{'help'},
- '--verbose' => \$params->{'verbose'},
- '--version' => \$params->{'version'},
- '--host=s' => \$params->{'host'},
- '--path=s' => \$params->{'path'},
- )) {
- usage(*STDERR,1)
-};
-usage(*STDOUT,0) if ($params->{'help'});
-usage(*STDERR,1) if (scalar @ARGV);
-
-my $host = $params->{'host'};
-my $path = $params->{'path'};
-my @slaves;
-my $status;
-my @exitstatus;
-my $exitcode = $OK;
-
-@slaves = gethostbyname($params->{'host'}) or die "Can't resolve " . $params->{'host'} .": $!\n";
-@slaves = map { inet_ntoa($_) } @slaves[4 .. $#slaves];
-print "Checking the following hosts:\n" . join("\n", @slaves) . "\n" if $params->{'verbose'};
-
-my @critical;
-
-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");
-
-
- if ($response->is_success) {
- my $content = $response->content; # or whatever
- my ($date, $foo, $bar) = split("\n", $content);
- my $synctime = str2time($date);;
- print "$slave last synced $synctime\n" if $params->{'verbose'};
- $status->{$slave}->{'synced'} = $synctime;
- }
- else {
- push @exitstatus, "$slave broken: " . $response->status_line;
- $status->{$slave}->{'error'} = $response->status_line;
- $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));
-} else {
- print "All mirrors unique\n" if $params->{'verbose'};
-}
-
-if ($exitcode == $CRITICAL) {
- print "CRITICAL: " . join(',',@exitstatus) . "\n";
-} elsif ($exitcode == $OK) {
- print "OK: all mirrors up2date\n";
-}
-
-foreach my $mirror (keys(%{$status})) {
- if ($status->{$mirror}->{'error'}) {
- print "$mirror broken: " . $status->{$mirror}->{'error'} . "\n";
- } else {
- print "$mirror last synced: " . localtime($status->{$mirror}->{'synced'}) ."\n";
- }
-}
-
-exit $exitcode;
+++ /dev/null
-#!/usr/bin/perl
-
-# dsa-check-packages
-
-# checks for obsolete/local and upgradeable packages.
-#
-# packages for the obsolete/local check can be ignored, by
-# listing their full name in /etc/nagios/obsolete-packages-ignore
-# or by having a regex (starting a line with "/") that matches
-# the packagename in said file.
-#
-# Takes one optional argument, the location of the ignore file.
-
-
-# Copyright (C) 2008, 2009 Peter Palfrader <peter@palfrader.org>
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-use strict;
-use warnings;
-use English;
-
-my $IGNORE = "/etc/nagios/obsolete-packages-ignore";
-
-my %CODE = (
- 'OK' => 0,
- 'WARNING' => 1,
- 'CRITICAL' => 2,
- 'UNKNOWN' => 3
-);
-my $EXITCODE = 'OK';
-sub record($) {
- my ($newexit) = @_;
- die "code $newexit not defined\n" unless defined $CODE{$newexit};
-
- if ($CODE{$newexit} > $CODE{$EXITCODE}) {
- $EXITCODE = $newexit;
- };
-}
-
-
-
-sub get_packages {
- $ENV{'COLUMNS'} = 1000;
- $ENV{'LC_ALL'} = 'C';
- open(F, "dpkg -l|") or die ("Cannot run dpkg: $!\n");
- my @lines = <F>;
- close(F);
- chomp(@lines);
-
- shift @lines while ($lines[0] !~ /\+\+\+/);
- shift @lines;
-
- my %pkgs;
- for my $line (@lines) {
- my ($state, $pkg, $version, undef) = split(/ */, $line);
- $pkgs{$state}{$pkg} = { 'installed' => $version }
- }
-
- my $installed = $pkgs{'ii'};
- delete $pkgs{'ii'};
-
- open my $olderr, ">&STDERR" or die "Can't dup STDERR: $!";
- open STDERR, ">/dev/null" or die "Can't dup STDOUT: $!";
-
- open (F, "apt-cache policy ".(join(" ", keys(%$installed)))." |") or die ("Cannot run apt-cache policy: $!\n");
- @lines = <F>;
- close(F);
- chomp(@lines);
- open STDERR, ">&", $olderr or die "Can't dup OLDERR: $!";
-
- my $line;
- my $pkgname = undef;
- while (defined($line = shift @lines)) {
- if ($line =~ /^([^ ]*):$/) {
- $pkgname = $1;
- } elsif ($line =~ /^ +Installed: (.*)$/) {
- # etch dpkg -l does not print epochs, so use this info, it's better
- $installed->{$pkgname}{'installed'} = $1;
- } elsif ($line =~ /^ +Candidate: (.*)$/) {
- $installed->{$pkgname}{'candidate'} = $1;
- } elsif ($line =~ /^ +\*\*\*/) {
- my @l;
- @l = split(/ +/, $line);
- $line = shift @lines;
- @l = split(/ +/, $line);
- $installed->{$pkgname}{'origin'} = $l[2];
- }
- }
-
- my (%current, %obsolete, %outofdate);
- for my $pkgname (keys %$installed) {
- my $pkg = $installed->{$pkgname};
-
- unless (defined($pkg->{'candidate'}) && defined($pkg->{'origin'})) {
- $obsolete{$pkgname} = $pkg;
- next;
- }
-
- if ($pkg->{'candidate'} ne $pkg->{'installed'}) {
- $outofdate{$pkgname} = $pkg;
- next;
- };
- if ($pkg->{'origin'} eq '/var/lib/dpkg/status') {
- $obsolete{$pkgname} = $pkg;
- next;
- }
- $current{$pkgname} = $pkg;
- }
-
- $pkgs{'current'} = \%current;
- $pkgs{'outofdate'} = \%outofdate;
- $pkgs{'obsolete'} = \%obsolete;
- return \%pkgs;
-}
-
-sub load_ignores {
- my ($ignorefile, $require_file) = @_;
-
- my @ignores;
- if (!$require_file and ! -e $ignorefile) {
- return \@ignores;
- }
-
- open (F, "< $ignorefile") or die ("Cannot open $ignorefile: $!\n");
- @ignores = <F>;
- close F;
- chomp(@ignores);
- return \@ignores;
-}
-
-sub check_ignore {
- my ($pkg, $ignores) = @_;
-
- my $ignore_this = 0;
- for my $ignore (@$ignores) {
- my $ig = $ignore;
- return 1 if ($ig eq $pkg);
- if (substr($ig,0,1) eq '/') {
- substr($ig, 0, 1, '');
- $ig =~ s,/$,,;
- return 1 if ($pkg =~ /$ig/);
- }
- }
- return 0
-}
-
-sub filter_ignored {
- my ($packages, $ignores) = @_;
-
- my $obs = $packages->{'obsolete'};
-
- my (%ignored, %bad);
- for my $pkg (keys %$obs) {
- if (check_ignore($pkg, $ignores)) {
- $ignored{$pkg} = $obs->{$pkg};
- } else {
- $bad{$pkg} = $obs->{$pkg};
- };
- }
- delete $packages->{'obsolete'};
- $packages->{'obsolete'} = \%bad;
- $packages->{'obsolete-ignored'} = \%ignored;
-};
-
-sub usage {
- my ($fd, $exit) = @_;
- print $fd "Usage: $PROGRAM_NAME [<ignorefile>]\n";
- exit $exit;
-}
-
-my $ignorefile = $IGNORE;
-my $ignorefile_userset = 0;
-usage(\*STDERR, 1) if (@ARGV > 1);
-if (@ARGV == 1) {
- usage(\*STDOUT, 0) if ($ARGV[0] eq "-h");
- usage(\*STDOUT, 0) if ($ARGV[0] eq "--help");
- $ignorefile = $ARGV[0];
- $ignorefile_userset = 1;
-};
-
-my $ignores = load_ignores($ignorefile, $ignorefile_userset);
-my $packages = get_packages();
-
-filter_ignored($packages, $ignores);
-
-
-
-my @reportform = (
- { 'key' => 'obsolete',
- 'listpackages' => 1,
- 'long' => "%d local or obsolete packages: %s",
- 'short' => "%d obs",
- 'status' => 'WARNING' },
- { 'key' => 'outofdate',
- 'listpackages' => 1,
- 'long' => "%d out of date packages: %s",
- 'short' => "%d updates",
- 'status' => 'WARNING' },
- { 'key' => 'current',
- 'listpackages' => 0,
- 'long' => "%d packages current.",
- 'short' => "%d ok",
- 'status' => 'OK' },
- { 'key' => 'obsolete-ignored',
- 'listpackages' => 1,
- 'long' => "%d whitelisted local or obsolete packages: %s",
- 'short' => "%d obs(ignored)",
- 'status' => 'OK' },
- { 'key' => 'rc',
- 'listpackages' => 1,
- 'long' => "%d packages removed but not purged: %s",
- 'short' => "%d rc",
- 'status' => 'OK' },
- { 'key' => 'hi',
- 'listpackages' => 1,
- 'long' => "%d packages on hold: %s",
- 'short' => "%d hi",
- 'status' => 'OK' },
- { 'key' => 'pc',
- 'listpackages' => 1,
- 'long' => "%d packages requested to be purged but conffiles still installed: %s",
- 'short' => "%d pc",
- 'status' => 'WARNING' },
- );
-
-my @longout;
-my @shortout;
-for my $form (@reportform) {
- my $pkgs = $packages->{$form->{'key'}};
- delete $packages->{$form->{'key'}};
- my $num = scalar keys %$pkgs;
- next unless ($num > 0);
- if ($form->{'listpackages'}) {
- my $list = join(", ", keys %$pkgs);
- push @longout, sprintf($form->{'long'}, $num, $list);
- } else {
- push @longout, sprintf($form->{'long'}, $num);
- };
- push @shortout, sprintf($form->{'short'}, $num);
- record($form->{'status'});
-};
-if (scalar keys %$packages) {
- record('WARNING');
- unshift @shortout, "unk: ".join(", ", keys %$packages);
- for my $status (sort {$b cmp $a} keys %$packages) {
- my $pkgs = $packages->{$status};
- my $list = join(", ", keys %$pkgs);
- unshift @longout, "Unknown package status $status: $list";
- };
-}
-
-my $shortout = $EXITCODE.": ".join(", ", @shortout);
-my $longout = join("\n", @longout);
-
-print $shortout,"\n";
-print $longout,"\n";
-
-exit $CODE{$EXITCODE};
+++ /dev/null
-#!/usr/bin/env ruby
-
-require 'optparse'
-
-class CheckPuppet
-
- VERSION = '0.1'
- script_name = File.basename($0)
-
- # default options
- OPTIONS = {
- :statefile => "/var/lib/puppet/state/state.yaml",
- :interval => 60,
- }
-
- o = OptionParser.new do |o|
- o.set_summary_indent(' ')
- o.banner = "Usage: #{script_name} [OPTIONS]"
- o.define_head "The check_puppet Nagios plug-in checks that the specified " +
- "puppet state file is no older than specified interval."
- o.separator ""
- o.separator "Mandatory arguments to long options are mandatory for " +
- "short options too."
-
- o.on("-s", "--statefile=statefile", String, "The state file",
- "Default: #{OPTIONS[:statefile]}") { |OPTIONS[:statefile]| }
- o.on("-i", "--interval=value", Integer,
- "Default: #{OPTIONS[:interval]} minutes") { |OPTIONS[:interval]| }
-
- o.separator ""
- o.on_tail("-h", "--help", "Show this help message.") do
- puts o
- exit
- end
-
- o.parse!(ARGV)
- end
-
- def check_state
-
- # Set variables
- curt = Time.now
- intv = OPTIONS[:interval] * 60
-
- # Check file time
- @modt = 0
- begin
- @modt = File.mtime("#{OPTIONS[:statefile]}")
- rescue
- @file = 3
- end
-
- diff = (curt - @modt).to_i
-
- @file = 2
- @file = 0 if diff <= intv
-
- end
-
- def output_status
-
- case @file
- when 0
- state = "state file status okay updated on " + @modt.strftime("%m/%d/%Y at %H:%M:%S")
- when 2
- state = "state file is missing or older than #{OPTIONS[:interval]} minutes"
- when 3
- state = "state file status unknown"
- end
-
- case @file
- when 0
- status = "OK"
- exitcode = 0
- when 2
- status = "CRITICAL"
- exitcode = 2
- when 3
- status = "UNKNOWN"
- exitcide = 3
- end
-
- puts "PUPPET " + status + ": " + state
- exit(exitcode)
- end
-end
-
-cp = CheckPuppet.new
-cp.check_state
-cp.output_status
-
+++ /dev/null
-#!/usr/bin/perl -Tw
-
-# Copyright (C) 2006 Peter Palfrader <peter@palfrader.org>
-
-# Need to allow /usr/local/bin/tw_cli info c0 u0 status in sudoers:
-#
-# nagios ALL=(ALL) NOPASSWD: /usr/local/bin/tw_cli info c0 u0 status
-#
-
-use strict;
-use English;
-use Getopt::Long;
-
-$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
-delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
-
-my $TW_CLI = '/usr/local/bin/tw_cli';
-my $SVN_REVISION_STRING = '$Rev: 313 $';
-my ($SVN_REVISION) = ($SVN_REVISION_STRING =~ /([0-9]+)/);
- $SVN_REVISION = 'unknown' unless defined $SVN_REVISION;
-my $VERSION = '0.0.0.'.$SVN_REVISION;
-
-# nagios exit codes
-my $UNKNOWN = -1;
-my $OK = 0;
-my $WARNING = 1;
-my $CRITICAL = 2;
-
-my $params = {
- 'no-sudo' => 0,
- 'controller' => 0,
- 'unit' => 0
- };
-
-Getopt::Long::config('bundling');
-if (!GetOptions (
- '--help' => \$params->{'help'},
- '--version' => \$params->{'version'},
- '--verbose' => \$params->{'verbose'},
- '--controller=i' => \$params->{'controller'},
- '--unit=i' => \$params->{'unit'},
- '--no-sudo' => \$params->{'no-sudo'},
- )) {
- die ("$PROGRAM_NAME: Usage: $PROGRAM_NAME [--help|--version] [--verbose] [--no-sudo] [--controller=<n>] [--unit=<n>]\n");
-};
-if ($params->{'help'}) {
- print "$PROGRAM_NAME: Usage: $PROGRAM_NAME [--help|--version] [--verbose] [--no-sudo] [--controller=<n>] [--unit=<n>]\n";
- print "Checks status of 3ware raid arrays.\n";
- exit (0);
-};
-if ($params->{'version'}) {
- print "nagios-check-raid-3ware $VERSION\n";
- print "nagios check for 3ware raids\n";
- print "Copyright (c) 2006 Peter Palfrader <peter\@palfrader.org>\n";
- exit (0);
-};
-
-$SIG{'__DIE__'} = sub {
- print STDERR @_;
- exit $UNKNOWN;
-};
-
-unless (-e $TW_CLI) {
- print "Cannot find '$TW_CLI'.\n";
- exit $UNKNOWN;
-};
-
-my $sudo = $params->{'no-sudo'} ? '' : 'sudo ';
-my $command = "$sudo $TW_CLI info c$params->{'controller'} u$params->{'unit'} status";
-print STDERR "Running $command\n" if $params->{'verbose'};
-open (TW, "$command|") or die ("Cannot run $command: $!\n");
-my @tw=<TW>;
-close TW;
-if ($CHILD_ERROR) { # program failed
- die("$command returned with non-zero exit code: ".($CHILD_ERROR / 256)."\n");
-};
-
-
-my $exit = $UNKNOWN;
-my $msg = '';
-for my $line (@tw) {
- chomp $line;
- next if $line =~ /^$/;
- my ($device, $status) = $line =~ m#^(/c[0-9]+/u[0-9]+) status = ([A-Z]+)$#;
- unless (defined($device) && defined($status)) {
- print "Cannot parse line '$line'\n";
- exit $UNKNOWN;
- };
- if ($status eq 'OK' ||
- $status eq 'VERIFYING') {
- $msg .= ($msg eq '' ? '' : '; '). "$device: $status";
- $exit = $exit > $OK ? $exit : $OK;
- } elsif ($status eq 'DEGRADED') {
- $msg .= ($msg eq '' ? '' : '; '). "$device: $status";
- $exit = $exit > $CRITICAL ? $exit : $CRITICAL;
- } elsif ($status eq 'OFFLINE') {
- $msg .= ($msg eq '' ? '' : '; '). "$device: $status";
- $exit = $exit > $CRITICAL ? $exit : $CRITICAL;
- } else {
- $msg .= ($msg eq '' ? '' : '; '). "$device: UNKNOWN STATUS '$status'";
- $exit = $exit > $UNKNOWN ? $exit : $UNKNOWN;
- };
-};
-
-if ($msg eq '') {
- $msg = "No devices found";
- die ("exit is not UNKNOWN but $exit") if ($exit != $UNKNOWN);
-}
-
-print $msg,"\n";
-exit $exit;
+++ /dev/null
-#!/usr/bin/perl
-
-# downloaded as check_areca from
-# http://www.nagiosexchange.org/cgi-bin/page.cgi?g=1486.html;d=1
-# on 20081001 by weasel.
-#
-# local changes: fix path to areca_cli
-
-#####################################################
-#Program to check the areca RAID controller for the status of the RAID
-#Created: 2007-11-27
-#Version: 1.1.0
-#Revised: 2008-07-23
-#Revised by: Erinn Looney-Triggs
-#Author: Erinn Looney-Triggs
-#Changelog:
-#1.1: Fixed issue with newer versions of the Areca CLI > 1.72 and
-#fixed a problem where the RAID name contained spaces
-#(Reported by Daniel Philipp). Also did a bit of cleanup.
-#####################################################
-
-use Carp;
-use English qw( -no_match_vars );
-use Getopt::Long; #Grab command line switches
-use Pod::Usage;
-use strict; #Do it right
-use warnings;
-
-$ENV{PATH} = '/usr/local/bin:/usr/bin:'; #Safer path
-my $areca_cli = '/usr/local/sbin/areca-cli';
-my $timeout = '10'; #Default timeout of 10 seconds
-my $VERSION = '1.1.0'; #Version number
-
-#Nagios plugin return values, in english
-my $OK = '0';
-my $WARNING = '1';
-my $CRITICAL = '2';
-my $UNKNOWN = '3';
-
-GetOptions( 'areca_cli|A=s' => \$areca_cli,
- 'man' => sub { pod2usage(3) },
- 'timeout|t=i' => \$timeout,
- 'usage' => sub { pod2usage(1) },
- 'version' => sub { VersionMessage() },
- 'help' => sub { pod2usage(1) },
-);
-
-sanity_checks();
-parse_areca( check_areca() );
-
-sub check_areca{
- my @output;
-
- #Timer operation. Times out after $timeout seconds.
- eval {
-
- #Set the alarm and set the timeout
- local $SIG{ALRM} = sub { die "alarm\n" };
- alarm $timeout;
-
- #Run the command
- @output = `sudo $areca_cli vsf info`;
- if ($?){
- print "Command: cli vsf info failed, "
- . "$OS_ERROR $CHILD_ERROR, aborting!\n";
- exit $CRITICAL;
- }
-
- #Reset the alarm if successful
- alarm 0;
- };
-
- #Test return value and exit if eval caught the alarm
- if ($EVAL_ERROR) {
- if ( $EVAL_ERROR eq "alarm\n" ) {
- print "Operation timed out after $timeout seconds.\n";
- exit $CRITICAL;
- }
- else {
- print "An unknown error has occured: $EVAL_ERROR \n";
- exit $UNKNOWN;
- }
- }
-
- return @output;
-}
-
-sub parse_areca{
- my @output = @_;
-
- my $abnormal; #Holds count of non-normal returns
-
- my @pertinent_lines = grep (/\s\d+\s/, @output);
-
- for my $line (@pertinent_lines){
- #Strip of leading spaces
- $line =~ s/^\s+//;
-
- #Split the line into discrete parts
- my ( $number, $level, $capacity, $state, )
- = (split (/\s+/, "$line"))[0,-4,-3,-1];
-
- #If the state is normal continue on in loop
- if (lc $state eq "normal"){
- print "|Controller number: $number RAID level: $level "
- . "Capacity: $capacity State: $state| ";
- }
-
- #If state is abnormal continue on in loop but add 1 to $abnormal
- else{
- print "|Controller number: $number RAID level: $level "
- . "Capacity: $capacity State: $state| ";
- $abnormal++;
- }
- }
-
- #If any abnormalities exist ext with a critical error.
- if ($abnormal){
- exit $CRITICAL;
- }
- else {
- exit $OK;
- }
-
- return; #This should never be reached
-}
-
-sub sanity_checks{
- if (! -e $areca_cli){
- print "$areca_cli does not exist, aborting!\n";
- exit $CRITICAL;
- }
- if (! -x $areca_cli){
- print "$areca_cli is not executable by the running user, aborting!\n";
- exit $CRITICAL;
- }
-
- return; #This should never be reached
-}
-
-#Version message information displayed in both --version and --help
-sub main::VersionMessage {
-
- print <<"EOF";
-This is version $VERSION of check_areca.
-
-Copyright (c) 2007-2008 Erinn Looney-Triggs (erinn.looneytriggs\@gmail.com).
-All rights reserved.
-
-This module is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License.
-See http://www.fsf.org/licensing/licenses/gpl.html
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-EOF
-
- exit 1;
-}
-
-__END__
-
-=head1 NAME
-
-check_areca - Checks the status of an Areca RAID via the Areca CLI utility.
-
-=head1 VERSION
-
-This documentation refers to check_areca version 1.1.0
-
-=head1 USAGE
-
-check_areca.pl
-
-=head1 REQUIRED ARGUMENTS
-
-None
-
-=head1 OPTIONS
-
- --areca_cli (-A) Set the location of the Areca cli executable.
- --help Display usage information.
- --man Display the entire POD documentation
- --timeout (-t) Sets the timeout, defaults to 10 seconds.
- --usage Display usage information (same as --help)
- --version Display the version number
-
-
-=head1 DESCRIPTION
-
-This is a Nagios plugin that runs the Areca CLI to check the status of the
-RAID controller. It then parses the resultant exit information and
-passes the output to NRPE.
-
-=head1 DIAGNOSTICS
-
-=head2 Command: cli vsf info failed, aborting!
-
-For some reason the command trying to be run failed. Try running it by hand
-and seeing if it runs properly.
-
-=head2 Operation timed out after <timeout> seconds.
-
-Running the command failed after a certain amount of time (defaults to 10
-seconds). Try using the --timeout (-t) switch and increasing the timeout
-threshold. Also try running the command by hand and see if it is hanging.
-
-=head2 An unknown error has occurred:
-
-Just what it says, running the cli command threw an unknown error and the
-process died. Run the CLI command by hand and see if you receive proper
-output.
-
-=head2 <areca cli> does not exist, aborting!
-
-The binary that the script is looking to run does not exist. By default
-check_areca looks in /usr/local/areca/bin/ for the cli. However, you can
-change this default by setting the --areca_cli (-A) flag from the command
-line
-
-=head2 <areca cli> is not executable by the running user, aborting!
-
-The cli program was found but it is not executable by the current user,
-usually this is the nagios user.
-
-=head1 CONFIGURATION AND ENVIRONMENT
-
-The Areca cli program should be available on the system. By default
-check_areca looks in /usr/local/areca/bin/cli for the cli. You can set the
-location using the --areca_cli (-A) flag from the command line.
-
-It is helpful to have an Areca RAID controller on the system being checked.
-
-=head1 DEPENDENCIES
-
- check_areca depends on the following modules:
- POSIX Standard Perl 5.8 module
- Getopt::Long Standard Perl 5.8 module
- Pod::USAGE Standard Perl 5.8 module
-
-=head1 INCOMPATIBILITIES
-
-None known yet.
-
-=head1 BUGS AND LIMITATIONS
-
-Bugs, never heard of 'em ;).
-If you encounter any bugs let me know. (erinn.looneytriggs@gmail.com)
-
-=head1 AUTHOR
-
-Erinn Looney-Triggs (erinn.looneytriggs@gmail.com)
-
-=head1 LICENCE AND COPYRIGHT
-
-Copyright (c) 2007-2008 Erinn Looney-Triggs (erinn.looneytriggs@gmail.com).
-All rights reserved.
-
-This module is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License.
-See L<http://www.fsf.org/licensing/licenses/gpl.html>.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+++ /dev/null
-#!/bin/sh
-
-# Nagios check for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
-#
-# Some background information on the driver is available at
-# http://home.germany.net/100-120220/mylex/DAC960.README
-#
-# Written 2008 Peter Palfrader
-
-if [ -e /proc/rd/status ]; then
- status=`cat /proc/rd/status`
- if [ "$status" = "OK" ]; then
- echo "OK: all DAC960 controllers operating normally; no (non-standby) failures have occurred"
- exit 0;
- else
- echo "CRITICAL: proc/rd/status is $status"
- exit 2;
- fi;
-else
- echo "UNKNOWN: No DAC960 controllers in the system"
- exit 3;
-fi
+++ /dev/null
-#!/usr/bin/perl -Tw
-
-# Copyright (C) 2008 Peter Palfrader <peter@palfrader.org>
-
-# Need to allow /usr/local/bin/tw_cli info c0 u0 status in sudoers:
-#
-# nagios ALL=(ALL) NOPASSWD: /usr/sbin/mpt-status -s
-#
-
-use strict;
-use English;
-use Getopt::Long;
-
-$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
-delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
-
-my $MPT_STATUS = '/usr/sbin/mpt-status';
-
-# nagios exit codes
-my $UNKNOWN = -1;
-my $OK = 0;
-my $WARNING = 1;
-my $CRITICAL = 2;
-
-$SIG{'__DIE__'} = sub {
- print STDERR @_;
- exit $UNKNOWN;
-};
-
-unless (-e $MPT_STATUS) {
- print "Cannot find '$MPT_STATUS'.\n";
- exit $UNKNOWN;
-};
-
-my $command = "sudo $MPT_STATUS -s";
-open (MPT, "$command|") or die ("Cannot run $command: $!\n");
-my @tw=<MPT>;
-close MPT;
-if ($CHILD_ERROR) { # program failed
- die("$command returned with non-zero exit code: ".($CHILD_ERROR / 256)."\n");
-};
-
-
-my $exit = $UNKNOWN;
-my $msg = '';
-for my $line (@tw) {
- chomp $line;
- next if $line =~ /^$/;
- my ($device, $num, $status) = $line =~ m#^(log_id|vol_id|phys_id)\s+([0-9]+)\s+(.*)$#;
- unless (defined($device) && defined($num) && defined($status)) {
- print "Cannot parse line '$line'\n";
- exit $UNKNOWN;
- };
- if ($status eq 'OPTIMAL' ||
- $status eq 'ONLINE') {
- $msg .= ($msg eq '' ? '' : '; '). "$device $num: $status";
- $exit = $exit > $OK ? $exit : $OK;
- } else {
- $msg .= ($msg eq '' ? '' : '; '). "$device $num: $status";
- $exit = $exit > $CRITICAL ? $exit : $CRITICAL;
- };
-};
-
-if ($msg eq '') {
- $msg = "No devices found";
- die ("exit is not UNKNOWN but $exit") if ($exit != $UNKNOWN);
-}
-
-print $msg,"\n";
-exit $exit;
+++ /dev/null
-#!/usr/bin/perl -w
-# ------------------------------------------------------------------------------
-# File Name: chech_raid.pl
-# Author: Thomas Nilsen - Norway
-# Date: 14/06/2003
-# Version: 0.1
-# Description: This script will check to see if any software raid
-# devices are down.
-# Email: thomas.nilsen@doc-s.co.uk
-# WWW: www.doc-s.co.uk
-# ------------------------------------------------------------------------------
-# Copyright 2003 (c) Thomas Nilsen
-# Credits go to Ethan Galstad for coding Nagios
-# License GPL
-# ------------------------------------------------------------------------------
-# Date Author Reason
-# ---- ------ ------
-# 2008-03-31 Peter Palfrader Return warning on running resync
-# 2007-11-07 Peter Palfrader Return unknown if /proc/mdstat does not exist
-# 05/10/2004 Peter Palfrader Make it work without that 'use util (vars)'
-# 14/06/2003 TN Initial Release
-# - Format of mdstat assumed to be "2 line" per
-# device with [??] on the second line.
-# ------------------------------------------------------------------------------
-
-use strict;
-use warnings;
-use Getopt::Long;;
-use vars qw($opt_V $opt_h $opt_t $opt_F $PROGNAME);
-use lib '/usr/local/nagios/libexec/';
-my $TIMEOUT=15;
-my %ERRORS = ( OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => -1 );
-
-
-$PROGNAME="check_raid";
-
-sub print_help ();
-sub print_usage ();
-
-$ENV{'PATH'}='';
-$ENV{'BASH_ENV'}='';
-$ENV{'ENV'}='';
-my ( $line, $stat, $state ,@device, $msg, $status, $timeout);
-
-$stat="/proc/mdstat";
-
-#Option checking
-Getopt::Long::Configure('bundling');
-$status = GetOptions(
- "V" => \$opt_V, "version" => \$opt_V,
- "h" => \$opt_h, "help" => \$opt_h,
- "F" => \$opt_F, "filename" => \$opt_F,
- "t" => \$opt_t, "timeout" => \$opt_t);
-# Version
-if ($opt_V) {
- print($PROGNAME,': $Revision: 0.1 $');
- exit $ERRORS{'OK'};
-}
-# Help
-if ($opt_h) {
- print_help();
- exit $ERRORS{'OK'};
-}
-# Filename supplied
-if ($opt_F) {
- $opt_F = shift;
- $stat = $1 if ($opt_F =~ /^(.*)$/);
-
- if ( ! -r $stat ) {
- print "Invalid mdstat file: $opt_F\n";
- exit $ERRORS{'UNKNOWN'};
- }
-}
-
-$timeout = $TIMEOUT;
-($opt_t) && ($opt_t =~ /^([0-9]+)$/) && ($timeout = $1);
-
-# Just in case of problems, let's not hang Nagios
-$SIG{'ALRM'} = sub {
- print ("ERROR: No response (alarm)\n");
- exit $ERRORS{'UNKNOWN'};
-};
-alarm($timeout);
-
-# Start checking the file...
-open (FH, $stat) or print("UNKNOWN: Cannot open $stat: $!\n"), exit $ERRORS{'UNKNOWN'};
-
-my @failed = ();
-my @resyncing = ();
-my $device = '';
-
-# Now check the mdstat file..
-while (<FH>) {
- $line = $_;
- if ($line =~ /^(md\S*) /) {
- $device = $1;
- } elsif( $line =~ / \[_|_\]|U_|_U /) {
- push @failed, $device;
- }
- elsif ( $line =~ / resync /) {
- # [==>..................] resync = 10.3% (15216320/146994624) finish=2153.2min speed=1018K/sec
- my ($percent) = ($line =~ m# resync = ([0-9.]+%)#);
- my ($finish) = ($line =~ m# finish=([0-9.]+min)#);
- my ($speed) = ($line =~ m# speed=([0-9.]+K/sec)#);
- push @resyncing, "$device ($percent done, finish in $finish at $speed)";
- }
-}
-close (FH);
-
-if (scalar @failed > 0) {
- if (scalar @failed == 1) {
- print "CRITICAL - Device $failed[0] has failed.\n";
- } else {
- print "CRITICAL - Devices ".join(", ", @failed)." have failed.\n"
- };
- exit $ERRORS{'CRITICAL'};
-} elsif (scalar @resyncing > 0 ) {
- print "WARNING: Resyncing: ".(join "; ", @resyncing)."\n";
- exit $ERRORS{'WARNING'};
-} else {
- print "OK - All devices are online\n";
- exit $ERRORS{'OK'};
-};
-
-
-sub print_usage () {
- print "Usage: $PROGNAME -t <timeout> -F <filename>\n";
-}
-
-sub print_help () {
- print_revision($PROGNAME,'$Revision: 0.1 $');
- print "Copyright (c) 2003 Thomas Nilsen/Karl DeBisschop\n";
- print "\n";
- print_usage();
- print "Checks the mdstat file for errors on any configured software raid.\n
--t ( --timeout=INTEGER)
- Seconds before script times out (default: 10)\n
--F ( --filename=FILE)
- Full path and name to mdstat file (usually '/proc/mdstat') \n\n";
-}
+++ /dev/null
-#!/bin/bash
-
-# Check if the running kernel has the same version string as the on-disk
-# kernel image.
-
-# Copyright 2008 Peter Palfrader
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-OK=0;
-WARNING=1;
-CRITICAL=2;
-UNKNOWN=3;
-
-get_offset() {
- local file needle
-
- file="$1"
- needle="$2"
- perl -e '
- undef $/;
- $i = index(<>, "'"$needle"'");
- if ($i < 0) {
- exit 1;
- };
- print $i,"\n"' < "$file"
-}
-
-get_image() {
- local image GZHDR1 GZHDR2 off
-
- image="$1"
-
- GZHDR1="\x1f\x8b\x08\x00"
- GZHDR2="\x1f\x8b\x08\x08"
-
- off=`get_offset "$image" $GZHDR1`
- [ "$?" != "0" ] && off="-1"
- if [ "$off" -eq "-1" ]; then
- off=`get_offset "$image" $GZHDR2`
- [ "$?" != "0" ] && off="-1"
- fi
- if [ "$off" -eq "0" ]; then
- zcat < "$image"
- return
- elif [ "$off" -ne "-1" ]; then
- (dd ibs="$off" skip=1 count=0 && dd bs=512k) < "$image" 2>/dev/null | zcat 2>/dev/null
- return
- fi
-
- echo "ERROR: Unable to extract kernel image." 2>&1
- exit 1
-}
-
-searched=""
-for on_disk in \
- "/boot/vmlinuz-`uname -r`"\
- "/boot/vmlinux-`uname -r`"; do
-
- if [ -e "$on_disk" ]; then
- on_disk_version="`get_image "$on_disk" | strings | grep 'Linux version' | head -n1`"
- [ -z "$on_disk_version" ] || break
- on_disk_version="`cat "$on_disk" | strings | grep 'Linux version' | head -n1`"
- [ -z "$on_disk_version" ] || break
-
- echo "UNKNOWN: Failed to get a version string from image $on_disk"
- exit $UNKNOWN
- fi
- searched="$searched $on_disk"
-done
-
-if ! [ -e "$on_disk" ]; then
- echo "WARNING: Did not find a kernel image (checked$searched) - I have no idea which kernel I am running"
- exit $WARNING
-fi
-
-
-running_version="`cat /proc/version`"
-if [ -z "$running_version" ] ; then
- echo "UNKNOWN: Failed to get a version string from running system"
- exit $UNKNOWN
-fi
-
-if [ "$running_version" != "$on_disk_version" ]; then
- echo "WARNING: Running kernel does not match on-disk kernel image: [$running_version != $on_disk_version]"
- exit $WARNING
-else
- echo "OK: Running kernel matches on disk image: [$running_version]"
- exit $OK
-fi
+++ /dev/null
-#!/usr/bin/perl -w
-
-# check_samhain.pl - check to see how many policy violations are reported
-# by the samhain file integrity checker.
-#
-# Copyright Rainer Wichmann (2004)
-# Copyright Martin Zobel-Helas (2008)
-#
-# License Information:
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-############################################################################
-
-# -------------------------------------------------------------------[ Uses ]--
-
-use strict;
-use Getopt::Long;
-use vars qw($PROGNAME $SAMHAIN $opt_V $opt_h $opt_v $verbose $opt_w $opt_c $opt_t $status $msg $state $retval);
-use lib "/usr/lib/nagios/plugins";
-use utils qw(%ERRORS &print_revision);
-
-#my $TIMEOUT = 15;
-#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4);
-#sub print_revision ($$);
-
-# ----------------------------------------------------[ Function Prototypes ]--
-
-sub print_help ();
-sub print_usage ();
-sub process_arguments ();
-
-# ------------------------------------------------------------[ Environment ]--
-
-$ENV{'PATH'}='';
-$ENV{'BASH_ENV'}='';
-$ENV{'ENV'}='';
-
-# -----------------------------------------------------------------[ Global ]--
-
-$PROGNAME = "dsa-check-samhain";
-$SAMHAIN = "/usr/sbin/samhain";
-
-# ----------------------------------------------------------------[ options ]--
-
-Getopt::Long::Configure('bundling');
-$status = process_arguments();
-if ($status){
- print "ERROR: processing arguments\n";
- exit $ERRORS{"UNKNOWN"};
-}
-
-# ----------------------------------------------------------------[ timeout ]--
-
-$SIG{'ALRM'} = sub {
- print ("ERROR: timed out waiting for $SAMHAIN\n");
- exit $ERRORS{"WARNING"};
-};
-alarm($opt_t);
-
-# ----------------------------------------------------------[ start samhain ]--
-
-if ( defined $SAMHAIN && -x $SAMHAIN ) {
- if (! open (SHPIPE, "/usr/bin/sudo $SAMHAIN -t check --foreground -p err -s none -l none -m none 2>&1 | " ) ) {
- print "ERROR: could not popen $SAMHAIN \n";
- exit $ERRORS{'UNKNOWN'};
- }
-}else{
- print "ERROR: Could not find samhain executable!\n";
- exit $ERRORS{'UNKNOWN'};
-}
-
-# ---------------------------------------------------------[ read from pipe ]--
-
-$status = 0;
-
-while (<SHPIPE>) {
- if (/POLICY/) {
- ++$status;
- print $_ if $verbose;
- }
-}
-
-if ($status < $opt_w) {
- $msg = "OK: $status policy violations (threshold $opt_w/$opt_c)";
- $state = $ERRORS{'OK'};
-} elsif ($status >= $opt_w && $status < $opt_c) {
- $msg = "WARNING: $status policy violations (threshold w=$opt_w)";
- $state = $ERRORS{'WARNING'};
-} else {
- $msg = "CRITICAL: $status policy violations (threshold w=$opt_w)";
- $state = $ERRORS{'CRITICAL'};
-}
-
-# -------------------------------------------------------------[ close pipe ]--
-
-close (SHPIPE);
-
-# declare an error if we also get a non-zero return code from samhain
-
-if ( $? ) {
- $retval = $? / 256;
- if ( $! ) {
- print "Error closing $SAMHAIN: $!\n" if $verbose;
- } else {
- print "$SAMHAIN returned exit status $retval\n" if $verbose;
- }
- if ($state == $ERRORS{"CRITICAL"}) {
- $state = $ERRORS{"CRITICAL"};
- } else {
- print "ERROR: $SAMHAIN exit status $retval\n";
- exit $ERRORS{'UNKNOWN'};
- }
-}
-
-# -------------------------------------------------------------------[ exit ]--
-
-print "$msg | 'policy violations'=$status;$opt_w;$opt_c\n";
-exit $state;
-
-
-# ------------------------------------------------------------[ Subroutines ]--
-
-sub process_arguments(){
- GetOptions
- ("V" => \$opt_V, "version" => \$opt_V,
- "h" => \$opt_h, "help" => \$opt_h,
- "v" => \$opt_v, "verbose" => \$opt_v,
- "w=i" => \$opt_w, "warning=i" => \$opt_w,
- "c=i" => \$opt_c, "critical=i" => \$opt_c,
- "t=i" => \$opt_t, "timeout=i" => \$opt_t
- );
-
- if ($opt_V) {
- print_revision($PROGNAME,'$Revision: 1.0 $ ');
- exit $ERRORS{'OK'};
- }
-
- if ($opt_h) {
- print_help();
- exit $ERRORS{'OK'};
- }
-
- if (defined $opt_v ){
- $verbose = $opt_v;
- }
-
- unless (defined $opt_t) {
- $opt_t = $utils::TIMEOUT ; # default timeout
- # $opt_t = $TIMEOUT ;
- }
-
- unless (defined $opt_w) {
- $opt_w = 1;
- }
-
- unless (defined $opt_c) {
- $opt_c = 1;
- }
-
- if ( $opt_w > $opt_c) {
- print "Warning cannot be greater than Critical!\n";
- exit $ERRORS{'UNKNOWN'};
- }
-
- return $ERRORS{'OK'};
-}
-
-sub print_usage () {
- print "Usage: $PROGNAME [-w <warn>] [-c <crit>] [-t <timeout>]\n";
-}
-
-sub print_help () {
- print_revision($PROGNAME, '$Revision: 1.0 $');
- print "Copyright (c) 2004 Rainer Wichmann
-
-This plugin checks the number of policy violations reported by the
-samhain file intgrity checker
-
-";
- print_usage();
- print "
--w, --warning=INTEGER
- Minimum number of policy violations for which a WARNING status will result
--c, --critical=INTEGER
- Minimum number of policy violations for which a CRITICAL status will result
--t, --timeout=SECONDS
- The number of seconds after which a the plugin will timeout
--v, --verbose
- Verbose output
--h, --help
- Show this help message
--V, --version
- Show the version of the plugin
-
-";
-}
-
-#sub print_revision ($$) {
-# my $commandName = shift;
-# my $pluginRevision = shift;
-# $pluginRevision =~ s/^\$Revision: //;
-# $pluginRevision =~ s/ \$\s*$//;
-# print "$commandName (samhain 2.2.3) $pluginRevision\n";
-#}
+++ /dev/null
-#!/usr/bin/ruby
-
-# Copyright 2006 Peter Palfrader
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-require 'resolv'
-require 'optparse'
-require 'yaml'
-
-NAGIOS_STATUS = { :OK => 0, :WARNING => 1, :CRITICAL => 2, :UNKNOWN => -1 };
-@verbose = 0;
-@additional_nameservers = []
-
-def show_help(parser, code=0, io=STDOUT)
- program_name = File.basename($0, '.*')
- io.puts "Usage: #{program_name} [options] <domainname> [<domainname> ...]"
- io.puts parser.summarize
- exit(code)
-end
-ARGV.options do |opts|
- opts.on_tail("-h", "--help" , "Display this help screen") { show_help(opts) }
- opts.on("-v", "--verbose" , String, "Be verbose") { @verbose += 1 }
- opts.on("-a", "--add=HOST" , String, "Also check SOA on <nameserver>") { |val| @additional_nameservers << val }
- opts.parse!
-end
-show_help(ARGV.options, 1, STDERR) if ARGV.length == 0
-
-warnings = []
-oks = []
-
-dns = Resolv::DNS.new
-ARGV.each{ |domain|
- serial = []
- nameservers = dns.getresources(domain, Resolv::DNS::Resource::IN::NS)
- nameservernames = nameservers.collect{ |ns| ns.name.to_s }
- nameservernames = nameservernames.concat @additional_nameservers
- nameservernames.each{ |nameserver|
- puts "Testing nameserver #{nameserver} for #{domain}" if @verbose > 0
- arecords = dns.getresources(nameserver, Resolv::DNS::Resource::IN::A)
- warnings << "Nameserver #{nameserver} for #{domain} has #{arecords.length} A records" if arecords.length != 1
- arecords.each{ |a|
- puts " Nameserver #{nameserver} is at #{a.address}" if @verbose > 0
- begin
- resolver = Resolv::DNS.new({:nameserver => a.address.to_s})
- soas = resolver.getresources(domain, Resolv::DNS::Resource::IN::SOA)
- rescue SystemCallError => e
- warnings << "Could not resolve #{domain} on #{nameserver}: #{e.message}"
- else
- resolver.close
- warnings << "Nameserver #{nameserver} for #{domain} returns #{soas.length} SOAs" if soas.length != 1
- soas.each{ |soa|
- puts " Nameserver #{nameserver} returns serial #{soa.serial} for #{domain}" if @verbose > 0
- serial << soa.serial unless serial.include? soa.serial
- }
- end
- }
- }
- case serial.length
- when 0
- warnings << "Found no serials for #{domain}"
- when 1
- oks << "#{domain} is at #{serial.first}"
- else
- warnings << "Nameservers disagree on serials for #{domain}: found #{serial.join(', ')}" if serial.length != 1
- end
-}
-dns.close
-
-if warnings.length > 0
- puts warnings.join('; ')
- exit NAGIOS_STATUS[:WARNING]
-else
- puts oks.join('; ')
- exit NAGIOS_STATUS[:OK]
-end
+++ /dev/null
-#!/usr/bin/ruby
-
-# Relay the status of a check that was previously run and which stored
-# its result in a file to nagios.
-#
-# Copyright 2008 Peter Palfrader
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-require 'resolv'
-require 'optparse'
-
-NAGIOS_STATUS = { "OK" => 0, "WARNING" => 1, "CRITICAL" => 2, "UNKNOWN" => 3 }
-UNITS_TO_SECONDS = { 's' => 1, 'm' => 60, 'h' => 60*60, 'd' => 24*60*60 }
-
-def show_help(parser, code=0, io=STDOUT)
- program_name = File.basename($0, '.*')
- io.puts "Usage: #{program_name} [options] <statusfile>"
- io.puts parser.summarize
- exit(code)
-end
-
-max_age = "26h"
-ARGV.options do |opts|
- opts.on_tail("-h", "--help" , "Display this help screen") { show_help(opts) }
- opts.on("-a", "--age=AGE" , String, "maximum age, in seconds (or use Nm, Nh or Nd) - default is 26h") { |max_age| }
- opts.parse!
-end
-show_help(ARGV.options, 1, STDERR) if ARGV.length != 1
-
-statusfile = ARGV.shift
-
-# find out what the max age is that we accept
-unless (m = /^([0-9]+)([smhd])?$/.match max_age)
- STDERR.puts "Invalid age #{age}."
- show_help(ARGV.options, 1, STDERR) if ARGV.length != 1
-end
-max_age = m[1].to_i * UNITS_TO_SECONDS[m[2] ? m[2] : 's']
-
-# let's see if it exists
-unless File.exists? statusfile
- puts "UNKNOWN: #{statusfile} does not exist."
- exit NAGIOS_STATUS['UNKNOWN']
-end
-
-
-mtime = File.stat(statusfile).mtime
-if mtime + max_age < Time.now
- puts "WARNING: #{statusfile} is old: #{mtime}"
- exit NAGIOS_STATUS['WARNING']
-end
-
-status = File.new(statusfile)
-returnvalue = status.readline.chomp
-
-unless NAGIOS_STATUS.has_key? returnvalue
- puts "UNKNOWN: #{statusfile} has invalid return value: #{returnvalue}"
- exit NAGIOS_STATUS['UNKNOWN']
-end
-
-status.readlines.each do |line|
- print line
-end
-exit NAGIOS_STATUS[returnvalue]
+++ /dev/null
-#!/usr/bin/perl -w
-
-use strict;
-my %CODE = (
- 'UNDEF' => -1,
- 'OK' => 0,
- 'WARNING' => 1,
- 'CRITICAL' => 2,
- 'UNKNOWN' => 3
-);
-
-my $f;
-
-$SIG{__DIE__ } = sub() {
- print shift;
- exit $CODE{'UNKNOWN'};
-};
-
-if ( -e "/var/lib/misc/thishost/passwd.tdb" ) {
- $f = "/var/lib/misc/thishost/passwd.tdb";
-} else {
- my $hostname = `hostname -f`;
- chomp $hostname;
- $hostname =~ m/^([a-z]+(?:\.[a-z]+)+)$/;
- die "Weird hostname '$hostname'\n" unless defined $1;
- $hostname = $1;
- if ( -e "/var/lib/misc/$hostname/passwd.tdb" ) {
- $f = "/var/lib/misc/$hostname/passwd.tdb";
- };
-};
-
-die "Could not find passwd.tdb" unless defined $f;
-
-my @stat = stat($f) or die ("Cannot stat $f: $!\n");
-my $age = time - $stat[10];
-my $hage;
-if ($age > 48 * 3600) {
- $hage = sprintf("%.1f days", $age / 24 / 3600);
-} elsif ($age > 3600) {
- $hage = sprintf("%.1f hours", $age / 3600);
-} else {
- $hage = sprintf("%d minutes", $age / 60);
-};
-
-if ($age > 60*60) {
- print "WARNING: ud-ldap info is $hage old\n";
- exit $CODE{'WARNING'};
-};
-print "OK: ud-ldap info is $hage old\n";
-exit $CODE{'OK'};
+++ /dev/null
-#!/bin/sh
-
-UPDATE_RUNS=3
-STATUS=/var/cache/dsa/nagios/apt
-SLEEP_MAX=$(( 15 * 60 ))
-MAX_AGE=$(( 23 * 60 * 60 ))
-
-# we want to run if any of the following things is true
-# - we have never run before
-# - var/lib/dpkg/status has been touched since the last run
-# - var/cache/apt/pkgcache.bin has been touched since the last run
-# - our last run ended with 'apt-get update failed'
-# - our last run has been more than MAX_AGE (23hrs) ago
-run_required() {
- local run=0
- local norun=1
-
- [ -e "$STATUS" ] || return $run
- [ /var/lib/dpkg/status -nt "$STATUS" ] && return $run
- [ /var/cache/apt/pkgcache.bin -nt "$STATUS" ] && return $run
- grep "apt-get update failed" "$STATUS" > /dev/null && return $run
-
- local last_mod
- last_mod=`stat -c "%Y" "$STATUS"`
- now=`date +%s`
- age=$(( $now - $last_mod ))
- [ "$age" -gt "$MAX_AGE" ] && return $run
-
- return $norun
-}
-
-# do stuff only when required
-run_required || exit
-
-# sleep if called non-interactively
-if [ -z "$TERM" -o "$TERM" = "dumb" ]; then
- sleep $(( $RANDOM % $SLEEP_MAX ))
-fi
-
-# run apt-get update, retry a few times if it fails
-count=0
-while [ "$count" -lt "$UPDATE_RUNS" ]; do
- apt-get update -qq >/dev/null >&2
- if [ "$?" = "0" ]; then break; fi
- sleep $(( $RANDOM % 600 ))
- count="$(( $count + 1 ))"
-done
-if [ "$count" -ge "$UPDATE_RUNS" ]; then
- (echo "WARNING"
- echo "apt-get update failed") > "$STATUS"
- exit 1
-fi
-
-# run the apt check itself
-tmp=`tempfile`
-trap "rm -f '$tmp'" exit
-#/usr/share/dsa/apt-status-check --noupdate --timeout=600 > "$tmp"
-/usr/lib/nagios/plugins/dsa-check-packages > "$tmp"
-result="$?"
-case "$result" in
- 0)
- st="OK"
- ;;
- 1)
- st="WARNING"
- ;;
- 2)
- st="CRITICAL"
- ;;
- *)
- st="UNKNOWN"
- ;;
-esac
-(echo "$st"; cat "$tmp") > "$STATUS"
+++ /dev/null
-#!/bin/sh
-
-STATUS=/var/cache/dsa/nagios/samhain
-
-tmp=`tempfile`
-trap "rm -f '$tmp'" exit
-/usr/lib/nagios/plugins/dsa-check-samhain -t 1800 > "$tmp"
-result="$?"
-case "$result" in
- 0)
- st="OK"
- ;;
- 1)
- st="WARNING"
- ;;
- 2)
- st="CRITICAL"
- ;;
- *)
- st="UNKNOWN"
- ;;
-esac
-(echo "$st"; cat "$tmp") > "$STATUS"
--- /dev/null
+/linux-image-.*/
+/kernel-image-.*/
+buildd
+sbuild
+++ /dev/null
-/linux-image-.*/
-/kernel-image-.*/
-buildd
-sbuild
--- /dev/null
+#!/bin/sh
+
+UPDATE_RUNS=3
+STATUS=/var/cache/dsa/nagios/apt
+SLEEP_MAX=$(( 15 * 60 ))
+MAX_AGE=$(( 23 * 60 * 60 ))
+
+# we want to run if any of the following things is true
+# - we have never run before
+# - var/lib/dpkg/status has been touched since the last run
+# - var/cache/apt/pkgcache.bin has been touched since the last run
+# - our last run ended with 'apt-get update failed'
+# - our last run has been more than MAX_AGE (23hrs) ago
+run_required() {
+ local run=0
+ local norun=1
+
+ [ -e "$STATUS" ] || return $run
+ [ /var/lib/dpkg/status -nt "$STATUS" ] && return $run
+ [ /var/cache/apt/pkgcache.bin -nt "$STATUS" ] && return $run
+ grep "apt-get update failed" "$STATUS" > /dev/null && return $run
+
+ local last_mod
+ last_mod=`stat -c "%Y" "$STATUS"`
+ now=`date +%s`
+ age=$(( $now - $last_mod ))
+ [ "$age" -gt "$MAX_AGE" ] && return $run
+
+ return $norun
+}
+
+# do stuff only when required
+run_required || exit
+
+# sleep if called non-interactively
+if [ -z "$TERM" -o "$TERM" = "dumb" ]; then
+ sleep $(( $RANDOM % $SLEEP_MAX ))
+fi
+
+# run apt-get update, retry a few times if it fails
+count=0
+while [ "$count" -lt "$UPDATE_RUNS" ]; do
+ apt-get update -qq >/dev/null >&2
+ if [ "$?" = "0" ]; then break; fi
+ sleep $(( $RANDOM % 600 ))
+ count="$(( $count + 1 ))"
+done
+if [ "$count" -ge "$UPDATE_RUNS" ]; then
+ (echo "WARNING"
+ echo "apt-get update failed") > "$STATUS"
+ exit 1
+fi
+
+# run the apt check itself
+tmp=`tempfile`
+trap "rm -f '$tmp'" exit
+#/usr/share/dsa/apt-status-check --noupdate --timeout=600 > "$tmp"
+/usr/lib/nagios/plugins/dsa-check-packages > "$tmp"
+result="$?"
+case "$result" in
+ 0)
+ st="OK"
+ ;;
+ 1)
+ st="WARNING"
+ ;;
+ 2)
+ st="CRITICAL"
+ ;;
+ *)
+ st="UNKNOWN"
+ ;;
+esac
+(echo "$st"; cat "$tmp") > "$STATUS"
--- /dev/null
+#!/bin/sh
+
+STATUS=/var/cache/dsa/nagios/samhain
+
+tmp=`tempfile`
+trap "rm -f '$tmp'" exit
+/usr/lib/nagios/plugins/dsa-check-samhain -t 1800 > "$tmp"
+result="$?"
+case "$result" in
+ 0)
+ st="OK"
+ ;;
+ 1)
+ st="WARNING"
+ ;;
+ 2)
+ st="CRITICAL"
+ ;;
+ *)
+ st="UNKNOWN"
+ ;;
+esac
+(echo "$st"; cat "$tmp") > "$STATUS"
--- /dev/null
+#!/usr/bin/perl -Tw
+
+# $Id: nagios-check-apt-updates 352 2008-05-20 21:36:54Z weasel $
+
+# nagios check for debian (security) updates,
+# based on net-snmp glue to security updates via apt-get.
+# Copyright (C) 2004 SILVER SERVER Gmbh
+# Copyright (C) 2004, 2005, 2006, 2007, 2008 Peter Palfrader
+#
+# 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA
+
+use strict;
+use English;
+use Getopt::Long;
+use IO::Handle;
+use IPC::Open2;
+use IPC::Open3;
+
+$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
+delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
+
+my $APT = '/usr/bin/apt-get';
+my $VERBOSE;
+
+sub do_check($$$$$$) {
+ my ($pre_command, $timeout, $noupdate, $name, $updates_security, $updates_other) = @_;
+ my $fh;
+ my $pid;
+ my @command;
+
+ unless ($noupdate) {
+ print STDERR "Running $APT update in $name\n" if $VERBOSE;
+ @command = ($APT, 'update');
+ unshift @command, @$pre_command;
+ $fh = new IO::Handle;
+ $pid = open3(\*STDIN, $fh, $fh, @command) or die ("Cannot run $APT update in $name: $!\n");
+ local $SIG{ALRM} = sub { die "Timeout for apt-get update.\n" };
+ alarm $timeout;
+ my @ignore=<$fh>;
+ alarm 0;
+ close $fh;
+ waitpid $pid, 0;
+ if ($CHILD_ERROR) { # program failed
+ die("$APT update returned with non-zero exit code in $name: ".($CHILD_ERROR / 256)."\n");
+ };
+ };
+
+ print STDERR "Running $APT --simulate upgrade in $name\n" if $VERBOSE;
+ @command = ($APT, qw{--simulate upgrade});
+ unshift @command, @$pre_command;
+ $fh = new IO::Handle;
+ $pid = open2($fh, \*STDIN, @command) or die ("Cannot run $APT --simulate upgrade | sort -u in $name: $!\n");
+ local $SIG{ALRM} = sub { die "Timeout for apt-get --simulate upgrade.\n" };
+ alarm $timeout;
+ my @lines=<$fh>;
+ close $fh;
+ alarm 0;
+ waitpid $pid, 0;
+ if ($CHILD_ERROR) { # program failed
+ die("$APT --simulate upgrade | sort -u returned with non-zero exit code in $name: ".($CHILD_ERROR / 256)."\n");
+ };
+
+ @lines = sort {$a cmp $b} @lines;
+ my %uniq;
+ @lines = grep {!$uniq{$_}++} @lines;
+
+ print STDERR "Processing information for $name\n" if $VERBOSE;
+ for my $line (@lines) {
+ if ($line =~ m/^Inst\s+(\S+)\s+/) {
+ my $package = $1;
+ if ($line =~ m/^Inst\s+\S+\s+.*security/i) {
+ push @$updates_security, $package.($name ne '/' ? "($name)" : '');
+ } else {
+ push @$updates_other, $package.($name ne '/' ? "($name)" : '');
+ };
+ }
+ }
+}
+
+
+
+my $VERSION = '0.0.3 - $Rev: 352 $';
+my $use_sudo = 1;
+my $params;
+
+# nagios exit codes
+my $OK = 0;
+my $WARNING = 1;
+my $CRITICAL = 2;
+my $UNKNOWN = 3;
+
+$params->{'chroots'} = [];
+$params->{'vservers'} = [];
+$params->{'timeout'} = 20;
+Getopt::Long::config('bundling');
+if (!GetOptions (
+ '--help' => \$params->{'help'},
+ '--version' => \$params->{'version'},
+ '--sudo' => \$params->{'sudo'},
+ '--noupdate' => \$params->{'noupdate'},
+ '--nosudo' => \$params->{'nosudo'},
+ '--verbose' => \$params->{'verbose'},
+ '--warnifupdates' => \$params->{'warnifupdates'},
+ '--timeout=i' => \$params->{'timeout'},
+ '--chroot=s' => $params->{'chroots'},
+ '--vserver=s' => $params->{'vservers'}
+ )) {
+ die ("Usage: $PROGRAM_NAME [--help|--version] [--sudo|--nosudo] [--timeout=<timeout>] [--verbose]\n");
+};
+if ($params->{'help'}) {
+ print "nagios-check-apt-updates $VERSION\n";
+ print "Usage: $PROGRAM_NAME [--help|--version] [--sudo|--nosudo] [--verbose]\n";
+ print "Reports packages to upgrade, updating the list if necessary.\n";
+ print "\n";
+ print " --help Print this short help.\n";
+ print " --version Report version number.\n";
+ print " --sudo Use sudo to call apt-get (default).\n";
+ print " --noupdate Do not run apt-get update first.\n";
+ print " --nosudo Do not use sudo to call apt-get.\n";
+ print " --warnifupdates Exit with a WARNING status if any updates are available.\n";
+ print " --timeout=<timeout> Timeout in seconds for each of the two apt-get runs.\n";
+ print " --verbose Be a little verbose.\n";
+ print " --chroot=<path> Run check in path.\n";
+ print " --vserver=<vserver> Run check in vserver.\n";
+ print "\n";
+ print "Note that for --sudo (default) you will need entries in /etc/sudoers like these:\n";
+ print "nagios ALL=(ALL) NOPASSWD: /usr/bin/apt-get update\n";
+ print "nagios ALL=(ALL) NOPASSWD: /usr/bin/apt-get --simulate upgrade\n";
+ print "nagios ALL=(ALL) NOPASSWD: /usr/sbin/chroot /chroot-ia32 /usr/bin/apt-get update\n";
+ print "nagios ALL=(ALL) NOPASSWD: /usr/sbin/chroot /chroot-ia32 /usr/bin/apt-get --simulate upgrade\n";
+ print "nagios ALL=(ALL) NOPASSWD: /usr/sbin/vserver phpserver exec /usr/bin/apt-get update\n";
+ print "nagios ALL=(ALL) NOPASSWD: /usr/sbin/vserver phpserver exec /usr/bin/apt-get --simulate upgrade\n";
+ print "\n";
+ exit (0);
+};
+if ($params->{'version'}) {
+ print "nagios-check-apt-updates $VERSION\n";
+ print "nagios check for availability of debian (security) updates\n";
+ print "Copyright (c) 2004 SILVER SERVER Gmbh\n";
+ print "Copyright (c) 2004,2005 Peter Palfrader <peter\@palfrader.org>\n";
+ exit (0);
+};
+if ($params->{'sudo'} && $params->{'nosudo'}) {
+ die ("$PROGRAM_NAME: --sudo and --nosudo are mutually exclusive.\n");
+};
+if ($params->{'sudo'}) {
+ $use_sudo = 1;
+};
+if ($params->{'nosudo'}) {
+ $use_sudo = 0;
+};
+if (scalar @{$params->{'chroots'}} == 0 && scalar @{$params->{'vservers'}} == 0) {
+ $params->{'chroots'} = ['/'];
+};
+$VERBOSE = $params->{'verbose'};
+
+
+$SIG{'__DIE__'} = sub {
+ print STDERR @_;
+ exit $UNKNOWN;
+};
+
+
+my @updates_security;
+my @updates_other;
+
+
+# Make sure chroot paths are nice;
+my @chroots = ();
+for my $root (@{$params->{'chroots'}}) {
+ if ($root =~ m#^(/[a-zA-Z0-9/.-]*)$#) {
+ push @chroots, $1;
+ } else {
+ die ("Chroot path $root is not nice.\n");
+ };
+};
+for my $root (@chroots) {
+ my @pre_command = ();
+ unshift @pre_command, 'chroot', $root if ($root ne '/');
+ unshift @pre_command, 'sudo' if $use_sudo;
+ do_check(\@pre_command, $params->{'timeout'}, $params->{'noupdate'}, $root, \@updates_security, \@updates_other);
+}
+
+# Make sure vserver names are nice;
+my @vservers = ();
+for my $vserver (@{$params->{'vservers'}}) {
+ if ($vserver =~ m#^([a-zA-Z0-9.-]+)$#) {
+ push @vservers, $1;
+ } else {
+ die ("Vserver name $vserver is not nice.\n");
+ };
+};
+for my $vserver (@vservers) {
+ my @pre_command = ();
+ unshift @pre_command, '/usr/sbin/vserver', $vserver, 'exec';
+ unshift @pre_command, 'sudo' if $use_sudo;
+ do_check(\@pre_command, $params->{'timeout'}, $params->{'noupdate'}, $vserver, \@updates_security, \@updates_other);
+}
+
+
+
+
+my $exit = $OK;
+
+my $updateinfo;
+if (@updates_security) {
+ $updateinfo .= 'Security updates ('.(scalar @updates_security).'): '.join(', ', @updates_security)."; ";
+ $exit = $CRITICAL;
+}
+if (@updates_other) {
+ $updateinfo .= 'Other Updates ('.(scalar @updates_other).'): '.join(', ', @updates_other)."; ";
+ $exit = $WARNING if ($params->{'warnifupdates'} and $exit == $OK);
+};
+$updateinfo = 'No updates available' unless defined $updateinfo;
+
+
+print $updateinfo,"\n";
+exit $exit;
--- /dev/null
+#!/usr/bin/perl
+
+# This cheak is based on code from the Debian/OpenSSL Weak Key Detector
+# written by Florian Weimer <fw@deneb.enyo.de>.
+# The code has been modified and enhanced by Alexander Wirt
+# <formorer@debian.org> to use it as a nagios check.
+#
+# Copyright (c) 2008, Florian Weimer <fw@deneb.enyo.de> for the original
+# Debian/OpenSSL Weak Key Detector
+# (http://security.debian.org/project/extra/dowkd/dowkd.pl.gz)
+#
+# Copyright (c) 2008, Alexander Wirt <formorer@debian.org> for check_weakkeys
+#
+# Copyright (c) 2008 Peter Palfrader <peter@palfrader.org>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+=pod
+
+=head1 NAME
+
+B<check_weakkeys> - checks system for weak ssh keys
+
+=cut
+
+=head1 SYNOPSIS
+
+B<check_weakkeys> [options]
+
+=cut
+
+=head1 DESCRIPTION
+
+B<check_weakkeys> checks for all users if there id_rsa, id_dsa or
+authorized_key files if they contain weak ssh keys created by a Debian with a
+broken libssl (see DSA-1571 for more informations). Optionally <check_weakkeys>
+can spit out a warning of there are any DSA keys left in key or authorized_key
+files. To work it needs a database of precomputed hashes of known weak keys.
+This file is expected as an bdb database with the hash (like
+03:a2:f0:46:7f:13:9f:5f:96:71:a9:b8:a0:1c:01:05) as key. See <gen_fprdb> for
+such a database generator. <check_weakkeys> outputs his data to STDOUT or to a
+file. It meaned to be picked up by an nagios check like B<dsa-check-statusfile>
+from Peter Palfrader.
+
+=cut
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-h, --help>
+
+Prints out a brief help
+
+=item B<-s, --statusfile> "statusfile"
+
+Use 'F<statusfile>' instead of 'F<STDOUT>'.
+
+=item B<-f, --fprdb> "database" (default: /var/lib/dsa/ssh-weak-keys.db)
+
+Use 'F<database>' instead of 'F</var/lib/dsa/ssh-weak-keys.db>'
+as fingerprint database.
+
+=item B<-n, --dsa_nowarn>
+
+Don't warn for DSA keys
+
+=back
+
+=cut
+
+use strict;
+use warnings;
+
+use File::Temp;
+use BerkeleyDB;
+use Pod::Usage;
+use Getopt::Long;
+use IPC::Open3;
+
+my $fprdb_fname = "/var/lib/dsa/ssh-weak-keys.db" ;
+my ($outfile, $help);
+my $dsa_nowarn = 0;
+
+GetOptions( 'help|h' => \$help, #Help function
+ 'statusfile|s=s' => \$outfile,
+ 'fprdb|f=s' => \$fprdb_fname,
+ 'n|dsa_nowarn' => \$dsa_nowarn,
+);
+
+pod2usage(1) if $help;
+
+my $fh;
+if ($outfile) {
+ open ($fh, '>', $outfile)
+ or die "Could not open statusfile '$outfile' for writing: $!";
+} else {
+ $fh = *STDOUT;
+}
+
+my %fpr_hash;
+tie %fpr_hash, 'BerkeleyDB::Btree',
+ -Filename => $fprdb_fname,
+ -Flags => DB_RDONLY
+ or die "Cannot open fingerprint db $fprdb_fname: $! $BerkeleyDB::Error\n";
+
+
+my ($weak_keys,$checked_keys) = 0;
+my $dsa_keys = 0;
+my $weird_keyfiles = 0;
+my $text = '';
+my %key_sizes;
+
+
+
+#&from_user_all;
+&from_debianorg_places;
+&from_ssh_host(qw(localhost));
+
+my $status="OK";
+if ($weak_keys) {
+ $status = "CRITICAL";
+} elsif ($dsa_keys && ! $dsa_nowarn || $weird_keyfiles) {
+ $status = "WARNING";
+}
+
+print $fh "$status\n";
+print $fh "Checked $checked_keys keys - $weak_keys weak - $dsa_keys dsa keys\n";
+print $fh "Sizes: ";
+foreach my $size (sort(keys(%key_sizes))) {
+ print $fh "$size:$key_sizes{$size} ";
+}
+
+print $fh "\n";
+print $fh "$text" if $text;
+
+
+
+sub safe_backtick (@) {
+ my @args = @_;
+
+ my ($wtr, $fh, $err);
+
+ open3($wtr,$fh,$err, @args)
+ or die "error: failed to spawn $args[0]: $!\n";
+ my @result;
+ if (wantarray) {
+ @result = <$fh>;
+ } else {
+ local $/;
+ @result = scalar(<$fh>);
+ }
+ close $fh;
+ $? == 0 or return undef;
+ if (wantarray) {
+ return @result;
+ } else {
+ return $result[0];
+ }
+}
+
+sub ssh_fprint_file ($) {
+ my $name = shift;
+ my $data = safe_backtick qw/ssh-keygen -l -f/, $name;
+ defined $data or return ();
+ my @data = $data =~ /^(\d+) ([0-9a-f]{2}(?::[0-9a-f]{2}){15})/;
+ return @data if @data == 2;
+ return ();
+}
+
+sub ssh_fprint_check ($$$) {
+ my ($name, $length, $hash) = @_;
+ if (exists $key_sizes{$length}) {
+ $key_sizes{$length}++;
+ } else {
+ $key_sizes{$length}=1;
+ }
+ $checked_keys++;
+ if (exists $fpr_hash{$hash}) {
+ $weak_keys++;
+ $text .= "$name weak ($hash)\n";
+ }
+}
+
+
+sub from_ssh_key_file ($) {
+ my $name = shift;
+ if (open (my $FH, '<', $name)) {
+ my $key = <$FH>;
+ if (! defined $key) {
+ $weird_keyfiles++;
+ $text .= "cannot read $name properly - empty?\n";
+ } elsif ($key =~ m/ssh-dss/) {
+ $dsa_keys++;
+ $text .= "$name is a DSA key\n";
+ }
+ } else {
+ $text .= "Could not open $name: $!";
+ }
+ my ($length, $hash) = ssh_fprint_file $name;
+ if ($length && $hash) {
+ ssh_fprint_check "$name:1", $length, $hash;
+ } else {
+ $text .= "$name:1: warning: failed to parse SSH key file\n";
+ }
+}
+
+sub clear_tmp ($) {
+ my $tmp = shift;
+ seek $tmp, 0, 0 or die "seek: $!";
+ truncate $tmp, 0 or die "truncate: $!";
+}
+
+sub from_ssh_auth_file ($) {
+ my $name = shift;
+ my $auth;
+ unless (open $auth, '<', $name) {
+ warn "$name:0: error: open failed: $!\n";
+ return;
+ }
+ my $tmp = new File::Temp;
+ while (my $line = <$auth>) {
+ chomp $line;
+ my $lineno = $.;
+ clear_tmp $tmp;
+ next if $line =~ m/^$/; # ignore empty lines
+ next if $line =~ m/^#/; # ignore comments
+ if ($line =~ m/ssh-dss/) {
+ $dsa_keys++;
+ $text .= "$name:$lineno is a DSA key\n";
+ }
+ print $tmp "$line\n" or die "print: $!";
+ $tmp->flush;
+ my ($length, $hash) = ssh_fprint_file "$tmp";
+ if ($length && $hash) {
+ ssh_fprint_check "$name:$lineno", $length, $hash;
+ } else {
+ $text .= "$name:$lineno: warning: unparsable line\n";
+ }
+ }
+}
+
+sub from_ssh_host (@) {
+ my @names = @_;
+ my @lines;
+ push @lines, safe_backtick qw|ssh-keyscan -t rsa|, @names;
+ push @lines, safe_backtick qw|ssh-keyscan -t dsa|, @names;
+
+ my $tmp = new File::Temp;
+ for my $line (@lines) {
+ next if $line =~ /^#/;
+ next if $line =~ /^no hostkey alg/;
+ my ($host, $data) = $line =~ /^(\S+) (.*)$/;
+ clear_tmp $tmp;
+ print $tmp "$data\n" or die "print: $!";
+ $tmp->flush;
+ my ($length, $hash) = ssh_fprint_file "$tmp";
+ if ($length && $hash) {
+ ssh_fprint_check "$host", $length, $hash;
+ } else {
+ $text .= "$host: warning: unparsable line\n";
+ }
+ }
+}
+
+sub from_user ($) {
+ my $user = shift;
+ my ($name,$passwd,$uid,$gid,
+ $quota,$comment,$gcos,$dir,$shell,$expire) = getpwnam($user);
+ my $file = "$dir/.ssh/authorized_keys";
+ from_ssh_auth_file $file if -r $file;
+ $file = "$dir/.ssh/authorized_keys2";
+ from_ssh_auth_file $file if -r $file;
+ $file = "$dir/.ssh/id_rsa.pub";
+ from_ssh_key_file $file if -r $file;
+ $file = "$dir/.ssh/id_dsa.pub";
+ from_ssh_key_file $file if -r $file;
+}
+
+sub from_user_all () {
+ setpwent;
+ while (my $name = getpwent) {
+ from_user $name;
+ }
+ endpwent;
+}
+
+
+sub from_debianorg_places () {
+ open(F, "/etc/ssh/sshd_config") or die ("Cannot open /etc/ssh/sshd_config: $!\n");
+ my @lines = <F>;
+ close(F);
+
+ my @ak = grep { /^AuthorizedKeysFile\s/i } @lines;
+ my @ak2 = grep { /^AuthorizedKeysFile2\s/i } @lines;
+
+ if (scalar @ak != 1) {
+ print $fh "UNKNOWN\n";
+ print $fh "There is more than one AuthorizedKeysFile definition in sshd_config\n";
+ exit
+ }
+ if (scalar @ak2 != 1) {
+ print $fh "UNKNOWN\n";
+ print $fh "There is more than one AuthorizedKeysFile2 definition in sshd_config\n";
+ exit
+ }
+ unless ($ak[0] =~ m#^((?i)AuthorizedKeysFile)\s+/etc/ssh/userkeys/%u$# ) {
+ print $fh "UNKNOWN\n";
+ print $fh "The AuthorizedKeysFile definition has an unexpected value. Should be /etc/ssh/userkeys/%u\n";
+ exit
+ }
+ unless ($ak2[0] =~ m#^((?i)AuthorizedKeysFile2)\s+/var/lib/misc/userkeys/%u$# ) {
+ print $fh "UNKNOWN\n";
+ print $fh "The AuthorizedKeysFile2 definition has an unexpected value. Should be /var/lib/misc/userkeys/%u\n";
+ exit
+ }
+
+ for my $d (qw{/etc/ssh/userkeys /var/lib/misc/userkeys}) {
+ next unless (-d $d);
+ opendir(D, $d) or die "Cannot opendir $d: $!\n";
+ for my $file (grep { ! -d $d.'/'.$_ } readdir(D)) {
+ next if ($file eq 'README-DSA-BUILDD');
+ my $f = $d.'/'.$file;
+ from_ssh_key_file $f if -r $f;
+ };
+ };
+}
+
+
+++ /dev/null
-#!/usr/bin/perl
-
-# This cheak is based on code from the Debian/OpenSSL Weak Key Detector
-# written by Florian Weimer <fw@deneb.enyo.de>.
-# The code has been modified and enhanced by Alexander Wirt
-# <formorer@debian.org> to use it as a nagios check.
-#
-# Copyright (c) 2008, Florian Weimer <fw@deneb.enyo.de> for the original
-# Debian/OpenSSL Weak Key Detector
-# (http://security.debian.org/project/extra/dowkd/dowkd.pl.gz)
-#
-# Copyright (c) 2008, Alexander Wirt <formorer@debian.org> for check_weakkeys
-#
-# Copyright (c) 2008 Peter Palfrader <peter@palfrader.org>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-=pod
-
-=head1 NAME
-
-B<check_weakkeys> - checks system for weak ssh keys
-
-=cut
-
-=head1 SYNOPSIS
-
-B<check_weakkeys> [options]
-
-=cut
-
-=head1 DESCRIPTION
-
-B<check_weakkeys> checks for all users if there id_rsa, id_dsa or
-authorized_key files if they contain weak ssh keys created by a Debian with a
-broken libssl (see DSA-1571 for more informations). Optionally <check_weakkeys>
-can spit out a warning of there are any DSA keys left in key or authorized_key
-files. To work it needs a database of precomputed hashes of known weak keys.
-This file is expected as an bdb database with the hash (like
-03:a2:f0:46:7f:13:9f:5f:96:71:a9:b8:a0:1c:01:05) as key. See <gen_fprdb> for
-such a database generator. <check_weakkeys> outputs his data to STDOUT or to a
-file. It meaned to be picked up by an nagios check like B<dsa-check-statusfile>
-from Peter Palfrader.
-
-=cut
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-h, --help>
-
-Prints out a brief help
-
-=item B<-s, --statusfile> "statusfile"
-
-Use 'F<statusfile>' instead of 'F<STDOUT>'.
-
-=item B<-f, --fprdb> "database" (default: /var/lib/dsa/ssh-weak-keys.db)
-
-Use 'F<database>' instead of 'F</var/lib/dsa/ssh-weak-keys.db>'
-as fingerprint database.
-
-=item B<-n, --dsa_nowarn>
-
-Don't warn for DSA keys
-
-=back
-
-=cut
-
-use strict;
-use warnings;
-
-use File::Temp;
-use BerkeleyDB;
-use Pod::Usage;
-use Getopt::Long;
-use IPC::Open3;
-
-my $fprdb_fname = "/var/lib/dsa/ssh-weak-keys.db" ;
-my ($outfile, $help);
-my $dsa_nowarn = 0;
-
-GetOptions( 'help|h' => \$help, #Help function
- 'statusfile|s=s' => \$outfile,
- 'fprdb|f=s' => \$fprdb_fname,
- 'n|dsa_nowarn' => \$dsa_nowarn,
-);
-
-pod2usage(1) if $help;
-
-my $fh;
-if ($outfile) {
- open ($fh, '>', $outfile)
- or die "Could not open statusfile '$outfile' for writing: $!";
-} else {
- $fh = *STDOUT;
-}
-
-my %fpr_hash;
-tie %fpr_hash, 'BerkeleyDB::Btree',
- -Filename => $fprdb_fname,
- -Flags => DB_RDONLY
- or die "Cannot open fingerprint db $fprdb_fname: $! $BerkeleyDB::Error\n";
-
-
-my ($weak_keys,$checked_keys) = 0;
-my $dsa_keys = 0;
-my $weird_keyfiles = 0;
-my $text = '';
-my %key_sizes;
-
-
-
-#&from_user_all;
-&from_debianorg_places;
-&from_ssh_host(qw(localhost));
-
-my $status="OK";
-if ($weak_keys) {
- $status = "CRITICAL";
-} elsif ($dsa_keys && ! $dsa_nowarn || $weird_keyfiles) {
- $status = "WARNING";
-}
-
-print $fh "$status\n";
-print $fh "Checked $checked_keys keys - $weak_keys weak - $dsa_keys dsa keys\n";
-print $fh "Sizes: ";
-foreach my $size (sort(keys(%key_sizes))) {
- print $fh "$size:$key_sizes{$size} ";
-}
-
-print $fh "\n";
-print $fh "$text" if $text;
-
-
-
-sub safe_backtick (@) {
- my @args = @_;
-
- my ($wtr, $fh, $err);
-
- open3($wtr,$fh,$err, @args)
- or die "error: failed to spawn $args[0]: $!\n";
- my @result;
- if (wantarray) {
- @result = <$fh>;
- } else {
- local $/;
- @result = scalar(<$fh>);
- }
- close $fh;
- $? == 0 or return undef;
- if (wantarray) {
- return @result;
- } else {
- return $result[0];
- }
-}
-
-sub ssh_fprint_file ($) {
- my $name = shift;
- my $data = safe_backtick qw/ssh-keygen -l -f/, $name;
- defined $data or return ();
- my @data = $data =~ /^(\d+) ([0-9a-f]{2}(?::[0-9a-f]{2}){15})/;
- return @data if @data == 2;
- return ();
-}
-
-sub ssh_fprint_check ($$$) {
- my ($name, $length, $hash) = @_;
- if (exists $key_sizes{$length}) {
- $key_sizes{$length}++;
- } else {
- $key_sizes{$length}=1;
- }
- $checked_keys++;
- if (exists $fpr_hash{$hash}) {
- $weak_keys++;
- $text .= "$name weak ($hash)\n";
- }
-}
-
-
-sub from_ssh_key_file ($) {
- my $name = shift;
- if (open (my $FH, '<', $name)) {
- my $key = <$FH>;
- if (! defined $key) {
- $weird_keyfiles++;
- $text .= "cannot read $name properly - empty?\n";
- } elsif ($key =~ m/ssh-dss/) {
- $dsa_keys++;
- $text .= "$name is a DSA key\n";
- }
- } else {
- $text .= "Could not open $name: $!";
- }
- my ($length, $hash) = ssh_fprint_file $name;
- if ($length && $hash) {
- ssh_fprint_check "$name:1", $length, $hash;
- } else {
- $text .= "$name:1: warning: failed to parse SSH key file\n";
- }
-}
-
-sub clear_tmp ($) {
- my $tmp = shift;
- seek $tmp, 0, 0 or die "seek: $!";
- truncate $tmp, 0 or die "truncate: $!";
-}
-
-sub from_ssh_auth_file ($) {
- my $name = shift;
- my $auth;
- unless (open $auth, '<', $name) {
- warn "$name:0: error: open failed: $!\n";
- return;
- }
- my $tmp = new File::Temp;
- while (my $line = <$auth>) {
- chomp $line;
- my $lineno = $.;
- clear_tmp $tmp;
- next if $line =~ m/^$/; # ignore empty lines
- next if $line =~ m/^#/; # ignore comments
- if ($line =~ m/ssh-dss/) {
- $dsa_keys++;
- $text .= "$name:$lineno is a DSA key\n";
- }
- print $tmp "$line\n" or die "print: $!";
- $tmp->flush;
- my ($length, $hash) = ssh_fprint_file "$tmp";
- if ($length && $hash) {
- ssh_fprint_check "$name:$lineno", $length, $hash;
- } else {
- $text .= "$name:$lineno: warning: unparsable line\n";
- }
- }
-}
-
-sub from_ssh_host (@) {
- my @names = @_;
- my @lines;
- push @lines, safe_backtick qw|ssh-keyscan -t rsa|, @names;
- push @lines, safe_backtick qw|ssh-keyscan -t dsa|, @names;
-
- my $tmp = new File::Temp;
- for my $line (@lines) {
- next if $line =~ /^#/;
- next if $line =~ /^no hostkey alg/;
- my ($host, $data) = $line =~ /^(\S+) (.*)$/;
- clear_tmp $tmp;
- print $tmp "$data\n" or die "print: $!";
- $tmp->flush;
- my ($length, $hash) = ssh_fprint_file "$tmp";
- if ($length && $hash) {
- ssh_fprint_check "$host", $length, $hash;
- } else {
- $text .= "$host: warning: unparsable line\n";
- }
- }
-}
-
-sub from_user ($) {
- my $user = shift;
- my ($name,$passwd,$uid,$gid,
- $quota,$comment,$gcos,$dir,$shell,$expire) = getpwnam($user);
- my $file = "$dir/.ssh/authorized_keys";
- from_ssh_auth_file $file if -r $file;
- $file = "$dir/.ssh/authorized_keys2";
- from_ssh_auth_file $file if -r $file;
- $file = "$dir/.ssh/id_rsa.pub";
- from_ssh_key_file $file if -r $file;
- $file = "$dir/.ssh/id_dsa.pub";
- from_ssh_key_file $file if -r $file;
-}
-
-sub from_user_all () {
- setpwent;
- while (my $name = getpwent) {
- from_user $name;
- }
- endpwent;
-}
-
-
-sub from_debianorg_places () {
- open(F, "/etc/ssh/sshd_config") or die ("Cannot open /etc/ssh/sshd_config: $!\n");
- my @lines = <F>;
- close(F);
-
- my @ak = grep { /^AuthorizedKeysFile\s/i } @lines;
- my @ak2 = grep { /^AuthorizedKeysFile2\s/i } @lines;
-
- if (scalar @ak != 1) {
- print $fh "UNKNOWN\n";
- print $fh "There is more than one AuthorizedKeysFile definition in sshd_config\n";
- exit
- }
- if (scalar @ak2 != 1) {
- print $fh "UNKNOWN\n";
- print $fh "There is more than one AuthorizedKeysFile2 definition in sshd_config\n";
- exit
- }
- unless ($ak[0] =~ m#^((?i)AuthorizedKeysFile)\s+/etc/ssh/userkeys/%u$# ) {
- print $fh "UNKNOWN\n";
- print $fh "The AuthorizedKeysFile definition has an unexpected value. Should be /etc/ssh/userkeys/%u\n";
- exit
- }
- unless ($ak2[0] =~ m#^((?i)AuthorizedKeysFile2)\s+/var/lib/misc/userkeys/%u$# ) {
- print $fh "UNKNOWN\n";
- print $fh "The AuthorizedKeysFile2 definition has an unexpected value. Should be /var/lib/misc/userkeys/%u\n";
- exit
- }
-
- for my $d (qw{/etc/ssh/userkeys /var/lib/misc/userkeys}) {
- next unless (-d $d);
- opendir(D, $d) or die "Cannot opendir $d: $!\n";
- for my $file (grep { ! -d $d.'/'.$_ } readdir(D)) {
- next if ($file eq 'README-DSA-BUILDD');
- my $f = $d.'/'.$file;
- from_ssh_key_file $f if -r $f;
- };
- };
-}
-
-