RFC 5011 trust anchor rollover status

Tony Finch dot at dotat.at
Thu Mar 14 15:31:24 UTC 2013


In response to ICANN's consultation on DNSSEC root key rollovers
http://www.icann.org/en/news/public-comment/root-zone-consultation-08mar13-en.htm
I was wondering how to check that a rollover is progressing OK. BIND
doesn't provide much help with this (unless I have missed something) so I
thought it might be useful to write a script to summarize the RFC 5011
managed keys status. Run it with the path to your managed-keys.bind file
as an argument.

Tony.
-- 
f.anthony.n.finch  <dot at dotat.at>  http://dotat.at/
Forties, Cromarty: East, veering southeast, 4 or 5, occasionally 6 at first.
Rough, becoming slight or moderate. Showers, rain at first. Moderate or good,
occasionally poor at first.



#!/usr/bin/perl

use warnings;
use strict;

use POSIX qw(strftime);
my $now = strftime "%Y%m%d%H%M%S", gmtime;

sub ext8601 ($) {
	my $d = shift;
	$d =~ s{(....)(..)(..)(..)(..)(..)}
	       {$1-$2-$3.$4:$5:$6};
	return $d;
}

sub getkey ($$) {
	my $h = shift;
	my $k = shift;
	m{\s+(\d+)\s+(\d+)\s+(\d+)\s+[(]\s*$};
	$k->{flags}     = $1;
	$k->{protocol}  = $2;
	$k->{algorithm} = $3;
	my $data = "(";
	while (<$h>) {
		s{^\s+}{};
		s{\s+$}{};
		last if m{^[)]};
		$data .= $_;
	}
	m{ alg = (\S+); key id = (\d+)};
	$k->{alg}  = $1;
	$k->{id}   = $2;
	$k->{data} = $data;
	return $k;
}

sub fmtkey ($) {
	my $k = shift;
	return sprintf "%16s tag %s", $k->{name}, $k->{id};
}

sub printstatus ($) {
	my $a = shift;
	if ($a->{removehd} ne "19700101000000") {
		printf " untrusted and to be removed at %s\n", ext8601 $a->{removehd};
	} elsif ($a->{addhd} lt $now) {
		printf " trusted\n";
	} else {
		printf " waiting for %s\n", ext8601 $a->{addhd};
	}
}

sub digkeys ($) {
	my $name = shift;
	my $keys;
	open my $d, "-|", qw{dig +multiline DNSKEY}, $name;
	while (<$d>) {
		next unless m{^([a-z0-9.-]*)\s+\d+\s+IN\s+DNSKEY\s+};
		next unless $name eq $1;
		push @$keys, getkey $d, { name => $name };
	}
	return $keys;
}

my $anchor;
while (<>) {
	next unless m{^([a-z0-9.-]*)\s+KEYDATA\s+(\d+)\s+(\d+)\s+(\d+)\s+};
	my $k = getkey *ARGV, {
		name     => $1,
		refresh  => $2,
		addhd    => $3,
		removehd => $4,
	};
	$k->{name} =~ s{[.]*$}{.};
	push @{$anchor->{$k->{name}}}, $k;
}

for my $name (keys %$anchor) {
	my $keys = digkeys $name;
	my $anchors = $anchor->{$name};
	for my $k (@$keys) {
		if ($k->{flags} & 1) {
			printf "%s %s KSK", fmtkey $k, $k->{alg};
		} else {
			# ZSK - skipping
			next;
		}
		if ($k->{flags} & 512) {
			print " revoked";
		}
		my $a;
		for my $t (@$anchors) {
			if ($t->{data} eq $k->{data} and
			    $t->{protocol} eq $k->{protocol} and
			    $t->{algorithm} eq $k->{algorithm}) {
				$t->{matched} = 1;
				$a = $t;
				last;
			}
		}
		if (not defined $a) {
			print " - WARNING NO MATCHING TRUST ANCHOR\n";
			next;
		}
		printstatus $a;
	}
	for my $a (@$anchors) {
		next if $a->{matched};
		printf "%s %s ???", fmtkey $a, $a->{alg};
		printstatus $a;
	}
}



More information about the bind-users mailing list