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