Hello,
I've created three scripts that parse the XML config from ODS and
create a BIND9 dnssec-signzone commandline that is (or should be)
identical to the ODS signer.
Disclaimer: these scripts are not tested by SIDN and haven't seen
production (yet).
The included README reads:
BIND Alternative (Altbind)
These scripts look at the XML from OpenDNSSEC and use that
to import the relevant keys from our HSM (Luna's from SafeNet).
The keys are formatted for BIND9 consumption (.key/.private files).
Timing meta data from OpenDNSSEC is applied to the keys, then
dnssec-signzone -S (smart signing) is executed.
Scripts:
keyconf.pl
Create a dnssec-keyfromlabel command line according to
the signconf.xml from ODS. Notably it sets the publish
and active times.
signconf.pl
Creates a dnssec-signzone command line equivalent to
the settings in signconf.xml
sign-nl:
Script that calls the above scripts to sign a .nl zone.
The sign-nl script is useless, unless you want to sign a .nl zone, but
it does show how to use keyconf.pl and signconf.pl together.
Feedback (bugs/feature requests) are welcome. The scripts are attached
to this mail.
Kind regards,
--
Miek Gieben
Technical Advisor SIDN
#!/usr/bin/perl
# (c) Miek Gieben, SIDN 2011
# GPL v2
use XML::LibXML;
use Getopt::Long;
use warnings;
use strict;
my $xmlfile;
GetOptions("x=s" => \$xmlfile);
my $parser = XML::LibXML->new();
my $dom = $parser->parse_file($xmlfile) or die "Error parsing xml: $!\n";
if ($#ARGV < 2) {
print "$0: -x xmlconf ENGINE KEYDIR ZONE\n";
exit 1
}
my $e=" -E $ARGV[0]";
my $keydir=" -K $ARGV[1]";
my $z=" $ARGV[2]";
my $kfl="dnssec-keyfromlabel";
# Look for the keys
#
# Clean old keys and then
# -P date/offset - publish date, after this date INCLUDE the key
# -A date/offset - active date, after this date USE the key
my @nodes = $dom->getElementsByTagName("Keys");
my @keys = $nodes[0]->getChildrenByTagName("Key");
foreach my $k (@keys) {
my $keygen = "";
my $locator = ($k->getChildrenByTagName("Locator"))[0]->textContent;
$keygen .= " -l $locator";
my $flags = ($k->getChildrenByTagName("Flags"))[0]->textContent;
if ($flags == 257) {
$keygen .= " -f KSK";
}
my $alg = ($k->getChildrenByTagName("Algorithm"))[0]->textContent;
if ($alg == 8) {
$keygen .= " -a RSASHA256";
}
if ($alg == 10) {
$keygen .= " -a RSASHA512";
}
my $publish = ($k->getChildrenByTagName("Publish"))[0];
if (defined $publish) {
$keygen .= " -P now";
} else {
$keygen .= " -P none";
# don't know what bind9 does if a keys is not published AND active?
}
my $ksk = ($k->getChildrenByTagName("KSK"))[0];
my $zsk = ($k->getChildrenByTagName("ZSK"))[0];
if (defined $zsk or defined $ksk) {
$keygen .= " -A now";
} else {
$keygen .= " -A none";
}
print $kfl, $e, $keydir, $keygen, $z, "\n";
}
#!/usr/bin/perl
# (c) Miek Gieben, SIDN 2011
# GPL v2
use XML::LibXML;
use warnings;
use strict;
if ($#ARGV < 3) {
print "$0: -x xmlconf ENGINE KEYDIR ZONE ZONEFILE\n";
exit 1
}
my $xmlfile;
GetOptions("x=s" => \$xmlfile);
my $e=" -E $ARGV[0]";
my $keydir=" -K $ARGV[1]";
my $z="-o $ARGV[2]";
my $file=" $ARGV[3]";
# convert a timetstamp PTxx[smh] to seconds
sub timestamp2sec($) {
my $stamp = shift;
my ($amount,$what) = $stamp =~ m/PT([0-9]+)([SMH])/;
if ($what eq "S") { ; } # do nothing
if ($what eq "M") { $amount *= 60 }
if ($what eq "H") { $amount *= 3600 }
$amount
}
print "dnssec-signzone ";
my $parser = XML::LibXML->new();
my $dom = $parser->parse_file($xmlfile) or die "Error parsing xml: $!\n";
#
# Sign the KEYSET only with the KSK
#
print "-x ";
#
# Look for NSEC3
#
my @nodes = $dom->getElementsByTagName("NSEC3");
my @opt = $nodes[0]->getChildrenByTagName("OptOut");
# should only be 1
if (@opt + 0 == -1) {
print STDERR "$0: No OptOut?\n";
exit 1
}
if ($opt[0]->toString eq "<OptOut/>") {
print "-A "
} else {
print STDERR "$0: No OptOut?\n";
exit 1;
}
my @h = $nodes[0]->getChildrenByTagName("Hash");
my $algo = ($h[0]->getChildrenByTagName("Algorithm"))[0]->textContent;
my $iter = ($h[0]->getChildrenByTagName("Iterations"))[0]->textContent;
my $salt = ($h[0]->getChildrenByTagName("Salt"))[0]->textContent;
if ($algo eq "" or $iter eq "" or $salt eq "") {
print STDERR "$0: Some (or all) NSEC3 options are not set\n";
exit 1
}
print " -3 $salt";
#print " $algo"; # no BIND equivalent
print " -H $iter";
#
# DNS KEY TTL
#
@nodes = $dom->getElementsByTagName("Keys");
my $keyttl = ($nodes[0]->getChildrenByTagName("TTL"))[0]->textContent;
if ($keyttl eq "") {
print STDERR "$0: No Key TTL found\n";
exit 1
} else {
$keyttl = timestamp2sec($keyttl);
print " -T $keyttl";
}
#
# Signature Jitter
#
@nodes = $dom->getElementsByTagName("Signatures");
my $jitter = ($nodes[0]->getChildrenByTagName("Jitter"))[0]->textContent;
if ($jitter eq "") {
print STDERR "$0: No Sig jitter found\n";
exit 1
} else {
$jitter = timestamp2sec($jitter);
print " -j $jitter";
}
#
# Offset -> start-time
#
my $starttime = ($nodes[0]->getChildrenByTagName("InceptionOffset"))[0]->textContent;
if ($starttime eq "") {
print STDERR "$0: No Sig offset found\n";
exit 1
} else {
$starttime = timestamp2sec($starttime);
print " -s -$starttime";
}
#
# Validity -> end-time
my @validity = $nodes[0]->getChildrenByTagName("Validity");
my $endtime = ($validity[0]->getChildrenByTagName("Default"))[0]->textContent;
if ($endtime eq "") {
print STDERR "$0: No Sig Validity found\n";
exit 1
} else {
$endtime = timestamp2sec($endtime);
print " -e +$endtime";
}
#
# SOA parameters
#
@nodes = $dom->getElementsByTagName("SOA");
my $serial = ($nodes[0]->getChildrenByTagName("Serial"))[0]->textContent;
if ($serial eq "") {
print STDERR "$0: No serial option found\n";
exit 1
} else {
if ($serial ne "keep") {
print STDERR "$0: serial option should ke \'keep\'\n";
exit 1
}
print " -N $serial";
}
# -S: smart signing, always
# -P: post verify disabled - we have other tools
# -n 10: 10 threads available on the signer
print " -S -P -n 10 ", $e, "$keydir", " $z ", $file, "\n";
#!/bin/bash
DEBUG=false
ZONE=nl
ZONEFILE=/var/lib/opendnssec/unsigned/nl
ENGINE=LunaCA3
KEYDIR="/tmp/keys-$(date +%s)"
XML=/var/lib/opendnssec/signconf/nl.xml
mkdir $KEYDIR
# extremely dumb PIN extractor
PIN=$(grep PIN /etc/opendnssec/conf.xml | sed 's/<PIN>'// | sed 's|</PIN>||' |
awk '{ print $1 }')
# Login to the SafeNet HSM
echo "Opening connection to the HSM"
if $DEBUG; then
echo /usr/local/sautil/bin/sautil -v -s 1 -i 10:11 -o -p "<PIN>"
else
/usr/local/sautil/bin/sautil -v -s 1 -i 10:11 -o -p "$PIN"
fi
keyconf.pl -x $XML $ENGINE $KEYDIR $ZONE | while read line; do
if $DEBUG; then
echo $line
else
echo $line
$line
fi
done
# should have the keys in the right directory now
if $DEBUG; then
signconf.pl -x $XML $ENGINE $KEYDIR $ZONE $ZONEFILE
else
signconf.pl -x $XML $ENGINE $KEYDIR $ZONE $ZONEFILE | while read line; do
echo $line
$line
done
fi
if [ -f $ZONEFILE.signed ]; then
echo "Copying zone file"
Z="$(basename $ZONEFILE)"
cp "$ZONEFILE".signed /var/lib/opendnssec/signed/"$Z".$$
mv /var/lib/opendnssec/signed/"$Z".$$ /var/lib/opendnssec/signed/"$Z"
rm $ZONEFILE.signed
fi
# remove DS set
if [ -f dsset-$ZONE. ]; then
rm dsset-$ZONE.
fi
# No matter what remove our garbage
if ! $DEBUG; then rm -rf $KEYDIR; fi
echo "Closing connection to the HSM"
if $DEBUG; then
echo /usr/local/sautil/bin/sautil -v -s 1 -i 10:11 -c
else
/usr/local/sautil/bin/sautil -v -s 1 -i 10:11 -c
fi
_______________________________________________
Opendnssec-user mailing list
[email protected]
https://lists.opendnssec.org/mailman/listinfo/opendnssec-user