From c54ba0b9990aaa955e0b6ef9b0c1fb1d59e140f6 Mon Sep 17 00:00:00 2001 From: Peter Palfrader Date: Wed, 17 Feb 2010 14:59:35 +0100 Subject: [PATCH] Add dsa-check-dnssec-delegation --- .../checks/dsa-check-dnssec-delegation | 158 ++++++++++++++++++ dsa-nagios-checks/debian/changelog | 3 +- 2 files changed, 160 insertions(+), 1 deletion(-) create mode 100755 dsa-nagios-checks/checks/dsa-check-dnssec-delegation diff --git a/dsa-nagios-checks/checks/dsa-check-dnssec-delegation b/dsa-nagios-checks/checks/dsa-check-dnssec-delegation new file mode 100755 index 0000000..ce56d81 --- /dev/null +++ b/dsa-nagios-checks/checks/dsa-check-dnssec-delegation @@ -0,0 +1,158 @@ +#!/usr/bin/perl + +# Copyright (c) 2010 Peter Palfrader +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +use strict; +use warnings; +use English; +use Net::DNS::Resolver; +use Getopt::Long; + +$SIG{'__DIE__'} = sub { print @_; exit 4; }; + +my $RES = Net::DNS::Resolver->new; +my $DLV = 'dlv.isc.org'; + +sub get_tag_generic { + my $zone = shift; + my $type = shift; + + my @result; + my $pkt = $RES->send($zone, $type); + return () unless $pkt; + return () unless $pkt->answer; + for my $rr ($pkt->answer) { + next unless ($rr->type eq $type); + next unless ($rr->name eq $zone); + + # only handle KSKs, i.e. keys with the SEP flag set + next if ($type eq 'DNSKEY' && !($rr->is_sep)); + + push @result, $rr->keytag; + }; + my %unique = (); + @result = sort {$a <=> $b} grep {!$unique{$_}++} @result; + return @result +}; + +sub get_dnskeytags { + my $zone = shift; + return get_tag_generic($zone, 'DNSKEY'); +}; +sub get_dstags { + my $zone = shift; + return get_tag_generic($zone, 'DS'); +}; +sub get_dlvtags { + my $zone = shift; + $zone .= ".".$DLV; + return get_tag_generic($zone, 'DLV'); +}; + +sub usage { + my $fd = shift; + my $exit = shift; + + print $fd "Usage: $PROGRAM_NAME overview|check-dlv|check-ds zone [zone...]\n"; + print $fd " $PROGRAM_NAME --dir overview|check-dlv|check-ds zone [zone...]\n"; + print $fd " $PROGRAM_NAME --help\n"; + exit $exit; +} + +my $params; +Getopt::Long::config('bundling'); +GetOptions ( + '--help' => \$params->{'help'}, + '--dir=s' => \$params->{'dir'}, + '--dlv=s' => \$params->{'dlv'}, +) or usage(\*STDERR, 1); +usage(\*STDOUT, 0) if ($params->{'help'}); + +my $mode = shift @ARGV; + +my @zones; +if (scalar @ARGV) { + warn "--dir option ignored" if defined $params->{'dir'}; + @zones = @ARGV; +} else { + my $dir = $params->{'dir'}; + usage(\*STDOUT, 0) unless (defined $dir); + + chdir $dir or die "chdir $dir failed? $!\n"; + opendir DIR, '.' or die ("Cannot opendir $dir\n"); + for my $file (readdir DIR) { + next if ( -l "$file" ); + next unless ( -f "$file" ); + next if $file =~ /^(dsset|keyset)-/; + + push @zones, $file; + } + closedir(DIR); +}; + +usage(\*STDOUT, 0) unless (defined $mode && $mode =~ /^(overview|check-dlv|check-ds)$/); +$DLV = $params->{'dlv'} if $params->{'dlv'}; + +my %data; +for my $zone (@zones) { + $data{$zone} = { 'dnskey' => join(', ', get_dnskeytags($zone)), + 'ds' => join(', ', get_dstags($zone)), + 'dlv' => join(', ', get_dlvtags($zone)) }; +} + +if ($mode eq 'overview') { + my $format = "%30s %-16s %-16s %-16s\n"; + printf $format, "zone", "DNSKEY", "DS in parent", "DLV"; + printf $format, "-"x 30, "-"x 16, "-"x 16, "-"x 16; + for my $zone (sort {$a cmp $b} keys %data) { + printf $format, $zone, + $data{$zone}->{'dnskey'}, + $data{$zone}->{'ds'}, + $data{$zone}->{'dlv'}; + } + exit(0); +} elsif ($mode eq 'check-dlv' || $mode eq 'check-ds') { + my $key; + $key = 'dlv' if $mode eq 'check-dlv'; + $key = 'ds' if $mode eq 'check-ds'; + die ("key undefined") unless $key; + + my @warn; + my @ok; + for my $zone (sort {$a cmp $b} keys %data) { + my $dnskey = $data{$zone}->{'dnskey'} || '-'; + my $target = $data{$zone}->{$key} || '-'; + + if ($dnskey ne $target) { + push @warn, "$zone ($dnskey != $target)"; + } else { + push @ok, "$zone ($dnskey)"; + }; + } + print "WARNING: ", join(", ", @warn), "\n" if (scalar @warn); + print "OK: ", join(", ", @ok), "\n" if (scalar @ok); + exit (1) if (scalar @warn); + exit (0); +} else { + die ("Invalid mode '$mode'\n"); +}; + diff --git a/dsa-nagios-checks/debian/changelog b/dsa-nagios-checks/debian/changelog index d07669b..1b1cbbf 100644 --- a/dsa-nagios-checks/debian/changelog +++ b/dsa-nagios-checks/debian/changelog @@ -21,8 +21,9 @@ dsa-nagios-checks (8x) unstable; urgency=low controller with a battery: "ZMM Optimal" is the way it says "optimal". * dsa-check-dabackup-server: check /etc/ssh/userkeys/root instead of /root/.ssh/authorized_keys. + * add dsa-check-dnssec-delegation. - -- Peter Palfrader Sun, 14 Feb 2010 23:34:43 +0100 + -- Peter Palfrader Wed, 17 Feb 2010 14:59:25 +0100 dsa-nagios-checks (84) unstable; urgency=low -- 2.20.1