mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
2691. [func] dnssec-signzone: retain the existing NSEC or NSEC3
chain when re-signing a previously-signed zone. Use -u to modify NSEC3 parameters or switch between NSEC and NSEC3. [RT #20304]
This commit is contained in:
5
CHANGES
5
CHANGES
@@ -1,3 +1,8 @@
|
||||
2691. [func] dnssec-signzone: retain the existing NSEC or NSEC3
|
||||
chain when re-signing a previously-signed zone.
|
||||
Use -u to modify NSEC3 parameters or switch
|
||||
between NSEC and NSEC3. [RT #20304]
|
||||
|
||||
2690. [bug] win32: fix isc_thread_key_getspecific() prototype.
|
||||
[RT #20315]
|
||||
|
||||
|
@@ -29,7 +29,7 @@
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: dnssec-signzone.c,v 1.234 2009/09/24 04:36:28 each Exp $ */
|
||||
/* $Id: dnssec-signzone.c,v 1.235 2009/09/25 06:47:50 each Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -147,6 +147,10 @@ static dns_dbiterator_t *gdbiter; /* The database iterator */
|
||||
static dns_rdataclass_t gclass; /* The class */
|
||||
static dns_name_t *gorigin; /* The database origin */
|
||||
static int nsec3flags = 0;
|
||||
static dns_iterations_t nsec3iter = 100U;
|
||||
static unsigned char saltbuf[255];
|
||||
static unsigned char *salt = saltbuf;
|
||||
static size_t salt_length = 0;
|
||||
static isc_task_t *master = NULL;
|
||||
static unsigned int ntasks = 0;
|
||||
static isc_boolean_t shuttingdown = ISC_FALSE, finished = ISC_FALSE;
|
||||
@@ -161,6 +165,7 @@ static unsigned int serialformat = SOA_SERIAL_KEEP;
|
||||
static unsigned int hash_length = 0;
|
||||
static isc_boolean_t unknownalg = ISC_FALSE;
|
||||
static isc_boolean_t disable_zone_check = ISC_FALSE;
|
||||
static isc_boolean_t update_chain = ISC_FALSE;
|
||||
static isc_boolean_t set_keyttl = ISC_FALSE;
|
||||
static dns_ttl_t keyttl;
|
||||
static isc_boolean_t smartsign = ISC_FALSE;
|
||||
@@ -2001,8 +2006,8 @@ nsecify(void) {
|
||||
type = rdataset.type;
|
||||
covers = rdataset.covers;
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
result = dns_db_deleterdataset(gdb, node, gversion, type,
|
||||
covers);
|
||||
result = dns_db_deleterdataset(gdb, node, gversion,
|
||||
type, covers);
|
||||
check_result(result,
|
||||
"dns_db_deleterdataset(nsec3param/rrsig)");
|
||||
}
|
||||
@@ -2019,6 +2024,7 @@ nsecify(void) {
|
||||
|
||||
result = dns_dbiterator_current(dbiter, &node, name);
|
||||
check_dns_dbiterator_current(result);
|
||||
|
||||
/*
|
||||
* Delete any NSEC3PARAM records at the apex.
|
||||
*/
|
||||
@@ -2354,6 +2360,7 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
|
||||
|
||||
result = dns_dbiterator_current(dbiter, &node, name);
|
||||
check_dns_dbiterator_current(result);
|
||||
|
||||
/*
|
||||
* Delete any NSEC records at the apex.
|
||||
*/
|
||||
@@ -2366,7 +2373,12 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
|
||||
type = rdataset.type;
|
||||
covers = rdataset.covers;
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
if (type == dns_rdatatype_nsec || covers == dns_rdatatype_nsec) {
|
||||
if (type == dns_rdatatype_nsec ||
|
||||
covers == dns_rdatatype_nsec) {
|
||||
if (!update_chain)
|
||||
fatal("Zone contains NSEC records. Use -u "
|
||||
"to update to NSEC3.");
|
||||
|
||||
result = dns_db_deleterdataset(gdb, node, gversion,
|
||||
type, covers);
|
||||
check_result(result,
|
||||
@@ -3012,6 +3024,100 @@ warnifallksk(dns_db_t *db) {
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_nsec3params(isc_boolean_t update_chain, isc_boolean_t set_salt,
|
||||
isc_boolean_t set_optout, isc_boolean_t set_iter)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_dbversion_t *ver = NULL;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_rdataset_t rdataset;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_nsec3_t nsec3;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *hashname;
|
||||
unsigned char orig_salt[256];
|
||||
size_t orig_saltlen;
|
||||
dns_hash_t orig_hash;
|
||||
isc_uint16_t orig_iter;
|
||||
|
||||
dns_db_currentversion(gdb, &ver);
|
||||
|
||||
orig_saltlen = sizeof(orig_salt);
|
||||
result = dns_db_getnsec3parameters(gdb, ver, &orig_hash, NULL,
|
||||
&orig_iter, orig_salt,
|
||||
&orig_saltlen);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
nsec_datatype = dns_rdatatype_nsec3;
|
||||
|
||||
if (!update_chain && set_salt) {
|
||||
if (salt_length != orig_saltlen ||
|
||||
memcmp(saltbuf, orig_salt, salt_length) != 0)
|
||||
fatal("An NSEC3 chain exists with a different salt. "
|
||||
"Use -u to update it.");
|
||||
} else if (!set_salt) {
|
||||
salt_length = orig_saltlen;
|
||||
memcpy(saltbuf, orig_salt, orig_saltlen);
|
||||
salt = saltbuf;
|
||||
}
|
||||
|
||||
if (!update_chain && set_iter) {
|
||||
if (nsec3iter != orig_iter)
|
||||
fatal("An NSEC3 chain exists with different "
|
||||
"iterations. Use -u to update it.");
|
||||
} else if (!set_iter)
|
||||
nsec3iter = orig_iter;
|
||||
|
||||
/*
|
||||
* Find an NSEC3 record to get the current OPTOUT value.
|
||||
* (This assumes all NSEC3 records agree.)
|
||||
*/
|
||||
|
||||
dns_fixedname_init(&fname);
|
||||
hashname = dns_fixedname_name(&fname);
|
||||
result = dns_nsec3_hashname(&fname, NULL, NULL,
|
||||
gorigin, gorigin, dns_hash_sha1,
|
||||
orig_iter, orig_salt, orig_saltlen);
|
||||
check_result(result, "dns_nsec3_hashname");
|
||||
|
||||
result = dns_db_findnsec3node(gdb, hashname, ISC_FALSE, &node);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
result = dns_db_findrdataset(gdb, node, ver, dns_rdatatype_nsec3,
|
||||
0, 0, &rdataset, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
result = dns_rdataset_first(&rdataset);
|
||||
check_result(result, "dns_rdataset_first");
|
||||
dns_rdataset_current(&rdataset, &rdata);
|
||||
result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
|
||||
check_result(result, "dns_rdata_tostruct");
|
||||
|
||||
if (!update_chain && set_optout) {
|
||||
if (nsec3flags != nsec3.flags)
|
||||
fatal("An NSEC3 chain exists with%s OPTOUT. "
|
||||
"Use -u -%s to %s it.",
|
||||
OPTOUT(nsec3.flags) ? "" : "out",
|
||||
OPTOUT(nsec3.flags) ? "AA" : "A",
|
||||
OPTOUT(nsec3.flags) ? "clear" : "set");
|
||||
} else if (!set_optout)
|
||||
nsec3flags = nsec3.flags;
|
||||
|
||||
dns_rdata_freestruct(&nsec3);
|
||||
|
||||
cleanup:
|
||||
if (dns_rdataset_isassociated(&rdataset))
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
if (node != NULL)
|
||||
dns_db_detachnode(gdb, &node);
|
||||
dns_db_closeversion(gdb, &ver, ISC_FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
writeset(const char *prefix, dns_rdatatype_t type) {
|
||||
char *filename;
|
||||
@@ -3177,9 +3283,9 @@ usage(void) {
|
||||
fprintf(stderr, "Version: %s\n", VERSION);
|
||||
|
||||
fprintf(stderr, "Options: (default value in parenthesis) \n");
|
||||
fprintf(stderr, "\t-S:\tsmart signing: automatically finds key\n"
|
||||
"\t\tfiles for the zone and determines they are to\n"
|
||||
"\t\tbe used\n");
|
||||
fprintf(stderr, "\t-S:\tsmart signing: automatically finds key files\n"
|
||||
"\t\tfor the zone and determines how they are to "
|
||||
"be used\n");
|
||||
fprintf(stderr, "\t-K directory:\n");
|
||||
fprintf(stderr, "\t\tdirectory to find key files (.)\n");
|
||||
fprintf(stderr, "\t-d directory:\n");
|
||||
@@ -3221,6 +3327,8 @@ usage(void) {
|
||||
fprintf(stderr, "\t-T TTL:\tTTL for newly added DNSKEYs");
|
||||
fprintf(stderr, "\t-t:\t");
|
||||
fprintf(stderr, "print statistics\n");
|
||||
fprintf(stderr, "\t-u:\t");
|
||||
fprintf(stderr, "update or replace an existing NSEC/NSEC3 chain\n");
|
||||
fprintf(stderr, "\t-C:\tgenerate a keyset file, for compatibility\n"
|
||||
"\t\twith older versions of dnssec-signzone -g\n");
|
||||
fprintf(stderr, "\t-n ncpus (number of cpus present)\n");
|
||||
@@ -3293,14 +3401,14 @@ main(int argc, char *argv[]) {
|
||||
isc_task_t **tasks = NULL;
|
||||
isc_buffer_t b;
|
||||
int len;
|
||||
unsigned int iterations = 100U;
|
||||
const unsigned char *salt = NULL;
|
||||
size_t salt_length = 0;
|
||||
unsigned char saltbuf[255];
|
||||
hashlist_t hashlist;
|
||||
isc_boolean_t make_keyset = ISC_FALSE;
|
||||
|
||||
#define CMDLINE_FLAGS "3:AaCc:Dd:e:f:FghH:i:I:j:K:k:l:m:n:N:o:O:pPr:s:ST:tUv:z"
|
||||
isc_boolean_t set_salt = ISC_FALSE;
|
||||
isc_boolean_t set_optout = ISC_FALSE;
|
||||
isc_boolean_t set_iter = ISC_FALSE;
|
||||
|
||||
#define CMDLINE_FLAGS \
|
||||
"3:AaCc:Dd:e:f:FghH:i:I:j:K:k:l:m:n:N:o:O:pPr:s:ST:tuUv:z"
|
||||
|
||||
/*
|
||||
* Process memory debugging argument first.
|
||||
@@ -3340,7 +3448,9 @@ main(int argc, char *argv[]) {
|
||||
while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
|
||||
switch (ch) {
|
||||
case '3':
|
||||
if (strcmp(isc_commandline_argument, "-")) {
|
||||
set_salt = ISC_TRUE;
|
||||
nsec_datatype = dns_rdatatype_nsec3;
|
||||
if (strcmp(isc_commandline_argument, "-") != 0) {
|
||||
isc_buffer_t target;
|
||||
char *sarg;
|
||||
|
||||
@@ -3350,17 +3460,16 @@ main(int argc, char *argv[]) {
|
||||
result = isc_hex_decodestring(sarg, &target);
|
||||
check_result(result,
|
||||
"isc_hex_decodestring(salt)");
|
||||
salt = saltbuf;
|
||||
salt_length = isc_buffer_usedlength(&target);
|
||||
} else {
|
||||
salt = saltbuf;
|
||||
salt_length = 0;
|
||||
}
|
||||
nsec_datatype = dns_rdatatype_nsec3;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
nsec3flags |= DNS_NSEC3FLAG_OPTOUT;
|
||||
set_optout = ISC_TRUE;
|
||||
if (OPTOUT(nsec3flags))
|
||||
nsec3flags &= ~DNS_NSEC3FLAG_OPTOUT;
|
||||
else
|
||||
nsec3flags |= DNS_NSEC3FLAG_OPTOUT;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
@@ -3398,11 +3507,11 @@ main(int argc, char *argv[]) {
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
iterations = strtoul(isc_commandline_argument,
|
||||
&endp, 0);
|
||||
set_iter = ISC_TRUE;
|
||||
nsec3iter = strtoul(isc_commandline_argument, &endp, 0);
|
||||
if (*endp != '\0')
|
||||
fatal("iterations must be numeric");
|
||||
if (iterations > 0xffffU)
|
||||
if (nsec3iter > 0xffffU)
|
||||
fatal("iterations too big");
|
||||
break;
|
||||
|
||||
@@ -3504,6 +3613,10 @@ main(int argc, char *argv[]) {
|
||||
unknownalg = ISC_TRUE;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
update_chain = ISC_TRUE;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
endp = NULL;
|
||||
verbose = strtol(isc_commandline_argument, &endp, 0);
|
||||
@@ -3622,7 +3735,8 @@ main(int argc, char *argv[]) {
|
||||
else if (strcasecmp(serialformatstr, "unixtime") == 0)
|
||||
serialformat = SOA_SERIAL_UNIXTIME;
|
||||
else
|
||||
fatal("unknown soa serial format: %s\n", serialformatstr);
|
||||
fatal("unknown soa serial format: %s\n",
|
||||
serialformatstr);
|
||||
}
|
||||
|
||||
result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL,
|
||||
@@ -3639,6 +3753,15 @@ main(int argc, char *argv[]) {
|
||||
if (!set_keyttl)
|
||||
keyttl = soa_ttl;
|
||||
|
||||
/*
|
||||
* Check for any existing NSEC3 parameters in the zone,
|
||||
* and use them as defaults if -u was not specified.
|
||||
*/
|
||||
if (update_chain && !set_optout && !set_iter && !set_salt)
|
||||
nsec_datatype = dns_rdatatype_nsec;
|
||||
else
|
||||
set_nsec3params(update_chain, set_salt, set_optout, set_iter);
|
||||
|
||||
if (IS_NSEC3) {
|
||||
isc_boolean_t answer;
|
||||
hash_length = dns_nsec3_hashlength(dns_hash_sha1);
|
||||
@@ -3769,7 +3892,7 @@ main(int argc, char *argv[]) {
|
||||
unsigned int max;
|
||||
result = dns_nsec3_maxiterations(gdb, NULL, mctx, &max);
|
||||
check_result(result, "dns_nsec3_maxiterations()");
|
||||
if (iterations > max)
|
||||
if (nsec3iter > max)
|
||||
fatal("NSEC3 iterations too big for weakest DNSKEY "
|
||||
"strength. Maximum iterations allowed %u.", max);
|
||||
}
|
||||
@@ -3794,7 +3917,7 @@ main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
if (IS_NSEC3)
|
||||
nsec3ify(dns_hash_sha1, iterations, salt, salt_length,
|
||||
nsec3ify(dns_hash_sha1, nsec3iter, salt, salt_length,
|
||||
&hashlist);
|
||||
else
|
||||
nsecify();
|
||||
|
@@ -18,7 +18,7 @@
|
||||
- PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
|
||||
<!-- $Id: dnssec-signzone.docbook,v 1.36 2009/09/02 06:29:00 each Exp $ -->
|
||||
<!-- $Id: dnssec-signzone.docbook,v 1.37 2009/09/25 06:47:50 each Exp $ -->
|
||||
<refentry id="man.dnssec-signzone">
|
||||
<refentryinfo>
|
||||
<date>June 05, 2009</date>
|
||||
@@ -80,6 +80,7 @@
|
||||
<arg><option>-s <replaceable class="parameter">start-time</replaceable></option></arg>
|
||||
<arg><option>-T <replaceable class="parameter">ttl</replaceable></option></arg>
|
||||
<arg><option>-t</option></arg>
|
||||
<arg><option>-u</option></arg>
|
||||
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg>
|
||||
<arg><option>-z</option></arg>
|
||||
<arg><option>-3 <replaceable class="parameter">salt</replaceable></option></arg>
|
||||
@@ -515,6 +516,20 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-u</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Update NSEC/NSEC3 chain when re-signing a previously signed
|
||||
zone. With this option, a zone signed with NSEC can be
|
||||
switched to NSEC3, or a zone signed with NSEC3 can
|
||||
be switch to NSEC or to NSEC3 with different parameters.
|
||||
Without this option, <command>dnssec-signzone</command> will
|
||||
retain the existing chain when re-signing.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-v <replaceable class="parameter">level</replaceable></term>
|
||||
<listitem>
|
||||
@@ -562,6 +577,12 @@
|
||||
NSEC3 records and do not generate NSEC3 records for insecure
|
||||
delegations.
|
||||
</para>
|
||||
<para>
|
||||
Using this option twice (i.e., <option>-AA</option>)
|
||||
turns the OPTOUT flag off for all records. This is useful
|
||||
when using the <option>-u</option> option to modify an NSEC3
|
||||
chain which previously had OPTOUT set.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: sign.sh,v 1.27 2009/06/04 02:56:47 tbox Exp $
|
||||
# $Id: sign.sh,v 1.28 2009/09/25 06:47:50 each Exp $
|
||||
|
||||
SYSTEMTESTTOP=../..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
@@ -213,12 +213,12 @@ cat $infile $keyname.key >$zonefile
|
||||
|
||||
$SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null
|
||||
mv $zonefile.signed $zonefile
|
||||
$SIGNER -P -3 - -r $RANDFILE -o $zone $zonefile > /dev/null
|
||||
$SIGNER -P -u3 - -r $RANDFILE -o $zone $zonefile > /dev/null
|
||||
mv $zonefile.signed $zonefile
|
||||
$SIGNER -P -3 AAAA -r $RANDFILE -o $zone $zonefile > /dev/null
|
||||
$SIGNER -P -u3 AAAA -r $RANDFILE -o $zone $zonefile > /dev/null
|
||||
mv $zonefile.signed $zonefile
|
||||
$SIGNER -P -3 BBBB -r $RANDFILE -o $zone $zonefile > /dev/null
|
||||
$SIGNER -P -u3 BBBB -r $RANDFILE -o $zone $zonefile > /dev/null
|
||||
mv $zonefile.signed $zonefile
|
||||
$SIGNER -P -3 CCCC -r $RANDFILE -o $zone $zonefile > /dev/null
|
||||
$SIGNER -P -u3 CCCC -r $RANDFILE -o $zone $zonefile > /dev/null
|
||||
mv $zonefile.signed $zonefile
|
||||
$SIGNER -P -3 DDDD -r $RANDFILE -o $zone $zonefile > /dev/null
|
||||
$SIGNER -P -u3 DDDD -r $RANDFILE -o $zone $zonefile > /dev/null
|
||||
|
Reference in New Issue
Block a user