mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-22 10:10:06 +00:00
Fix for RT #23136 task 1.
This commit is contained in:
parent
8513ad9a35
commit
a50ce0f80b
3
CHANGES
3
CHANGES
@ -1,3 +1,6 @@
|
|||||||
|
3114. [bug] Retain signed RRSET if key is inactive and there is
|
||||||
|
no replacement key. [RT #23136 task 1]
|
||||||
|
|
||||||
3113. [doc] Document the relationship between serial-query-rate
|
3113. [doc] Document the relationship between serial-query-rate
|
||||||
and NOTIFY messages.
|
and NOTIFY messages.
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: named.conf,v 1.46 2011/03/21 01:02:39 marka Exp $ */
|
/* $Id: named.conf,v 1.47 2011/05/19 00:31:57 smann Exp $ */
|
||||||
|
|
||||||
// NS3
|
// NS3
|
||||||
|
|
||||||
@ -223,4 +223,10 @@ zone "nsec3chain-test" {
|
|||||||
masters { 10.53.0.2; };
|
masters { 10.53.0.2; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
zone "expiring.example" {
|
||||||
|
type master;
|
||||||
|
allow-update { any; };
|
||||||
|
file "expiring.example.db.signed";
|
||||||
|
};
|
||||||
|
|
||||||
include "trusted.conf";
|
include "trusted.conf";
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
# PERFORMANCE OF THIS SOFTWARE.
|
# PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
# $Id: sign.sh,v 1.40 2011/03/31 15:58:51 each Exp $
|
# $Id: sign.sh,v 1.41 2011/05/19 00:31:57 smann Exp $
|
||||||
|
|
||||||
SYSTEMTESTTOP=../..
|
SYSTEMTESTTOP=../..
|
||||||
. $SYSTEMTESTTOP/conf.sh
|
. $SYSTEMTESTTOP/conf.sh
|
||||||
@ -370,3 +370,13 @@ echo '$INCLUDE "'"$signedfile"'"' >> $zonefile
|
|||||||
: > $signedfile
|
: > $signedfile
|
||||||
$SIGNER -P -S -r $RANDFILE -D -o $zone $zonefile > /dev/null 2>&1
|
$SIGNER -P -S -r $RANDFILE -D -o $zone $zonefile > /dev/null 2>&1
|
||||||
|
|
||||||
|
zone="expiring.example."
|
||||||
|
infile="expiring.example.db.in"
|
||||||
|
zonefile="expiring.example.db"
|
||||||
|
signedfile="expiring.example.db.signed"
|
||||||
|
kskname=`$KEYGEN -q -r $RANDFILE $zone`
|
||||||
|
zskname=`$KEYGEN -q -r $RANDFILE -f KSK $zone`
|
||||||
|
cp $infile $zonefile
|
||||||
|
$SIGNER -S -r $RANDFILE -e now+1mi -o $zone $zonefile > /dev/null 2>&1
|
||||||
|
rm -f ${zskname}.private ${kskname}.private
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
# PERFORMANCE OF THIS SOFTWARE.
|
# PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
# $Id: tests.sh,v 1.88 2011/03/24 02:10:23 marka Exp $
|
# $Id: tests.sh,v 1.89 2011/05/19 00:31:57 smann Exp $
|
||||||
|
|
||||||
SYSTEMTESTTOP=..
|
SYSTEMTESTTOP=..
|
||||||
. $SYSTEMTESTTOP/conf.sh
|
. $SYSTEMTESTTOP/conf.sh
|
||||||
@ -1315,7 +1315,7 @@ n=`expr $n + 1`
|
|||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
echo "I:check dnssec-dsfromkey from stdin($n)"
|
echo "I:check dnssec-dsfromkey from stdin ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
$DIG $DIGOPTS dnskey algroll. @10.53.0.2 | \
|
$DIG $DIGOPTS dnskey algroll. @10.53.0.2 | \
|
||||||
$DSFROMKEY -f - algroll. > dig.out.ns2.test$n || ret=1
|
$DSFROMKEY -f - algroll. > dig.out.ns2.test$n || ret=1
|
||||||
@ -1324,5 +1324,13 @@ n=`expr $n + 1`
|
|||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
echo "I:testing soon-to-expire RRSIGs without a replacement private key ($n)"
|
||||||
|
ret=0
|
||||||
|
$DIG +noall +answer +dnssec +nottl -p 5300 expiring.example ns @10.53.0.3 | grep RRSIG > dig.out.ns3.test$n 2>&1
|
||||||
|
# there must be a signature here
|
||||||
|
[ -s dig.out.ns3.test$n ] || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
echo "I:exit status: $status"
|
echo "I:exit status: $status"
|
||||||
exit $status
|
exit $status
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: db.h,v 1.104 2011/01/13 04:59:25 tbox Exp $ */
|
/* $Id: db.h,v 1.105 2011/05/19 00:31:57 smann Exp $ */
|
||||||
|
|
||||||
#ifndef DNS_DB_H
|
#ifndef DNS_DB_H
|
||||||
#define DNS_DB_H 1
|
#define DNS_DB_H 1
|
||||||
@ -1441,7 +1441,9 @@ dns_db_setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
|
|||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
* \li 'db' is a valid zone database.
|
* \li 'db' is a valid zone database.
|
||||||
* \li 'rdataset' to be associated with 'db'.
|
* \li 'rdataset' is or is to be associated with 'db'.
|
||||||
|
* \li 'rdataset' is not pending removed from the heap via an
|
||||||
|
* uncommitted call to dns_db_resigned().
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* \li #ISC_R_SUCCESS
|
* \li #ISC_R_SUCCESS
|
||||||
@ -1472,7 +1474,9 @@ dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset,
|
|||||||
* Mark 'rdataset' as not being available to be returned by
|
* Mark 'rdataset' as not being available to be returned by
|
||||||
* dns_db_getsigningtime(). If the changes associated with 'version'
|
* dns_db_getsigningtime(). If the changes associated with 'version'
|
||||||
* are committed this will be permanent. If the version is not committed
|
* are committed this will be permanent. If the version is not committed
|
||||||
* this change will be rolled back when the version is closed.
|
* this change will be rolled back when the version is closed. Until
|
||||||
|
* 'version' is either committed or rolled back, 'rdataset' can no longer
|
||||||
|
* be acted upon by dns_db_setsigningtime().
|
||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
* \li 'db' is a valid zone database.
|
* \li 'db' is a valid zone database.
|
||||||
|
124
lib/dns/zone.c
124
lib/dns/zone.c
@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: zone.c,v 1.604 2011/05/06 21:23:51 each Exp $ */
|
/* $Id: zone.c,v 1.605 2011/05/19 00:31:57 smann Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@ -109,12 +109,20 @@
|
|||||||
|
|
||||||
#define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
|
#define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* Key flags
|
||||||
|
*/
|
||||||
|
#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
|
||||||
|
#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
|
||||||
|
#define ALG(x) dst_key_alg(x)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default values.
|
* Default values.
|
||||||
*/
|
*/
|
||||||
#define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
|
#define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
|
||||||
#define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
|
#define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
|
||||||
#define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
|
#define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
|
||||||
|
#define RESIGN_DELAY 3600 /*%< 1 hour */
|
||||||
|
|
||||||
#ifndef DNS_MAX_EXPIRE
|
#ifndef DNS_MAX_EXPIRE
|
||||||
#define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
|
#define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
|
||||||
@ -214,6 +222,7 @@ struct dns_zone {
|
|||||||
isc_uint32_t expire;
|
isc_uint32_t expire;
|
||||||
isc_uint32_t minimum;
|
isc_uint32_t minimum;
|
||||||
isc_stdtime_t key_expiry;
|
isc_stdtime_t key_expiry;
|
||||||
|
isc_stdtime_t log_key_expired_timer;
|
||||||
char *keydirectory;
|
char *keydirectory;
|
||||||
|
|
||||||
isc_uint32_t maxrefresh;
|
isc_uint32_t maxrefresh;
|
||||||
@ -663,6 +672,8 @@ static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
|
|||||||
dns_dbnode_t *node, dns_name_t *name,
|
dns_dbnode_t *node, dns_name_t *name,
|
||||||
dns_diff_t *diff);
|
dns_diff_t *diff);
|
||||||
static void zone_rekey(dns_zone_t *zone);
|
static void zone_rekey(dns_zone_t *zone);
|
||||||
|
static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr,
|
||||||
|
dst_key_t **keys, unsigned int nkeys);
|
||||||
|
|
||||||
#define ENTER zone_debuglog(zone, me, 1, "enter")
|
#define ENTER zone_debuglog(zone, me, 1, "enter")
|
||||||
|
|
||||||
@ -810,6 +821,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
|||||||
zone->timer = NULL;
|
zone->timer = NULL;
|
||||||
zone->idlein = DNS_DEFAULT_IDLEIN;
|
zone->idlein = DNS_DEFAULT_IDLEIN;
|
||||||
zone->idleout = DNS_DEFAULT_IDLEOUT;
|
zone->idleout = DNS_DEFAULT_IDLEOUT;
|
||||||
|
zone->log_key_expired_timer = 0;
|
||||||
ISC_LIST_INIT(zone->notifies);
|
ISC_LIST_INIT(zone->notifies);
|
||||||
isc_sockaddr_any(&zone->notifysrc4);
|
isc_sockaddr_any(&zone->notifysrc4);
|
||||||
isc_sockaddr_any6(&zone->notifysrc6);
|
isc_sockaddr_any6(&zone->notifysrc6);
|
||||||
@ -3611,6 +3623,39 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||||||
resume_signingwithkey(zone);
|
resume_signingwithkey(zone);
|
||||||
resume_addnsec3chain(zone);
|
resume_addnsec3chain(zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zone->type == dns_zone_master &&
|
||||||
|
dns_zone_isdynamic(zone, ISC_TRUE) &&
|
||||||
|
dns_db_issecure(db)) {
|
||||||
|
dns_name_t *name;
|
||||||
|
dns_fixedname_t fixed;
|
||||||
|
dns_rdataset_t next;
|
||||||
|
|
||||||
|
dns_rdataset_init(&next);
|
||||||
|
dns_fixedname_init(&fixed);
|
||||||
|
name = dns_fixedname_name(&fixed);
|
||||||
|
|
||||||
|
result = dns_db_getsigningtime(db, &next, name);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
isc_stdtime_t timenow;
|
||||||
|
char namebuf[DNS_NAME_FORMATSIZE];
|
||||||
|
char typebuf[DNS_RDATATYPE_FORMATSIZE];
|
||||||
|
|
||||||
|
isc_stdtime_get(&timenow);
|
||||||
|
dns_name_format(name, namebuf, sizeof(namebuf));
|
||||||
|
dns_rdatatype_format(next.covers,
|
||||||
|
typebuf, sizeof(typebuf));
|
||||||
|
dns_zone_log(zone, ISC_LOG_DEBUG(3),
|
||||||
|
"next resign: %s/%s in %d seconds",
|
||||||
|
namebuf, typebuf,
|
||||||
|
next.resign - timenow);
|
||||||
|
dns_rdataset_disassociate(&next);
|
||||||
|
} else
|
||||||
|
dns_zone_log(zone, ISC_LOG_WARNING,
|
||||||
|
"signed dynamic zone has no "
|
||||||
|
"resign event scheduled");
|
||||||
|
}
|
||||||
|
|
||||||
zone_settimer(zone, &now);
|
zone_settimer(zone, &now);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4604,6 +4649,31 @@ set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function to del_sigs(). We don't want to delete RRSIGs that
|
||||||
|
* have no new key.
|
||||||
|
*/
|
||||||
|
static isc_boolean_t
|
||||||
|
delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) {
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < nkeys; i++) {
|
||||||
|
if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
|
||||||
|
(rrsig_ptr->keyid != dst_key_id(keys[i]))) {
|
||||||
|
if ((dst_key_isprivate(keys[i])) && !KSK(keys[i])) {
|
||||||
|
/*
|
||||||
|
* Success - found a private key, which
|
||||||
|
* means it is an active key and thus, it
|
||||||
|
* is OK to delete the RRSIG
|
||||||
|
*/
|
||||||
|
return (ISC_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ISC_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete expired RRsigs and any RRsigs we are about to re-sign.
|
* Delete expired RRsigs and any RRsigs we are about to re-sign.
|
||||||
* See also update.c:del_keysigs().
|
* See also update.c:del_keysigs().
|
||||||
@ -4653,13 +4723,49 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
|||||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
|
|
||||||
if (type != dns_rdatatype_dnskey) {
|
if (type != dns_rdatatype_dnskey) {
|
||||||
result = update_one_rr(db, ver, diff,
|
if(delsig_ok(&rrsig, keys, nkeys)) {
|
||||||
|
result = update_one_rr(db, ver, diff,
|
||||||
DNS_DIFFOP_DELRESIGN, name,
|
DNS_DIFFOP_DELRESIGN, name,
|
||||||
rdataset.ttl, &rdata);
|
rdataset.ttl, &rdata);
|
||||||
dns_rdata_reset(&rdata);
|
dns_db_resigned(db, &rdataset, ver);
|
||||||
if (result != ISC_R_SUCCESS)
|
dns_rdata_reset(&rdata);
|
||||||
break;
|
if (result != ISC_R_SUCCESS)
|
||||||
continue;
|
break;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* At this point, we've got an RRSIG,
|
||||||
|
* which is signed by an inactive key.
|
||||||
|
* An administrator needs to provide a new
|
||||||
|
* key/alg, but until that time, we want to
|
||||||
|
* keep the old RRSIG. Resetting the timer
|
||||||
|
* here will ensure that we don't
|
||||||
|
* constantly recheck this expired record.
|
||||||
|
*
|
||||||
|
* Note: dns_db_setsigningtime() will
|
||||||
|
* assert if called after dns_db_resigned().
|
||||||
|
*/
|
||||||
|
isc_stdtime_t recheck = now + RESIGN_DELAY;
|
||||||
|
dns_db_setsigningtime(db, &rdataset, recheck);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* log the key id and algorithm of
|
||||||
|
* the inactive key with no replacement
|
||||||
|
*/
|
||||||
|
if((isc_log_getdebuglevel(dns_lctx) > 3) ||
|
||||||
|
(zone->log_key_expired_timer <= now)) {
|
||||||
|
dns_zone_log(zone, ISC_LOG_WARNING,
|
||||||
|
"del_sigs(): "
|
||||||
|
"keyid: %u/algorithm: %u "
|
||||||
|
"is not active and there "
|
||||||
|
"is no replacement. "
|
||||||
|
"Not deleting.",
|
||||||
|
rrsig.keyid,
|
||||||
|
rrsig.algorithm);
|
||||||
|
zone->log_key_expired_timer = now +
|
||||||
|
3600;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4763,10 +4869,6 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
|
|
||||||
#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
|
|
||||||
#define ALG(x) dst_key_alg(x)
|
|
||||||
|
|
||||||
for (i = 0; i < nkeys; i++) {
|
for (i = 0; i < nkeys; i++) {
|
||||||
isc_boolean_t both = ISC_FALSE;
|
isc_boolean_t both = ISC_FALSE;
|
||||||
|
|
||||||
@ -4922,7 +5024,6 @@ zone_resigninc(dns_zone_t *zone) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_db_resigned(db, &rdataset, version);
|
|
||||||
dns_rdataset_disassociate(&rdataset);
|
dns_rdataset_disassociate(&rdataset);
|
||||||
|
|
||||||
result = del_sigs(zone, db, version, name, covers, &sig_diff,
|
result = del_sigs(zone, db, version, name, covers, &sig_diff,
|
||||||
@ -4933,6 +5034,7 @@ zone_resigninc(dns_zone_t *zone) {
|
|||||||
dns_result_totext(result));
|
dns_result_totext(result));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = add_sigs(db, version, name, covers, &sig_diff,
|
result = add_sigs(db, version, name, covers, &sig_diff,
|
||||||
zone_keys, nkeys, zone->mctx, inception,
|
zone_keys, nkeys, zone->mctx, inception,
|
||||||
expire, check_ksk, keyset_kskonly);
|
expire, check_ksk, keyset_kskonly);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user