X-Git-Url: https://git.adam-barratt.org.uk/?a=blobdiff_plain;f=dsa-nagios-checks%2Fchecks%2Fdsa-check-zone-rrsig-expiration;h=1b54970d76c79918c1c66af97217d5ba18aa059b;hb=3551260dad9b25594a1460dfdecfd2171f78b349;hp=1349863e82f46ea1446d75fe6ada844b2819bbab;hpb=e1ca7b9a1cc4d84c9eb71010c257e93aae498a9a;p=mirror%2Fdsa-nagios.git diff --git a/dsa-nagios-checks/checks/dsa-check-zone-rrsig-expiration b/dsa-nagios-checks/checks/dsa-check-zone-rrsig-expiration index 1349863..1b54970 100755 --- a/dsa-nagios-checks/checks/dsa-check-zone-rrsig-expiration +++ b/dsa-nagios-checks/checks/dsa-check-zone-rrsig-expiration @@ -39,6 +39,14 @@ # POSSIBILITY OF SUCH DAMAGE. # Copyright (c) 2010 Peter Palfrader +# - various fixes and cleanups +# - do more than one zone +# Copyright (c) 2012 Peter Palfrader +# - add -s option to configure udp packet size. default changed from 4k to 1k +# Copyright (c) 2013 Peter Palfrader +# - add -r option to override initial refs. +# Copyright (c) 2014 Peter Palfrader +# - Do not ask for RRSIG directly, instead ask for SOA with dnssec data # usage @@ -74,18 +82,33 @@ use Time::HiRes qw ( gettimeofday tv_interval); use Time::Local; use List::Util qw ( shuffle ); -my %opts = (t=>30); -getopts('hZ:dt:', \%opts); -usage() unless $opts{Z}; +sub convert_time { + my $in = shift; + my ($ticks, $unit) = ($in =~ /^(\d+)([smhdw]?)$/); + + if ($unit eq 's' || $unit eq '') { } + elsif ($unit eq 'm') { $ticks *= 60; } + elsif ($unit eq 'h') { $ticks *= 60*60; } + elsif ($unit eq 'd') { $ticks *= 60*60*24; } + elsif ($unit eq 'w') { $ticks *= 60*60*24*7; } + else { die "Invalid unit '$unit' in '$in'\n" } + return $ticks; +} + +my %opts = (t=>30, s=>1024); +getopts('hdt:c:w:s:r:', \%opts); +usage() unless scalar @ARGV == 1; usage() if $opts{h}; -my $zone = $opts{Z}; -$zone =~ s/^zone\.//; +my $zone = $ARGV[0]; my $data; my $start; my $stop; -my $CRIT_DAYS = 3; -my $WARN_DAYS = 7; +my $CRIT = 3 * 3600*24; +my $WARN = 7 * 3600*24; + +$CRIT = convert_time($opts{c}) if defined $opts{c}; +$WARN = convert_time($opts{w}) if defined $opts{w}; my @refs = qw ( a.root-servers.net @@ -102,6 +125,7 @@ k.root-servers.net l.root-servers.net m.root-servers.net ); +@refs = split(/\s*,\s*/, $opts{r}) if (defined $opts{r}); $start = [gettimeofday()]; do_recursion(); @@ -115,25 +139,28 @@ sub do_recursion { do { print STDERR "\nRECURSE\n" if $opts{d}; my $pkt; + my $prettyrefs = (scalar @refs) ? join(", ", @refs) : "empty set(!?)"; foreach my $ns (shuffle @refs) { - print STDERR "sending query for $zone RRSIG to $ns\n" if $opts{d}; + print STDERR "sending query for $zone NS to $ns\n" if $opts{d}; $res->nameserver($ns); $res->udp_timeout($opts{t}); - $res->udppacketsize(4096); - $pkt = $res->send($zone, 'RRSIG'); + $res->udppacketsize($opts{s}); + $pkt = $res->send($zone, 'NS'); last if $pkt; } - critical("No response to seed query") unless $pkt; + critical("No response to seed query for $zone from $prettyrefs.") unless $pkt; critical($pkt->header->rcode . " from " . $pkt->answerfrom) unless ($pkt->header->rcode eq 'NOERROR'); @refs = (); - foreach my $rr ($pkt->authority) { + foreach my $rr ($pkt->authority, $pkt->answer) { print STDERR $rr->string, "\n" if $opts{d}; - push (@refs, $rr->nsdname); + push (@refs, $rr->nsdname) if $rr->type eq 'NS'; next unless lc($rr->name) eq lc($zone); add_nslist_to_data($pkt); + #print STDERR "Adding for $zone: ", $pkt->string, "\n" if $opts{d}; $done = 1; } + critical("No new references after querying for $zone NS from $prettyrefs. Packet was ".$pkt->string) unless (scalar @refs); } while (! $done); } @@ -144,11 +171,11 @@ sub do_queries { $n = 0; foreach my $ns (keys %$data) { next if $data->{$ns}->{done}; - print STDERR "\nQUERY $ns\n" if $opts{d}; + print STDERR "\nQUERY \@$ns SOA $zone\n" if $opts{d}; - my $pkt = send_query($zone, 'RRSIG', $ns); + my $pkt = send_query($zone, 'SOA', $ns); add_nslist_to_data($pkt); - $data->{$ns}->{queries}->{RRSIG} = $pkt; + $data->{$ns}->{queries}->{SOA} = $pkt; print STDERR "done with $ns\n" if $opts{d}; $data->{$ns}->{done} = 1; @@ -163,7 +190,7 @@ sub do_analyze { my %MAX_EXP_BY_TYPE; foreach my $ns (keys %$data) { print STDERR "\nANALYZE $ns\n" if $opts{d}; - my $pkt = $data->{$ns}->{queries}->{RRSIG}; + my $pkt = $data->{$ns}->{queries}->{SOA}; critical("No response from $ns") unless $pkt; print STDERR $pkt->string if $opts{d}; critical($pkt->header->rcode . " from $ns") @@ -194,15 +221,15 @@ sub do_analyze { } } critical("$min_ns has expired RRSIGs") if ($min_exp < $NOW); - if ($min_exp - $NOW < ($CRIT_DAYS*86400)) { + if ($min_exp - $NOW < ($CRIT)) { my $ND = sprintf "%3.1f days", ($min_exp-$NOW)/86400; critical("$min_type RRSIG expires in $ND at $min_ns") } - if ($min_exp - $NOW < ($WARN_DAYS*86400)) { + if ($min_exp - $NOW < ($WARN)) { my $ND = sprintf "%3.1f days", ($min_exp-$NOW)/86400; warning("$min_type RRSIG expires in $ND at $min_ns") } - success("No RRSIGs expiring in the next $WARN_DAYS days"); + success(sprintf("No RRSIGs at zone apex expiring in the next %3.1f days", $WARN/86400)); } sub sigrr_exp_epoch { @@ -252,7 +279,7 @@ sub output { } sub usage { - print STDERR "usage: $0 [-d] [-t=] -Z zone\n"; + print STDERR "usage: $0 [-d] [-w=] [-c=] [-t=] [-r=[,[,..]]] [-s=] \n"; exit 3; } @@ -263,8 +290,9 @@ sub send_query { my $res = Net::DNS::Resolver->new; $res->nameserver($server) if $server; $res->udp_timeout($opts{t}); + $res->dnssec(1); $res->retry(2); - $res->udppacketsize(4096); + $res->udppacketsize($opts{s}); my $pkt = $res->send($qname, $qtype); unless ($pkt) { $res->usevc(1); @@ -277,11 +305,11 @@ sub send_query { sub get_nslist { my $pkt = shift; return () unless $pkt; - return () unless $pkt->authority; + return () if (!$pkt->authority && !$pkt->answer); my @nslist; - foreach my $rr ($pkt->authority) { + foreach my $rr ($pkt->authority, $pkt->answer) { next unless ($rr->type eq 'NS'); - next unless ($rr->name eq $zone); + next unless lc($rr->name) eq lc($zone); push(@nslist, lc($rr->nsdname)); } return @nslist;