Kaarsemaker.net


check_trace
3.79 KB

140 lines

Download

check_nick
jabber_notify

Preview

 1 #!/usr/bin/perl
 2 #
 3 # check_trace plugin for nagios
 4 # 
 5 # This plugins checks whether a hostname resolves to the address you expect
 6 # it to. It uses dig +trace to check the entire path, from the root
 7 # nameservers to your domain
 8 #
 9 # See check_trace -h for usage information
10 # (c)2008 Dennis Kaarsemaker - Licensed under GNU GPL v3 or later
11 
12 use strict;
13 use warnings;
14 
15 sub print_help ();
  1 #!/usr/bin/perl
  2 #
  3 # check_trace plugin for nagios
  4 # 
  5 # This plugins checks whether a hostname resolves to the address you expect
  6 # it to. It uses dig +trace to check the entire path, from the root
  7 # nameservers to your domain
  8 #
  9 # See check_trace -h for usage information
 10 # (c)2008 Dennis Kaarsemaker - Licensed under GNU GPL v3 or later
 11 
 12 use strict;
 13 use warnings;
 14 
 15 sub print_help ();
 16 sub _usage ();
 17 sub in ($$);
 18 
 19 use Getopt::Long;
 20 
 21 use lib '/usr/lib/nagios/plugins';
 22 use utils qw(%ERRORS $TIMEOUT &print_revision &usage);
 23 
 24 our ($progname, $progversion);
 25 my ($opt_h, $opt_A, $opt_V);
 26 my ($verbose, $host, $address, @addresses, @found_addresses, $cnames);
 27 
 28 $progname = "check_trace";
 29 $progversion = "1.0";
 30 $cnames = 5;
 31 
 32 
 33 # Parse options
 34 Getopt::Long::Configure('bundling');
 35 GetOptions(
 36     "V"   => \$opt_V,   "version"   => \$opt_V,
 37     "h"   => \$opt_h,   "help"      => \$opt_h,
 38     "H=s" => \$host,    "hostname"  => \$host,
 39     "a=s" => \$address, "address"   => \$address,
 40     "A=s" => \$opt_A,   "addresses" => \$opt_A,
 41     "v"   => \$verbose, "verbose"   => \$verbose,
 42     "c"   => \$cnames,  "cnames"    => \$cnames,
 43 );
 44 
 45 if ($opt_h) { print_help(); exit $ERRORS{"OK"}; }
 46 if ($opt_V) { print_revision($progname, $progversion); exit $ERRORS{"OK"}; } 
 47 @addresses = ();
 48 @addresses = split(/,/, $opt_A) if(defined($opt_A));
 49 push(@addresses, $address);
 50 
 51 usage(_usage) unless $host;
 52 usage(_usage) unless $address;
 53 
 54 # Trace the hostname
 55 my $orig_host = $host;
 56 $host .= '.' unless $host =~ /\.$/;
 57 my @ns_trace = ();
 58 my $cname_count = 0;
 59 
 60 while($cname_count <= $cnames) {
 61     my $cname = undef;
 62     print "*** Searching $host\n" if $verbose;
 63     open(DIG, '-|', "dig +time=$TIMEOUT +trace $host");
 64     while(<DIG>) {
 65         print if $verbose;
 66         # ;; Received 427 bytes from 192.33.4.12#53(C.ROOT-SERVERS.NET) in 24 ms
 67         if(/^;; Received.*?\((.*?)\)./) {
 68             push(@ns_trace, $1);
 69         }
 70         # foo.example.com.  86400   IN  CNAME   bar.example.com.
 71         if(/$host\s+\d+\s+IN\s+CNAME\s+(.*)/) {
 72             $cname = sprintf('%s CNAME %s', $host, $1);
 73             $host = $1;
 74         }
 75         # bar.example.com. 300 IN  A   127.0.0.1
 76         if(/$host\s+\d+\s+IN\s+A\s+(.*)/) {
 77             push(@found_addresses, $1);
 78         }
 79     }
 80     last if not defined($cname);
 81     last if @found_addresses;
 82     push(@ns_trace, $cname);
 83     $cname_count++;
 84 }
 85 
 86 # So, did it work?
 87 if($cname_count == $cnames) {
 88     print "Need to follow too many cnames (more than $cnames) to resolve address";
 89     exit($ERRORS{"CRITICAL"});
 90 }
 91 
 92 my @errors;
 93 foreach my $address (@addresses) {
 94     if(!in(\@found_addresses, $address)) {
 95        push(@errors,"$orig_host did not resolve to $address");
 96     }
 97 }
 98 foreach my $address (@found_addresses) {
 99     if(!in(\@addresses, $address)) {
100         push(@errors, "$orig_host resolved to unknonwn IP $address");
101     }
102 }
103 if(@errors) {
104     print join(', ', @errors);
105     exit $ERRORS{"CRITICAL"};
106 }
107 print "$orig_host resolved to ".join(', ', @addresses)." via ".join(', ', @ns_trace);
108 exit $ERRORS{"OK"};
109 
110 sub print_help() {
111     print_revision($progname, $progversion);
112     print "\n" .
113     _usage .
114     "\n" .
115     "-H|--hostname hostname to resolve\n" .
116     "-a|--address address it resolves to\n" .
117     "-A|--addresses extra addresses it can resolve to (round robin)\n" .
118     "-c|--cnames max. number of CNAME's to follow\n" .
119     "\n" .
120     "The plugin will use dig +trace to trace your hostname. It will\n" .
121     "allso follow CNAME's unless the A answer came in baliwick\n";
122 }
123 
124 sub _usage() {
125     return "Usage:\n$progname -H hostname -a address [-A extra_addresses] -v\n" .
126            "$progname -h|--help\n" .
127            "$progname -V|--version\n"
128 }
129 
130 sub in($$) {
131     my $array_ref = shift;
132     my $test = shift;
133 
134     foreach my $element (@{$array_ref}) {
135         if ($test eq $element) {
136             return 1;
137         }
138     }
139     return 0;
140 }

Show all