check_scan.pl
changeset 5 b28f231eda85
parent 2 8766cde065c5
equal deleted inserted replaced
4:e10152caf835 5:b28f231eda85
     1 #!/usr/bin/perl -w
     1 #!/usr/bin/perl -w
     2 
     2 
     3 #    Copyright (C) 2011  Christian Arnold
     3 #    Copyright (C) 2012  Christian Arnold
     4 #
     4 #
     5 #    This program is free software: you can redistribute it and/or modify
     5 #    This program is free software: you can redistribute it and/or modify
     6 #    it under the terms of the GNU General Public License as published by
     6 #    it under the terms of the GNU General Public License as published by
     7 #    the Free Software Foundation, either version 3 of the License, or
     7 #    the Free Software Foundation, either version 3 of the License, or
     8 #    (at your option) any later version.
     8 #    (at your option) any later version.
    20 use 5.010;
    20 use 5.010;
    21 use strict;
    21 use strict;
    22 use File::Basename;
    22 use File::Basename;
    23 use Getopt::Long;
    23 use Getopt::Long;
    24 use Pod::Usage;
    24 use Pod::Usage;
       
    25 use Data::Dumper;
    25 
    26 
    26 delete @ENV{ grep /^LC_/ => keys %ENV };
    27 delete @ENV{ grep /^LC_/ => keys %ENV };
    27 $ENV{LANG}   = "C";
    28 $ENV{LANG}   = "C";
    28 $ENV{LC_ALL} = "C";
    29 $ENV{LC_ALL} = "C";
    29 
    30 
    30 sub version($$);
    31 sub version($$);
    31 sub scan($$$);
    32 sub scan($$$);
    32 sub report(@);
    33 sub report($$);
    33 
    34 
    34 my %ERRORS = (
    35 my %ERRORS = (
    35     OK        => 0,
    36     OK        => 0,
    36     WARNING   => 1,
    37     WARNING   => 1,
    37     CRITICAL  => 2,
    38     CRITICAL  => 2,
    39     DEPENDENT => 4
    40     DEPENDENT => 4
    40 );
    41 );
    41 
    42 
    42 my $ME      = basename $0;
    43 my $ME      = basename $0;
    43 my $NAME    = "SCAN";
    44 my $NAME    = "SCAN";
    44 my $VERSION = "0.2";
    45 my $VERSION = "0.5";
    45 
    46 
    46 my %opt = (
    47 my %opt = (
    47     host       => "localhost",
    48     host       => "localhost",
    48     options    => "-sT -sU -r -p1-65535",
    49     options    => "-sS -sU -r -p1-65535",
    49     exceptions => "22/tcp"
    50     exceptions => "22/tcp"
    50 );
    51 );
    51 
    52 
    52 MAIN: {
    53 MAIN: {
    53     Getopt::Long::Configure('bundling');
    54     Getopt::Long::Configure('bundling');
    58         "h|help" => sub { pod2usage( -verbose => 1, -exitval => $ERRORS{OK} ) },
    59         "h|help" => sub { pod2usage( -verbose => 1, -exitval => $ERRORS{OK} ) },
    59         "m|man" => sub { pod2usage( -verbose => 2, -exitval => $ERRORS{OK} ) },
    60         "m|man" => sub { pod2usage( -verbose => 2, -exitval => $ERRORS{OK} ) },
    60         "V|version" => sub { version( $ME, $VERSION ); exit $ERRORS{OK}; }
    61         "V|version" => sub { version( $ME, $VERSION ); exit $ERRORS{OK}; }
    61     ) or pod2usage( -verbose => 1, -exitval => $ERRORS{CRITICAL} );
    62     ) or pod2usage( -verbose => 1, -exitval => $ERRORS{CRITICAL} );
    62 
    63 
    63     my @openports = scan( $opt{host}, $opt{options}, $opt{exceptions} );
    64     my ( $opened, $closed ) =
    64     report(@openports);
    65       scan( $opt{host}, $opt{options}, $opt{exceptions} );
       
    66     report( $opened, $closed );
    65 }
    67 }
    66 
    68 
    67 sub version($$) {
    69 sub version($$) {
    68     my ( $progname, $version ) = @_;
    70     my ( $progname, $version ) = @_;
    69 
    71 
    77 _VERSION
    79 _VERSION
    78 }
    80 }
    79 
    81 
    80 sub scan($$$) {
    82 sub scan($$$) {
    81     my ( $host, $options, $exceptions ) = @_;
    83     my ( $host, $options, $exceptions ) = @_;
    82     my @scan = grep { /^\d+\/.*\s+open/ } `nmap $options $host`;
    84     my @scan = grep { /^\d+\// } `nmap $options $host`;
    83     my @openports;
    85     my @openports;
       
    86     my @closedports;
    84     my @exceptions;
    87     my @exceptions;
    85 
    88 
    86     if ($exceptions) {
    89     if ($exceptions) {
    87         @exceptions = split( /,/, $exceptions );
    90         @exceptions = split( /,/, $exceptions );
    88     }
    91     }
    91         foreach my $exceptions (@exceptions) {
    94         foreach my $exceptions (@exceptions) {
    92             next PORTS if ( $port =~ /^$exceptions/ );
    95             next PORTS if ( $port =~ /^$exceptions/ );
    93         }
    96         }
    94         chomp($port);
    97         chomp($port);
    95         $port =~ s/\s+/ /g;
    98         $port =~ s/\s+/ /g;
    96         push @openports, $port;
    99         push @openports,   $port if ( $port =~ /^\d+\/tcp|udp\s+open\s+/ );
    97     }
   100         push @closedports, $port if ( $port =~ /^\d+\/tcp|udp\s+closed\s+/ );
    98 
   101     }
    99     return @openports;
   102 
   100 }
   103     return ( \@openports, \@closedports );
   101 
   104 }
   102 sub report(@) {
   105 
   103     my @openports = @_;
   106 sub report($$) {
   104 
   107     my $opened = shift;
   105     if (@openports) {
   108     my $closed = shift;
   106         say "$NAME WARNING: " . join( "; ", @openports );
   109 
       
   110     my @opened = @$opened;
       
   111     my @closed = @$closed;
       
   112 
       
   113     if (@opened) {
       
   114         if ( $opt{exceptions} ) {
       
   115             say "$NAME CRITICAL: "
       
   116               . join( "; ", @opened )
       
   117               . " (exceptions: $opt{exceptions})";
       
   118         }
       
   119         else {
       
   120             say "$NAME CRITICAL: "
       
   121               . join( "; ", @opened )
       
   122               . " (exceptions: $opt{exceptions})";
       
   123         }
       
   124         exit $ERRORS{CRITICAL};
       
   125     }
       
   126 
       
   127     if (@closed) {
       
   128         if ( $opt{exceptions} ) {
       
   129             say "$NAME WARNING: "
       
   130               . join( "; ", @closed )
       
   131               . " (exceptions: $opt{exceptions})";
       
   132         }
       
   133         else {
       
   134             say "$NAME WARNING: " . join( "; ", @closed );
       
   135         }
   107         exit $ERRORS{WARNING};
   136         exit $ERRORS{WARNING};
   108     }
   137     }
   109 
   138 
   110     if ( $opt{exceptions} ) {
   139     if ( $opt{exceptions} ) {
   111         say "$NAME OK: no open ports (exceptions: $opt{exceptions})";
   140         say "$NAME OK: no open ports (exceptions: $opt{exceptions})";
   138 
   167 
   139 Host or ip to scan. (default: localhost)
   168 Host or ip to scan. (default: localhost)
   140 
   169 
   141 =item B<-o>|B<--options>
   170 =item B<-o>|B<--options>
   142 
   171 
   143 Nmap options for scan, must be specified in quotes. (default: '-sT -sU -r -p1-65535')
   172 Nmap options for scan, must be specified in quotes. (default: '-sS -sU -r -p1-65535')
   144 
   173 
   145 =item B<-e>|B<--exceptions>
   174 =item B<-e>|B<--exceptions>
   146 
   175 
   147 No warning is generated if any of these ports open. Multiple ports can
   176 No warning is generated if any of these ports open. Multiple ports can
   148 be specified separated by commas (22/tcp,25/tcp,53/udp,...). (default: 22/tcp)
   177 be specified separated by commas (22/tcp,25/tcp,53/udp,...). (default: 22/tcp)
   165 
   194 
   166 This nagios plugin scans hosts with nmap.
   195 This nagios plugin scans hosts with nmap.
   167 
   196 
   168 =head1 VERSION
   197 =head1 VERSION
   169 
   198 
   170 This man page is current for version 0.2 of B<check_scan>.
   199 This man page is current for version 0.5 of B<check_scan>.
   171 
   200 
   172 =head1 AUTHOR
   201 =head1 AUTHOR
   173 
   202 
   174 Written by Christian Arnold L<arnold@schlittermann.de>
   203 Written by Christian Arnold L<arnold@schlittermann.de>
   175 
   204