diff options
Diffstat (limited to 'nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth')
5 files changed, 363 insertions, 0 deletions
diff --git a/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/Makefile b/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/Makefile new file mode 100644 index 0000000..23f8a8f --- /dev/null +++ b/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/Makefile @@ -0,0 +1 @@ +include ../common.mk diff --git a/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/check_zone_auth b/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/check_zone_auth new file mode 100644 index 0000000..372a2be --- /dev/null +++ b/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/check_zone_auth @@ -0,0 +1,324 @@ +#!/usr/bin/perl + +# $Id: check_zone_auth,v 1.13 2010/07/23 15:54:08 wessels Exp $ +# +# check_zone_auth +# +# nagios plugin to check that all authoritative nameservers for a zone +# have the same NS RRset and the same serial number. +# +# Can also check that the NS RRset is equal to specific nameservers +# passed on the command line. + + +# Copyright (c) 2008, The Measurement Factory, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# Neither the name of The Measurement Factory nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# USAGE +# +# define command { +# command_name check-zone-auth +# command_line /usr/local/libexec/nagios-local/check_zone_auth -Z $HOSTADDRESS$ +# } +# +# define service { +# name dns-auth-service +# check_command check-zone-auth +# ... +# } +# +# define host { +# use dns-zone +# host_name zone.example.com +# alias ZONE example.com +# } +# +# define service { +# use dns-auth-service +# host_name zone.example.com +# } + +# CONTRIBUTORS: +# +# Matt Christian + +use warnings; +use strict; + +use Getopt::Std; +use Net::DNS::Resolver; +use Net::DNS::Resolver::Recurse; +use Time::HiRes qw ( gettimeofday tv_interval); +use List::Util qw ( shuffle ); + +use vars qw( %opts @refs $zone $expected_ns_rrset $data $start $stop ); +getopts('Z:N:d', \%opts); +usage() unless $opts{Z}; +usage() if $opts{h}; +$zone = $opts{Z}; +$zone =~ s/^zone\.//; +$expected_ns_rrset = $opts{N} ? join(',', sort split(',', lc($opts{N}))) : undef; + +@refs = qw ( +a.root-servers.net +b.root-servers.net +c.root-servers.net +d.root-servers.net +e.root-servers.net +f.root-servers.net +g.root-servers.net +h.root-servers.net +i.root-servers.net +j.root-servers.net +k.root-servers.net +l.root-servers.net +m.root-servers.net +); + +$start = [gettimeofday()]; +do_recursion(); +do_queries(); +$stop = [gettimeofday()]; +do_analyze(); + +sub do_recursion { + my $done = 0; + my $res = Net::DNS::Resolver->new; + do { + print STDERR "\nRECURSE\n" if $opts{d}; + my $pkt; + foreach my $ns (shuffle @refs) { + print STDERR "sending query for $zone SOA to $ns\n" if $opts{d}; + $res->nameserver($ns); + $res->udp_timeout(5); + $pkt = $res->send($zone, 'SOA'); + last if $pkt; + } + critical("No response to seed query") unless $pkt; + critical($pkt->header->rcode . " from " . $pkt->answerfrom) + unless ($pkt->header->rcode eq 'NOERROR'); + add_nslist_to_data($pkt); + @refs = (); + foreach my $rr ($pkt->authority) { + next unless ($rr->type eq 'NS'); + print STDERR $rr->string, "\n" if $opts{d}; + push (@refs, $rr->nsdname); + next unless names_equal($rr->name, $zone); + $done = 1; + } + } while (! $done); +} + + +sub do_queries { +# +# Net::DNS::Resolver::Recurse has some less-than-desirable +# properties. For one it seems to generate many more queries +# than necessary. Also it seems to have a tough time when +# IPv6 is involved. For now this is disabled in favor +# of a custom, simple recursor +# +# my $recres = Net::DNS::Resolver::Recurse->new; +# $recres->recursion_callback(sub { +# my $p = shift; +# # +# # This debugging below is commented out because it +# # generates a 'Variable "%opts" may be unavailable' +# # warning when ePN (embedded perl nagios) is in use. +# # +# #print STDERR $p->string if $opts{d}; +# add_nslist_to_data($p); +# }); +# my $seed = $recres->query_dorecursion($zone, 'SOA'); +# critical("No response to seed query") unless $seed; +# $recres = undef; +# +# critical($seed->header->rcode . " from " . $seed->answerfrom) +# unless ($seed->header->rcode eq 'NOERROR'); +# print STDERR $seed->string if $opts{d}; +# add_nslist_to_data($seed); + + my $n; + do { + $n = 0; + foreach my $ns (keys %$data) { + next if $data->{$ns}->{done}; + print STDERR "\nQUERY $ns\n" if $opts{d}; + + my $pkt = send_query($zone, 'SOA', $ns); + add_nslist_to_data($pkt); + $data->{$ns}->{queries}->{SOA} = $pkt; + + if ($pkt && $pkt->header->nscount == 0) { + my $ns_pkt = send_query($zone, 'NS', $ns); + add_nslist_to_data($ns_pkt); + $data->{$ns}->{queries}->{NS} = $ns_pkt; + } + + print STDERR "done with $ns\n" if $opts{d}; + $data->{$ns}->{done} = 1; + $n++; + } + } while ($n); +} + +sub do_analyze { + my $maxserial = 0; + my $nscount = 0; + foreach my $ns (keys %$data) { + print STDERR "\nANALYZE $ns\n" if $opts{d}; + my $soa_pkt = $data->{$ns}->{queries}->{SOA}; + critical("No response from $ns") unless $soa_pkt; + print STDERR $soa_pkt->string if $opts{d}; + critical($soa_pkt->header->rcode . " from $ns") + unless ($soa_pkt->header->rcode eq 'NOERROR'); + critical("$ns is lame") unless $soa_pkt->header->ancount; + my $serial = soa_serial($soa_pkt); + $maxserial = $serial if ($serial > $maxserial); + $nscount++; + } + warning("No nameservers found. Is '$zone' a zone?") if ($nscount < 1); + warning("Only one auth NS") if ($nscount < 2); + if ($expected_ns_rrset) { + my $got_ns_rrset = join(',', sort keys %$data); + critical("Unexpected NS RRset: $got_ns_rrset") + unless $expected_ns_rrset eq $got_ns_rrset; + } + foreach my $ns (keys %$data) { + my $soa_pkt = $data->{$ns}->{queries}->{SOA}; + my $ns_pkt = $data->{$ns}->{queries}->{NS}; + + # see if this nameserver lists all nameservers + # + my %all_ns; + foreach my $data_ns (keys %$data) { $all_ns{$data_ns} = 1; } + foreach my $soa_ns (get_nslist($soa_pkt)) { delete $all_ns{$soa_ns}; } + foreach my $ns_ns (get_nslist($ns_pkt)) { delete $all_ns{$ns_ns}; } + if (keys %all_ns) { + warning("$ns does not include " . + join(',', keys %all_ns) . + " in NS RRset"); + } + + warning("$ns claims is it not authoritative") unless $soa_pkt->header->aa; + + my $serial = soa_serial($soa_pkt); + warning("$ns serial ($serial) is less than the maximum ($maxserial)") if ($serial < $maxserial); + } + success("$nscount nameservers, serial $maxserial"); +} + +sub add_nslist_to_data { + my $pkt = shift; + foreach my $ns (get_nslist($pkt)) { + print STDERR "adding NS $ns\n" if $opts{d}; + $data->{$ns}->{done} |= 0; + } +} + +sub soa_serial { + my $pkt = shift; + foreach my $rr ($pkt->answer) { + next unless ($rr->type eq 'SOA'); + next unless ($rr->name eq $zone); + return $rr->serial; + } + return 0; +} + +sub success { + output('OK', shift); + exit(0); +} + +sub warning { + output('WARNING', shift); + exit(1); +} + +sub critical { + output('CRITICAL', shift); + exit(2); +} + +sub output { + my $state = shift; + my $msg = shift; + $stop = [gettimeofday()] unless $stop; + my $latency = tv_interval($start, $stop); + printf "ZONE %s: %s; (%.2fs) |time=%.6fs;;;0.000000\n", + $state, + $msg, + $latency, + $latency; +} + +sub usage { + print STDERR "usage: $0 -Z zone [-N ns1,ns2,ns3]\n"; + print STDERR "\t-Z specifies the zone to test\n"; + print STDERR "\t-N optionally specifies the expected NS RRset\n"; + exit 3; +} + +sub send_query { + my $qname = shift; + my $qtype = shift; + my $server = shift; + my $res = Net::DNS::Resolver->new; + $res->nameserver($server) if $server; + return $res->send($qname, $qtype); +} + +sub get_nslist { + my $pkt = shift; + return () unless $pkt; + my @nslist = (); + foreach my $rr ($pkt->authority) { + next unless ($rr->type eq 'NS'); + next unless names_equal($rr->name, $zone); + push(@nslist, lc($rr->nsdname)); + } + return @nslist if @nslist; + # + # look for NS records in answer section too + # + foreach my $rr ($pkt->answer) { + next unless ($rr->type eq 'NS'); + next unless names_equal($rr->name, $zone); + push(@nslist, lc($rr->nsdname)); + } + return @nslist; +} + +sub names_equal { + my $a = shift; + my $b = shift; + $a =~ s/\.$//; + $b =~ s/\.$//; + lc($a) eq lc($b); +} diff --git a/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/control b/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/control new file mode 100644 index 0000000..08a842d --- /dev/null +++ b/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/control @@ -0,0 +1,7 @@ +Homepage: http://dns.measurement-factory.com/tools/nagios-plugins/check_zone_auth.html +Watch: http://dns.measurement-factory.com/tools/nagios-plugins/src/check_zone_auth Id: check_zone_auth,v ([0-9.]+) +Uploaders: Bernd Zeimetz <bzed@debian.org> +Description: plugin to ensure that the authoritative nameservers + for a given zone remain in sync. +Recommends: libnet-dns-perl +Version: 1.13 diff --git a/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/copyright b/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/copyright new file mode 100644 index 0000000..fab5e90 --- /dev/null +++ b/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/copyright @@ -0,0 +1,27 @@ +Copyright (c) 2008, The Measurement Factory, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +Neither the name of The Measurement Factory nor the names of its +contributors may be used to endorse or promote products derived +from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/zone_auth.cfg b/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/zone_auth.cfg new file mode 100644 index 0000000..d947dcf --- /dev/null +++ b/nagios-plugins-contrib-24.20190301~bpo9+1/check_zone_auth/zone_auth.cfg @@ -0,0 +1,4 @@ +define command { + command_name check_zone_auth + command_line /usr/lib/nagios/plugins/check_zone_auth -Z $HOSTADDRESS$ +} |