X-Git-Url: https://git.adam-barratt.org.uk/?a=blobdiff_plain;f=dsa-nagios-checks%2Fchecks%2Fdsa-check-dnssec-delegation;h=65b48b0cb19342d056ad6848b044b3da4f62f98e;hb=37663a677deb85798a66d091537c96b3e65b7d74;hp=6afc2d5e581868b5f0e5f8547fdcc8fbb5e42466;hpb=e69f77d06c86c5aad6ad96e5ccc77bfa5cf72ec0;p=mirror%2Fdsa-nagios.git diff --git a/dsa-nagios-checks/checks/dsa-check-dnssec-delegation b/dsa-nagios-checks/checks/dsa-check-dnssec-delegation index 6afc2d5..65b48b0 100755 --- a/dsa-nagios-checks/checks/dsa-check-dnssec-delegation +++ b/dsa-nagios-checks/checks/dsa-check-dnssec-delegation @@ -1,6 +1,6 @@ #!/usr/bin/perl -# Copyright (c) 2010 Peter Palfrader +# Copyright (c) 2010, 2014, 2015, 2017 Peter Palfrader # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -57,6 +57,7 @@ my $params; sub get_tag_generic { my $zone = shift; my $type = shift; + my %options = @_; my @result; my @zsks; @@ -68,35 +69,45 @@ sub get_tag_generic { next unless ($rr->type eq $type); next unless (lc($rr->name) eq lc($zone)); + my $tag = $options{'pretty'} ? sprintf("%5d(%d)", $rr->keytag, $rr->algorithm) : $rr->keytag; + + if ($type eq 'DNSKEY' && ($rr->{'flags'} & (1<<(15-8)))) { + # key is revoked + next; + } + # for now only handle KSKs, i.e. keys with the SEP flag set - if ($type eq 'DNSKEY' && !($rr->is_sep)) { - push @zsks, $rr->keytag; + if ($type eq 'DNSKEY' && !($rr->sep)) { + push @zsks, $tag; next; } - push @result, $rr->keytag; + push @result, $tag; }; if ($type eq 'DNSKEY' && (scalar @result) == 0) { # use remaining keys if no keys with the SEP bit are present @result = @zsks; } my %unique = (); - @result = sort {$a <=> $b} grep {!$unique{$_}++} @result; + @result = sort {$a cmp $b} grep {!$unique{$_}++} @result; return @result }; sub get_dnskeytags { my $zone = shift; - return get_tag_generic($zone, 'DNSKEY'); + my %options = @_; + return get_tag_generic($zone, 'DNSKEY', %options); }; sub get_dstags { my $zone = shift; - return get_tag_generic($zone, 'DS'); + my %options = @_; + return get_tag_generic($zone, 'DS', %options); }; sub get_dlvtags { my $zone = shift; + my %options = @_; $zone .= ".".$DLV; - return get_tag_generic($zone, 'DLV'); + return get_tag_generic($zone, 'DLV', %options); }; sub has_dnskey_parent { my $zone = shift; @@ -175,6 +186,15 @@ sub what_to_check { return { 'dlv' => $do_dlv, 'ds' => $do_ds }; } +sub diff_spec { + my $a = shift; + my $b = shift; + + my @elems = intersect(@$a, @$b); + push @elems, map { '-'.$_ } array_minus(@$a, @$b); + push @elems, map { '+'.$_ } array_minus(@$b, @$a); + return join(',', @elems); +} Getopt::Long::config('bundling'); GetOptions ( @@ -223,15 +243,15 @@ $DLV = $params->{'dlv'} if $params->{'dlv'}; if ($mode eq 'overview') { my %data; for my $zone (keys %zones) { - $data{$zone} = { 'dnskey' => join(', ', get_dnskeytags($zone)), - 'ds' => join(', ', get_dstags($zone)), - 'dlv' => join(', ', get_dlvtags($zone)), + $data{$zone} = { 'dnskey' => join(', ', get_dnskeytags($zone, pretty=>1)), + 'ds' => join(', ', get_dstags($zone, pretty=>1)), + 'dlv' => join(', ', get_dlvtags($zone, pretty=>1)), 'parent_dnssec' => get_parent_dnssec_status($zone) }; } - my $format = "%60s %-15s %-15s %-3s %-10s\n"; + my $format = "%60s %-20s %-15s %-3s %-10s\n"; printf $format, "zone", "DNSKEY", "DS\@parent", "DLV", "dnssec\@parent"; - printf $format, "-"x 60, "-"x 15, "-"x 15, "-"x 3, "-"x 10; + printf $format, "-"x 60, "-"x 20, "-"x 15, "-"x 3, "-"x 10; for my $zone (sort {$a cmp $b} keys %data) { printf $format, $zone, $data{$zone}->{'dnskey'}, @@ -254,27 +274,18 @@ if ($mode eq 'overview') { } my @dnskey = get_dnskeytags($zone); - my $dnskey = join(",", @dnskey) || '-'; for my $thiskey (@to_check) { my @target = $thiskey eq 'ds' ? get_dstags($zone) : get_dlvtags($zone); - my $target = join(",", @target) || '-'; - my @isect = intersect(@dnskey, @target); - if (scalar @isect == 0) { + my $spec = diff_spec(\@target, \@dnskey); + # if the intersection between DS and KEY is empty, + # or if there are DS records for keys we do not have, that's an issue. + if (intersect(@dnskey, @target) == 0 || array_minus(@target, @dnskey)) { if ($require->{$thiskey} || scalar @target > 0) { - push @warn, "$zone ([$dnskey] ~ [$target])"; + push @warn, "$zone ($spec)"; } } else { if ($require->{$thiskey}) { - my $spec; - if (!array_diff(@dnskey, @target)) { - $spec = $dnskey; - } else { - my @elems = intersect(@dnskey, @target); - push @elems, map { '-'.$_ } array_minus(@target, @dnskey); - push @elems, map { '+'.$_ } array_minus(@dnskey, @target); - $spec = join ',', @elems; - } push @ok, "$zone ($spec)"; } };