[Opendnssec-user] Timing/triggers for ODS2 Enforcer's <DelegationSignerSubmitCommand> & <DelegationSignerRetractCommand> ?
Havard Eidnes
he at uninett.no
Wed Feb 1 14:45:52 UTC 2017
>> Is ODS enforcer polling for a specific trigger to fire each script?
>
> It decides based on its internal state. When a KSK is ready to be
> submitted to the parent the <DelegationSignerSubmitCommand> script
> will run. After that it waits for an external signal (ds-ssen). Given
> by either the operator of a script.
>
>> Or do we need to add polling of some sort in the scripts themselves?
>
> OpenDNSSEC does not poll the parent nameservers to see that DS
> availability. So if you fully want to automate a rollover you will need
> to do some polling yourself before you call ds-ssen.
Indeed. To do this checking with my OpenDNSSEC 1.4.x installation, I
use the attached script as a component in the setup, and do this polling
via cron for zones where the status says "waiting for ds-seen". It must
be run by a user which can do "ods-ksmutil key export".
Regards,
- Håvard
-------------- next part --------------
#! /usr/bin/perl
# $Id: ds-ok.pl,v 1.5 2016/11/30 09:31:49 he Exp $
# Verify that all the parent name servers reply with the correct DS
# record for a given zone.
use strict;
use Net::DNS;
use Net::DNS::SEC;
use Getopt::Std;
sub get_ds_from_ods {
my($z) = @_;
my($in);
my(@ret);
open($in, "ods-ksmutil key export --zone $z " .
"--verbose --ds --keystate ready |") ||
die "Could not run ods-ksmutil to get DS records from OpenDNSSEC: $!";
while(<$in>) {
chomp;
@_ = split;
if (($z . ".") =~ /^$_[0]$/) {
my $ds = join(" ", @_[4..$#_]);
push(@ret, $ds);
}
}
close($in);
return @ret;
}
our $local_ns = Net::DNS::Resolver->new(
recurse => 1,
);
sub get_parent_domain {
my($z) = @_;
if ($z !~ /\.$/) {
$z .= "."; # Absolute DNS name
}
my @c = split(/\./, $z);
shift(@c);
while(@c) {
my $qn = join(".", @c) . ".";
if (&has_nameservers($qn)) {
return $qn;
}
shift(@c);
}
}
sub has_nameservers {
my($z) = @_;
my(@ns);
@ns = &nameservers($z);
return ($#ns > 0);
}
sub nameservers {
my($z) = @_;
my(@ns);
my $repl = $local_ns->query($z, "NS");
if ($repl) {
foreach my $a ($repl->answer) {
if ($a->type eq "NS") {
push(@ns, $a->rdstring);
}
}
return @ns;
}
return undef;
}
sub keytag {
my($ds) = @_;
my @c = split(/\./, $ds);
return $c[0];
}
sub get_dses_from {
my($ns, $name) = @_;
my(@dses);
my $res = Net::DNS::Resolver->new (
nameservers => [ $ns ],
recurse => 0,
);
my $ans = $res->query($name, "DS");
if ($ans) {
foreach my $a ($ans->answer) {
if ($a->type eq "DS") {
my($ds) = join(" ",
($a->keytag,
$a->algorithm,
$a->digtype,
$a->digest));
push(@dses, $ds);
}
}
return @dses;
} else {
return undef;
}
}
sub ds_matches {
my($ds, @match) = @_;
foreach my $m (@match) {
if ($ds eq $m) {
return 1;
}
}
return 0;
}
sub OK_ds_from_parent {
my($z) = @_;
my($p) = &get_parent_domain($z);
my @nses = &nameservers($p);
my @ODS_ds = &get_ds_from_ods($z);
our($opt_a);
my($err) = 0;
if (!@ODS_ds) {
printf(STDERR
"No DS records from OpenDNSSEC for %s.\n" .
"No keys in ready state?\n", $z);
return 0;
}
foreach my $ns (@nses) {
my @dses = &get_dses_from($ns, $z);
my $match = 0;
foreach my $ds (@dses) {
if (&ds_matches($ds, @ODS_ds)) {
$match = 1;
}
}
if (! $match) {
printf(STDERR "No matching DS for %s from %s\n", $z, $ns);
if (!defined($opt_a)) {
return undef;
} else {
$err++;
}
} else {
printf("OK DS for %s from %s\n", $z, $ns);
}
}
if ($opt_a) {
return($err == 0);
}
return 1;
}
#
# Main
#
our $opt_a;
getopts("a");
my $z = $ARGV[0];
if (&OK_ds_from_parent($z)) {
printf("All parent NSes return OK DS records for %s\n", $z);
printf("KSK for %s can be signalled with ds-seen\n", $z);
exit(0);
}
exit(1);
More information about the Opendnssec-user
mailing list