check5011.pl revision 1.1.1.1
126168Sfsmp#!/usr/bin/perl 226168Sfsmp 335393Steggeuse warnings; 426168Sfsmpuse strict; 526168Sfsmp 626168Sfsmpuse POSIX qw(strftime); 728043Sfsmpmy $now = strftime "%Y%m%d%H%M%S", gmtime; 827728Sfsmp 928043Sfsmpsub ext8601 ($) { 1027517Sfsmp my $d = shift; 1127007Sfsmp $d =~ s{(....)(..)(..)(..)(..)(..)} 1228043Sfsmp {$1-$2-$3.$4:$5:$6+0000}; 1328442Sfsmp return $d; 1428442Sfsmp} 1528442Sfsmp 1628442Sfsmpsub getkey ($$) { 1728442Sfsmp my $h = shift; 1828442Sfsmp my $k = shift; 1928442Sfsmp m{\s+(\d+)\s+(\d+)\s+(\d+)\s+[(]\s*$}; 2028442Sfsmp $k->{flags} = $1; 2128442Sfsmp $k->{protocol} = $2; 2228442Sfsmp $k->{algorithm} = $3; 2328442Sfsmp my $data = "("; 2428442Sfsmp while (<$h>) { 2528442Sfsmp s{^\s+}{}; 2628442Sfsmp s{\s+$}{}; 2728442Sfsmp last if m{^[)]}; 2828442Sfsmp $data .= $_; 2928487Sfsmp } 3028442Sfsmp m{ alg = (\S+)\s*; key id = (\d+)}; 3128442Sfsmp $k->{alg} = $1; 3228442Sfsmp $k->{id} = $2; 3328442Sfsmp $k->{data} = $data; 3428442Sfsmp return $k; 3528442Sfsmp} 3628442Sfsmp 3726168Sfsmpsub fmtkey ($) { 3826168Sfsmp my $k = shift; 3926168Sfsmp return sprintf "%16s tag %s", $k->{name}, $k->{id}; 4026168Sfsmp} 4126168Sfsmp 4226168Sfsmpsub printstatus ($) { 4328442Sfsmp my $a = shift; 4426168Sfsmp if ($a->{removehd} ne "19700101000000") { 4528487Sfsmp printf " untrusted and to be removed at %s\n", ext8601 $a->{removehd}; 4626168Sfsmp } elsif ($a->{addhd} le $now) { 4727696Sfsmp printf " trusted\n"; 4828487Sfsmp } else { 4927696Sfsmp printf " waiting for %s\n", ext8601 $a->{addhd}; 5027728Sfsmp } 5127728Sfsmp} 5226168Sfsmp 5326168Sfsmpsub digkeys ($) { 5426168Sfsmp my $name = shift; 5526168Sfsmp my $keys; 5626168Sfsmp open my $d, "-|", qw{dig +multiline DNSKEY}, $name; 5726168Sfsmp while (<$d>) { 5826168Sfsmp next unless m{^([a-z0-9.-]*)\s+\d+\s+IN\s+DNSKEY\s+}; 5926168Sfsmp next unless $name eq $1; 6026168Sfsmp push @$keys, getkey $d, { name => $name }; 6126168Sfsmp } 6226168Sfsmp return $keys; 6326168Sfsmp} 6426168Sfsmp 6528921Sfsmpmy $anchor; 6628442Sfsmpmy $owner = "."; 6726168Sfsmpwhile (<>) { 6828921Sfsmp next unless m{^([a-z0-9.-]*)\s+KEYDATA\s+(\d+)\s+(\d+)\s+(\d+)\s+}; 6928442Sfsmp my $k = getkey *ARGV, { 7027406Sfsmp name => $1, 7128442Sfsmp refresh => $2, 7228442Sfsmp addhd => $3, 7328442Sfsmp removehd => $4, 7428442Sfsmp }; 7528442Sfsmp if ($k->{name} eq "") { 7628442Sfsmp $k->{name} = $owner; 7728442Sfsmp } else { 7828442Sfsmp $owner = $k->{name}; 7928442Sfsmp } 8028442Sfsmp $k->{name} =~ s{[.]*$}{.}; 8128442Sfsmp push @{$anchor->{$k->{name}}}, $k; 8228442Sfsmp} 8328442Sfsmp 8428641Sfsmpfor my $name (keys %$anchor) { 8528442Sfsmp my $keys = digkeys $name; 8628442Sfsmp my $anchors = $anchor->{$name}; 8728442Sfsmp for my $k (@$keys) { 8828442Sfsmp if ($k->{flags} & 1) { 8928442Sfsmp printf "%s %s", fmtkey $k, $k->{alg}; 9028442Sfsmp } else { 9128442Sfsmp # ZSK - skipping 9228442Sfsmp next; 9328442Sfsmp } 9428442Sfsmp if ($k->{flags} & 512) { 9528641Sfsmp print " revoked;"; 9628641Sfsmp } 9728442Sfsmp my $a; 9828442Sfsmp for my $t (@$anchors) { 9928442Sfsmp if ($t->{data} eq $k->{data} and 10028442Sfsmp $t->{protocol} eq $k->{protocol} and 10128442Sfsmp $t->{algorithm} eq $k->{algorithm}) { 10228641Sfsmp $t->{matched} = 1; 10328442Sfsmp $a = $t; 10428641Sfsmp last; 10526168Sfsmp } 10626168Sfsmp } 10728641Sfsmp if (not defined $a) { 10826168Sfsmp print " no trust anchor\n"; 10928641Sfsmp next; 11026168Sfsmp } 11128641Sfsmp printstatus $a; 11226168Sfsmp } 11326168Sfsmp for my $a (@$anchors) { 11426168Sfsmp next if $a->{matched}; 11528442Sfsmp printf "%s %s missing;", fmtkey $a, $a->{alg}; 11626168Sfsmp printstatus $a; 11726168Sfsmp } 11826168Sfsmp} 11926168Sfsmp 12026168Sfsmpexit; 12126168Sfsmp 12226168Sfsmp__END__ 12326168Sfsmp 12426168Sfsmp=head1 NAME 12528641Sfsmp 12626168Sfsmpcheck5011 - summarize DNSSEC trust anchor status 12728641Sfsmp 12826168Sfsmp=head1 SYNOPSIS 12928641Sfsmp 13028641Sfsmpcheck5011 <I<managed-keys.bind>> 13126168Sfsmp 13226168Sfsmp=head1 DESCRIPTION 13326168Sfsmp 13426168SfsmpThe BIND managed-keys file contains DNSSEC trust anchors 13526168Sfsmpthat can be automatically updated according to RFC 5011. The 13628641SfsmpB<check5011> program reads this file and prints a summary of the 13726168Sfsmpstatus of the trust anchors. It fetches the corresponding 13826168SfsmpDNSKEY records using B<dig> and compares them to the trust anchors. 13926168Sfsmp 14028641SfsmpEach key is printed on a line with its name, its tag, and its 14128641Sfsmpalgorithm, followed by a summary of its status. 14228641Sfsmp 14328641Sfsmp=over 14428641Sfsmp 14526168Sfsmp=item C<trusted> 14628641Sfsmp 14726168SfsmpThe key is currently trusted. 14826168Sfsmp 14926168Sfsmp=item C<waiting for ...> 15028442Sfsmp 15128442SfsmpThe key is new, and B<named> is waiting for the "add hold-down" period 15228442Sfsmpto pass before the key will be trusted. 15328487Sfsmp 15428487Sfsmp=item C<untrusted and to be removed at ...> 15528487Sfsmp 15628487SfsmpThe key was revoked and will be removed at the stated time. 15728487Sfsmp 15828487Sfsmp=item C<no trust anchor> 15928487Sfsmp 16028487SfsmpThe key is present in the DNS but not in the managed-keys file. 16128487Sfsmp 16228487Sfsmp=item C<revoked> 16328487Sfsmp 16428487SfsmpThe key has its revoked flag set. This is printed before the key's 16528487Sfsmptrust anchor status which should normally be C<untrusted...> if 16628487SfsmpB<named> has observed the revocation. 16728487Sfsmp 16828487Sfsmp=item C<missing> 16934021Stegge 17034021SteggeThere is no DNSKEY record for this trust anchor. This is printed 17134021Steggebefore the key's trust anchor status. 17234021Stegge 17334021Stegge=back 17434021Stegge 17534021SteggeBy default the managed keys are stored in a file called 17634021SteggeF<managed-keys.bind> in B<named>'s working directory. This location 17734021Steggecan be changed with B<named>'s B<managed-keys-directory> option. If 17834021Steggeyou are using views the file may be named with the SHA256 hash of a 17934021Steggeview name with a F<.mkeys> extension added. 18034021Stegge 18128487Sfsmp=head1 AUTHOR 18228487Sfsmp 18328487Sfsmp=over 18428487Sfsmp 18528487Sfsmp=item Written by Tony Finch <fanf2@cam.ac.uk> <dot@dotat.at> 18628487Sfsmp 18728487Sfsmp=item at the University of Cambridge Computing Service. 18834021Stegge 18934021Stegge=item You may do anything with this. It has no warranty. 19034021Stegge 19128487Sfsmp=item L<http://creativecommons.org/publicdomain/zero/1.0/> 19234021Stegge 19334021Stegge=back 19434021Stegge 19534021Stegge=head1 SEE ALSO 19634021Stegge 19734021Steggedig(1), named(8) 19834021Stegge 19934021Stegge=cut 20034021Stegge