[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