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