O script de plug-in do Nagios não funciona como esperado

1

Eu modifiquei um script perl do Nagios para (em teoria) retornar um ou zero de acordo com a existência, ou não, de um arquivo em um servidor linux remoto. O script executa uma sessão ssh remota e efetua login como o usuário nagios. Os servidores linux remotos têm a configuração de chaves privadas para esse usuário e, na linha de comando bash, o script funciona como esperado, mas quando executado como um plugin, ele sempre retorna '1' (true), mesmo que o arquivo não exista. Alguma ajuda com a lógica ou um comentário sobre por que as coisas não estão funcionando como esperado dentro do Nagios seria apreciado. Eu prefiro usar este método de login ssh em vez de ter que instalar o nrpe em todos os servidores linux.

Para executar a partir de uma linha de comando (supondo que o servidor remoto tenha um usuário chamado nagios com uma chave privada válida):

./check_reboot_required -e ssh -H remote-servers-ip-addr -p 'filename-to-check' -v

Ta.

#! /usr/bin/perl -w
#
#
# 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.
#
############################################################################

use POSIX;
use strict;
use Getopt::Long;
use lib "/usr/lib/nagios/plugins" ;
use vars qw($host $opt_V $opt_h $opt_v $verbose $PROGNAME $pattern $opt_p $mmin $opt_e $opt_t $opt_H $status $state $msg $msg_q $MAILQ $SHELL $device $used $avail $percent $fs $blocks $CMD $RMTOS);
use utils qw(%ERRORS &print_revision &support &usage );

sub print_help ();
sub print_usage ();
sub process_arguments ();

$ENV{'PATH'}='';
$ENV{'BASH_ENV'}=''; 
$ENV{'ENV'}='';
$PROGNAME = "check_reboot_required";

Getopt::Long::Configure('bundling');
$status = process_arguments();

if ($status){
    print "ERROR: processing arguments\n";
    exit $ERRORS{'UNKNOWN'};
}

$SIG{'ALRM'} = sub {
    print ("ERROR: timed out waiting for $CMD on $host\n");
exit $ERRORS{'WARNING'};
};

$host = $opt_H;
$pattern = $opt_p;

print "Pattern >" . $pattern . "< " if $verbose;
alarm($opt_t);

#$CMD = "/usr/bin/find " . $pattern . " -type f 2>/dev/null| /usr/bin/wc -l";
$CMD = "[ -f " . $pattern . " ] && echo 1 || echo 0";

alarm($opt_t);

## get cmd output from remote system

if (! open (OUTPUT, "$SHELL $host $CMD|" ) ) {
    print "ERROR: could not open $CMD on $host\n";
    exit $ERRORS{'UNKNOWN'};
}

my $perfdata = "";
my $state = "3";
my $msg = "Indeterminate result";
# only first line is relevant in this iteration.
while (<OUTPUT>) {
                my $result = chomp($_);
                $msg = $result;
                print "Shell returned >" . $result . "< length is " . length($result)     . " " if $verbose;
                if ( $result == 1 ) {
                  $msg = "Reboot required (NB: Result still not accurate)" . $result ;
                  $state = $ERRORS{'WARNING'};
                  last;
                } elsif ( $result == 0 ) {
                  $msg = "No reboot required (NB: Result still not accurate) " .    $result ;
              $state = $ERRORS{'OK'};
              last;
            }
            else {
              $msg = "Output received, but it was neither a 1 nor a 0" ;
              last;
            }   

}

close (OUTPUT);
print "$msg | $perfdata\n";
exit $state;

#####################################
#### subs


sub process_arguments(){
    GetOptions
        ("V"   => \$opt_V, "version"    => \$opt_V,
         "v"   => \$opt_v, "verbose"    => \$opt_v,
         "h"   => \$opt_h, "help"   => \$opt_h,
         "e=s" => \$opt_e, "shell=s"    => \$opt_e,
             "p=s" => \$opt_p, "pattern=s"  => \$opt_p,
         "t=i" => \$opt_t, "timeout=i"  => \$opt_t,
         "H=s" => \$opt_H, "hostname=s" => \$opt_H
     );

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;
}

    if (defined $opt_e ){
    if ( $opt_e eq "ssh" ) {
        if (-x "/usr/local/bin/ssh") {
        $SHELL = "/usr/local/bin/ssh";
        } elsif ( -x "/usr/bin/ssh" ) {
        $SHELL = "/usr/bin/ssh"; 
        } else {
                    print_usage();
                    exit $ERRORS{'UNKNOWN'};
                }

    } elsif ( $opt_e eq "rsh" ) {
        $SHELL = "/usr/bin/rsh";
    } else {
        print_usage();
                exit $ERRORS{'UNKNOWN'};
    }
    } else {
   print_usage();
       exit $ERRORS{'UNKNOWN'};
}

unless (defined $opt_t) {
    $opt_t = $utils::TIMEOUT ;  # default timeout
}

unless (defined $opt_H) {
    print_usage();
    exit $ERRORS{'UNKNOWN'};
}


return $ERRORS{'OK'};
}

sub print_usage () {
    print "Usage: $PROGNAME -e <shell> -H <hostname> -p <directory/file pattern> [-t <timeout>] [-v verbose]\n";
}

sub print_help () {
print_revision($PROGNAME,'$Revision: 0.1 $');
print "\n";
print_usage();
print "\n";
print "   Checks for the presence of a 'reboot-required' file on a remote host via SSH or RSH\n";
print "-e (--shell)     = ssh or rsh (required)\n";
print "-H (--hostname)  = remote server name (required)";
print "-p (--pattern)   = File pattern for find command (default = /var/run/reboot-required)\n";
print "-t (--timeout)   = Plugin timeout in seconds (default = $utils::TIMEOUT)\n";
print "-h (--help)\n";
print "-V (--version)\n";
print "-v (--verbose)   = debugging output\n";
print "\n\n";
support();
}
    
por Linker3000 09.05.2012 / 12:23

1 resposta

2

O Nagios roda plugins sem qualquer ENV e, portanto, não há $ HOME ... então provavelmente não é possível encontrar as chaves ssh / informações de identidade (você pode simular isso executando seu teste manual através de "env -i"). É por isso que o check_by_ssh tem opções para especificar explicitamente esta informação.

Como grifferz comentou acima, você realmente deveria estar usando check_by_ssh , já que este script perl que você está usando não é muito mais do que uma (pobre) reimplementação do mesmo.

    
por 15.05.2012 / 18:07