mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-28 21:17:54 +00:00
Merge branch '2645-dnssec-polic-insecure' into 'main'
Add built-in dnssec-policy "insecure" Closes #2645 See merge request isc-projects/bind9!4929
This commit is contained in:
commit
968b9b5697
4
CHANGES
4
CHANGES
@ -1,3 +1,7 @@
|
||||
5632. [func] Add built-in dnssec-policy "insecure". This is used to
|
||||
transition a zone from a signed state to a unsigned
|
||||
state. [GL #2645]
|
||||
|
||||
5631. [bug] Update ZONEMD to match RFC 8976. [GL #2658]
|
||||
|
||||
5630. [func] Treat DNSSEC responses with NSEC3 iterations greater
|
||||
|
@ -9174,7 +9174,7 @@ load_configuration(const char *filename, named_server_t *server,
|
||||
dns_kasp_detach(&kasp);
|
||||
}
|
||||
/*
|
||||
* Create the built-in kasp policies ("default", "none").
|
||||
* Create the built-in kasp policies ("default", "insecure").
|
||||
*/
|
||||
kasp = NULL;
|
||||
CHECK(cfg_kasp_fromconfig(NULL, "default", named_g_mctx, named_g_lctx,
|
||||
@ -9184,7 +9184,7 @@ load_configuration(const char *filename, named_server_t *server,
|
||||
dns_kasp_detach(&kasp);
|
||||
|
||||
kasp = NULL;
|
||||
CHECK(cfg_kasp_fromconfig(NULL, "none", named_g_mctx, named_g_lctx,
|
||||
CHECK(cfg_kasp_fromconfig(NULL, "insecure", named_g_mctx, named_g_lctx,
|
||||
&kasplist, &kasp));
|
||||
INSIST(kasp != NULL);
|
||||
dns_kasp_freeze(kasp);
|
||||
@ -14827,7 +14827,7 @@ named_server_signing(named_server_t *server, isc_lex_t *lex,
|
||||
CHECK(ISC_R_UNEXPECTEDEND);
|
||||
}
|
||||
|
||||
if (dns_zone_use_kasp(zone)) {
|
||||
if (dns_zone_getkasp(zone) != NULL) {
|
||||
(void)putstr(text, "zone uses dnssec-policy, use rndc dnssec "
|
||||
"command instead");
|
||||
(void)putnull(text);
|
||||
|
@ -1249,15 +1249,23 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
result = named_config_get(maps, "dnssec-policy", &obj);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
kaspname = cfg_obj_asstring(obj);
|
||||
result = dns_kasplist_find(kasplist, kaspname, &kasp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(obj, named_g_lctx, ISC_LOG_ERROR,
|
||||
"'dnssec-policy '%s' not found ",
|
||||
kaspname);
|
||||
RETERR(result);
|
||||
if (strcmp(kaspname, "none") != 0) {
|
||||
result = dns_kasplist_find(kasplist, kaspname,
|
||||
&kasp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(
|
||||
obj, named_g_lctx,
|
||||
ISC_LOG_ERROR,
|
||||
"dnssec-policy '%s' not found ",
|
||||
kaspname);
|
||||
RETERR(result);
|
||||
}
|
||||
dns_zone_setkasp(zone, kasp);
|
||||
use_kasp = true;
|
||||
}
|
||||
dns_zone_setkasp(zone, kasp);
|
||||
use_kasp = dns_zone_use_kasp(zone);
|
||||
}
|
||||
if (!use_kasp) {
|
||||
dns_zone_setkasp(zone, NULL);
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
@ -1671,10 +1679,11 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
|
||||
obj = NULL;
|
||||
result = cfg_map_get(zoptions, "auto-dnssec", &obj);
|
||||
if (kasp != NULL && strcmp(dns_kasp_getname(kasp), "none") != 0)
|
||||
{
|
||||
if (kasp != NULL) {
|
||||
bool s2i = (strcmp(dns_kasp_getname(kasp),
|
||||
"insecure") != 0);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, true);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_CREATE, true);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_CREATE, !s2i);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, true);
|
||||
} else if (result == ISC_R_SUCCESS) {
|
||||
const char *arg = cfg_obj_asstring(obj);
|
||||
@ -1691,11 +1700,6 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_CREATE, false);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint);
|
||||
} else {
|
||||
bool s2i = dns_zone_secure_to_insecure(zone, false);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, s2i);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_CREATE, false);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, s2i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2216,13 +2220,6 @@ named_zone_inlinesigning(dns_zone_t *zone, const cfg_obj_t *zconfig,
|
||||
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
||||
"inline-signing: "
|
||||
"implicitly through dnssec-policy");
|
||||
} else {
|
||||
inline_signing = dns_zone_secure_to_insecure(zone,
|
||||
true);
|
||||
dns_zone_log(
|
||||
zone, ISC_LOG_DEBUG(1), "inline-signing: %s",
|
||||
inline_signing ? "transitioning to insecure"
|
||||
: "no");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,8 +196,8 @@ set_policy() {
|
||||
CDS_DELETE="no"
|
||||
}
|
||||
# By default policies are considered to be secure.
|
||||
# If a zone sets its policy to "none", call 'set_cdsdelete' to tell the system
|
||||
# test to expect a CDS and CDNSKEY Delete record.
|
||||
# If a zone sets its policy to "insecure", call 'set_cdsdelete' to tell the
|
||||
# system test to expect a CDS and CDNSKEY Delete record.
|
||||
set_cdsdelete() {
|
||||
CDS_DELETE="yes"
|
||||
}
|
||||
@ -779,18 +779,22 @@ check_dnssecstatus() {
|
||||
|
||||
_rndccmd $_server dnssec -status $_zone in $_view > rndc.dnssec.status.out.$_zone.$n || _log_error "rndc dnssec -status zone ${_zone} failed"
|
||||
|
||||
grep "dnssec-policy: ${_policy}" rndc.dnssec.status.out.$_zone.$n > /dev/null || _log_error "bad dnssec status for signed zone ${_zone}"
|
||||
if [ "$(key_get KEY1 EXPECT)" = "yes" ]; then
|
||||
grep "key: $(key_get KEY1 ID)" rndc.dnssec.status.out.$_zone.$n > /dev/null || _log_error "missing key $(key_get KEY1 ID) from dnssec status"
|
||||
fi
|
||||
if [ "$(key_get KEY2 EXPECT)" = "yes" ]; then
|
||||
grep "key: $(key_get KEY2 ID)" rndc.dnssec.status.out.$_zone.$n > /dev/null || _log_error "missing key $(key_get KEY2 ID) from dnssec status"
|
||||
fi
|
||||
if [ "$(key_get KEY3 EXPECT)" = "yes" ]; then
|
||||
grep "key: $(key_get KEY3 ID)" rndc.dnssec.status.out.$_zone.$n > /dev/null || _log_error "missing key $(key_get KEY3 ID) from dnssec status"
|
||||
fi
|
||||
if [ "$(key_get KEY4 EXPECT)" = "yes" ]; then
|
||||
grep "key: $(key_get KEY4 ID)" rndc.dnssec.status.out.$_zone.$n > /dev/null || _log_error "missing key $(key_get KEY4 ID) from dnssec status"
|
||||
if [ "$_policy" = "none" ]; then
|
||||
grep "Zone does not have dnssec-policy" rndc.dnssec.status.out.$_zone.$n > /dev/null || log_error "bad dnssec status for unsigned zone ${_zone}"
|
||||
else
|
||||
grep "dnssec-policy: ${_policy}" rndc.dnssec.status.out.$_zone.$n > /dev/null || _log_error "bad dnssec status for signed zone ${_zone}"
|
||||
if [ "$(key_get KEY1 EXPECT)" = "yes" ]; then
|
||||
grep "key: $(key_get KEY1 ID)" rndc.dnssec.status.out.$_zone.$n > /dev/null || _log_error "missing key $(key_get KEY1 ID) from dnssec status"
|
||||
fi
|
||||
if [ "$(key_get KEY2 EXPECT)" = "yes" ]; then
|
||||
grep "key: $(key_get KEY2 ID)" rndc.dnssec.status.out.$_zone.$n > /dev/null || _log_error "missing key $(key_get KEY2 ID) from dnssec status"
|
||||
fi
|
||||
if [ "$(key_get KEY3 EXPECT)" = "yes" ]; then
|
||||
grep "key: $(key_get KEY3 ID)" rndc.dnssec.status.out.$_zone.$n > /dev/null || _log_error "missing key $(key_get KEY3 ID) from dnssec status"
|
||||
fi
|
||||
if [ "$(key_get KEY4 EXPECT)" = "yes" ]; then
|
||||
grep "key: $(key_get KEY4 ID)" rndc.dnssec.status.out.$_zone.$n > /dev/null || _log_error "missing key $(key_get KEY4 ID) from dnssec status"
|
||||
fi
|
||||
fi
|
||||
|
||||
test "$ret" -eq 0 || echo_i "failed"
|
||||
|
@ -100,6 +100,13 @@ zone "unsigned.kasp" {
|
||||
dnssec-policy "none";
|
||||
};
|
||||
|
||||
/* A zone that is initially set to insecure. */
|
||||
zone "insecure.kasp" {
|
||||
type primary;
|
||||
file "insecure.kasp.db";
|
||||
dnssec-policy "insecure";
|
||||
};
|
||||
|
||||
/* A master zone with dnssec-policy but keys already created. */
|
||||
zone "dnssec-keygen.kasp" {
|
||||
type primary;
|
||||
|
@ -79,6 +79,13 @@ zonefile="${zone}.db"
|
||||
infile="${zone}.db.infile"
|
||||
cp template.db.in $zonefile
|
||||
|
||||
# Set up zone that stays unsigned.
|
||||
zone="insecure.kasp"
|
||||
echo_i "setting up zone: $zone"
|
||||
zonefile="${zone}.db"
|
||||
infile="${zone}.db.infile"
|
||||
cp template.db.in $zonefile
|
||||
|
||||
# Some of these zones already have keys.
|
||||
zone="dnssec-keygen.kasp"
|
||||
$KEYGEN -k rsasha1 -l policies/kasp.conf $zone > keygen.out.$zone.1 2>&1
|
||||
|
@ -50,6 +50,12 @@ zone "step1.going-insecure-dynamic.kasp" {
|
||||
allow-update { any; };
|
||||
};
|
||||
|
||||
zone "step1.going-straight-to-none.kasp" {
|
||||
type master;
|
||||
file "step1.going-straight-to-none.kasp.db";
|
||||
dnssec-policy "default";
|
||||
};
|
||||
|
||||
/* These are alorithm rollover test zones. */
|
||||
zone "step1.algorithm-roll.kasp" {
|
||||
type primary;
|
||||
|
@ -39,29 +39,35 @@ controls {
|
||||
zone "step1.going-insecure.kasp" {
|
||||
type master;
|
||||
file "step1.going-insecure.kasp.db";
|
||||
dnssec-policy "none";
|
||||
dnssec-policy "insecure";
|
||||
};
|
||||
|
||||
zone "step2.going-insecure.kasp" {
|
||||
type master;
|
||||
file "step2.going-insecure.kasp.db";
|
||||
dnssec-policy "none";
|
||||
dnssec-policy "insecure";
|
||||
};
|
||||
|
||||
zone "step1.going-insecure-dynamic.kasp" {
|
||||
type master;
|
||||
file "step1.going-insecure-dynamic.kasp.db";
|
||||
dnssec-policy "none";
|
||||
dnssec-policy "insecure";
|
||||
allow-update { any; };
|
||||
};
|
||||
|
||||
zone "step2.going-insecure-dynamic.kasp" {
|
||||
type master;
|
||||
file "step2.going-insecure-dynamic.kasp.db";
|
||||
dnssec-policy "none";
|
||||
dnssec-policy "insecure";
|
||||
allow-update { any; };
|
||||
};
|
||||
|
||||
zone "step1.going-straight-to-none.kasp" {
|
||||
type master;
|
||||
file "step1.going-straight-to-none.kasp.db";
|
||||
dnssec-policy "none";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zones for testing KSK/ZSK algorithm roll.
|
||||
*/
|
||||
|
@ -78,6 +78,17 @@ do
|
||||
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
done
|
||||
|
||||
# This zone is going straight to "none" policy. This is undefined behavior.
|
||||
setup step1.going-straight-to-none.kasp
|
||||
echo "$zone" >> zones
|
||||
TactN="now"
|
||||
csktimes="-P ${TactN} -A ${TactN} -P sync ${TactN}"
|
||||
CSK=$($KEYGEN -k default $csktimes $zone 2> keygen.out.$zone.1)
|
||||
$SETTIME -s -g $O -k $O $TactN -z $O $TactN -r $O $TactN -d $O $TactN "$CSK" > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK}.key" > "$infile"
|
||||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
#
|
||||
# The zones at algorithm-roll.kasp represent the various steps of a ZSK/KSK
|
||||
# algorithm rollover.
|
||||
|
@ -784,6 +784,23 @@ check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
||||
check_apex
|
||||
check_subdomain
|
||||
|
||||
#
|
||||
# Zone: insecure.kasp.
|
||||
#
|
||||
set_zone "insecure.kasp"
|
||||
set_policy "insecure" "0" "0"
|
||||
set_server "ns3" "10.53.0.3"
|
||||
|
||||
key_clear "KEY1"
|
||||
key_clear "KEY2"
|
||||
key_clear "KEY3"
|
||||
key_clear "KEY4"
|
||||
|
||||
check_keys
|
||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
||||
check_apex
|
||||
check_subdomain
|
||||
|
||||
#
|
||||
# Zone: unlimited.kasp.
|
||||
#
|
||||
@ -3541,6 +3558,44 @@ check_apex
|
||||
check_subdomain
|
||||
dnssec_verify
|
||||
|
||||
#
|
||||
# Zone step1.going-straight-to-none.kasp
|
||||
#
|
||||
set_zone "step1.going-straight-to-none.kasp"
|
||||
set_policy "default" "1" "3600"
|
||||
set_server "ns6" "10.53.0.6"
|
||||
# Key properties.
|
||||
set_keyrole "KEY1" "csk"
|
||||
set_keylifetime "KEY1" "0"
|
||||
set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
|
||||
set_keysigning "KEY1" "yes"
|
||||
set_zonesigning "KEY1" "yes"
|
||||
# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait.
|
||||
set_keystate "KEY1" "GOAL" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_KRRSIG" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_ZRRSIG" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_DS" "omnipresent"
|
||||
# This policy only has one key.
|
||||
key_clear "KEY2"
|
||||
key_clear "KEY3"
|
||||
key_clear "KEY4"
|
||||
|
||||
check_keys
|
||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
||||
|
||||
# The first key is immediately published and activated.
|
||||
created=$(key_get KEY1 CREATED)
|
||||
set_keytime "KEY1" "PUBLISHED" "${created}"
|
||||
set_keytime "KEY1" "ACTIVE" "${created}"
|
||||
set_keytime "KEY1" "SYNCPUBLISH" "${created}"
|
||||
# Key lifetime is unlimited, so not setting RETIRED and REMOVED.
|
||||
check_keytimes
|
||||
|
||||
check_apex
|
||||
check_subdomain
|
||||
dnssec_verify
|
||||
|
||||
# Reconfig dnssec-policy (triggering algorithm roll and other dnssec-policy
|
||||
# changes).
|
||||
echo_i "reconfig dnssec-policy to trigger algorithm rollover"
|
||||
@ -3598,7 +3653,7 @@ wait_for_done_signing() {
|
||||
# Zone: step1.going-insecure.kasp
|
||||
#
|
||||
set_zone "step1.going-insecure.kasp"
|
||||
set_policy "none" "2" "7200"
|
||||
set_policy "insecure" "2" "7200"
|
||||
set_server "ns6" "10.53.0.6"
|
||||
# Expect a CDS/CDNSKEY Delete Record.
|
||||
set_cdsdelete
|
||||
@ -3635,7 +3690,7 @@ check_next_key_event 93600
|
||||
# Zone: step2.going-insecure.kasp
|
||||
#
|
||||
set_zone "step2.going-insecure.kasp"
|
||||
set_policy "none" "2" "7200"
|
||||
set_policy "insecure" "2" "7200"
|
||||
set_server "ns6" "10.53.0.6"
|
||||
|
||||
# The DS is long enough removed from the zone to be considered HIDDEN.
|
||||
@ -3665,7 +3720,7 @@ check_next_key_event 7500
|
||||
#
|
||||
set_zone "step1.going-insecure-dynamic.kasp"
|
||||
set_dynamic
|
||||
set_policy "none" "2" "7200"
|
||||
set_policy "insecure" "2" "7200"
|
||||
set_server "ns6" "10.53.0.6"
|
||||
# Expect a CDS/CDNSKEY Delete Record.
|
||||
set_cdsdelete
|
||||
@ -3703,7 +3758,7 @@ check_next_key_event 93600
|
||||
#
|
||||
set_zone "step2.going-insecure-dynamic.kasp"
|
||||
set_dynamic
|
||||
set_policy "none" "2" "7200"
|
||||
set_policy "insecure" "2" "7200"
|
||||
set_server "ns6" "10.53.0.6"
|
||||
|
||||
# The DS is long enough removed from the zone to be considered HIDDEN.
|
||||
@ -3728,6 +3783,42 @@ check_subdomain
|
||||
# 5m + 2h = 125m = 7500 seconds.
|
||||
check_next_key_event 7500
|
||||
|
||||
#
|
||||
# Zone: step1.going-straight-to-none.kasp
|
||||
#
|
||||
set_zone "step1.going-straight-to-none.kasp"
|
||||
set_policy "none" "1" "3600"
|
||||
set_server "ns6" "10.53.0.6"
|
||||
|
||||
# The zone will go bogus after signatures expire, but remains validly signed for now.
|
||||
|
||||
# Key properties.
|
||||
set_keyrole "KEY1" "csk"
|
||||
set_keylifetime "KEY1" "0"
|
||||
set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
|
||||
set_keysigning "KEY1" "yes"
|
||||
set_zonesigning "KEY1" "yes"
|
||||
# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait.
|
||||
set_keystate "KEY1" "GOAL" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_KRRSIG" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_ZRRSIG" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_DS" "omnipresent"
|
||||
# This policy only has one key.
|
||||
key_clear "KEY2"
|
||||
key_clear "KEY3"
|
||||
key_clear "KEY4"
|
||||
|
||||
# Various signing policy checks.
|
||||
check_keys
|
||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
||||
check_apex
|
||||
check_subdomain
|
||||
dnssec_verify
|
||||
|
||||
echo_i "status: $status"
|
||||
exit $status
|
||||
|
||||
#
|
||||
# Testing KSK/ZSK algorithm rollover.
|
||||
#
|
||||
|
@ -1443,12 +1443,12 @@ default is used.
|
||||
reduced.
|
||||
|
||||
``dnssec-policy``
|
||||
This specifies which key and signing policy (KASP) should be used for this zone.
|
||||
This is a string referring to a ``dnssec-policy`` statement. There are two
|
||||
built-in policies: ``default``, which uses the default policy, and
|
||||
``none``, which means no DNSSEC policy and keeps the zone unsigned. The
|
||||
default is ``none``. See :ref:`dnssec-policy Grammar
|
||||
<dnssec_policy_grammar>` for more details.
|
||||
This specifies which key and signing policy (KASP) should be used for this
|
||||
zone. This is a string referring to a ``dnssec-policy`` statement. There
|
||||
are three built-in policies: ``default``, which uses the default policy,
|
||||
``insecure``, to be used when you want to gracefully unsign your zone, and
|
||||
``none``, which means no DNSSEC policy. The default is ``none``.
|
||||
See :ref:`dnssec-policy Grammar <dnssec_policy_grammar>` for more details.
|
||||
|
||||
``dnssec-update-mode``
|
||||
If this option is set to its default value of ``maintain`` in a zone
|
||||
|
@ -1069,8 +1069,8 @@ Below is an example showing how to remove DS records using the
|
||||
To be on the safe side, wait a while before actually deleting
|
||||
all signed data from your zone, just in case some validating resolvers
|
||||
have cached information. After you are certain that all cached
|
||||
information has expired (usually this means one TTL interval has passed), you may
|
||||
reconfigure your zone.
|
||||
information has expired (usually this means one TTL interval has passed),
|
||||
you may reconfigure your zone.
|
||||
|
||||
Here is what ``named.conf`` looks like when it is signed:
|
||||
|
||||
@ -1083,7 +1083,7 @@ Here is what ``named.conf`` looks like when it is signed:
|
||||
dnssec-policy "default";
|
||||
};
|
||||
|
||||
Remove the ``dnssec-policy`` line so your ``named.conf`` looks like this:
|
||||
Change your ``dnssec-policy`` line to indicate you want to revert to unsigned:
|
||||
|
||||
::
|
||||
|
||||
@ -1091,8 +1091,24 @@ Remove the ``dnssec-policy`` line so your ``named.conf`` looks like this:
|
||||
type primary;
|
||||
file "db/example.com.db";
|
||||
allow-transfer { any; };
|
||||
dnssec-policy "insecure";
|
||||
};
|
||||
|
||||
Then use ``rndc reload`` to reload the zone.
|
||||
|
||||
Your zone is now reverted back to the traditional, insecure DNS format.
|
||||
The "insecure" policy is a built-in policy (like "default"). It will make sure
|
||||
the zone is still DNSSEC maintained, to allow for a graceful transition to
|
||||
unsigned,
|
||||
|
||||
When the DS records have been removed from the parent zone, use
|
||||
``rndc dnssec -checkds -key <id> withdrawn example.com`` to tell ``named`` that
|
||||
the DS is removed, and the remaining DNSSEC records will be removed in a timely
|
||||
manner.
|
||||
|
||||
After a while, your zone is reverted back to the traditional, insecure DNS
|
||||
format. You can verify by checking that all DNSKEY and RRSIG records have been
|
||||
removed from the zone.
|
||||
|
||||
You can then remove the ``dnssec-policy`` line from your ``named.conf`` and
|
||||
reload the zone. The zone will now no longer be subject to any DNSSEC
|
||||
maintenance.
|
||||
|
@ -41,7 +41,18 @@ Feature Changes
|
||||
configured in an NSEC3 zones to 150. :gl:`#2642`
|
||||
|
||||
- Treat DNSSEC responses with NSEC3 iterations greater than 150 as insecure.
|
||||
[GL #2445]
|
||||
:gl:`#2445`
|
||||
|
||||
- Implement ``draft-vandijk-dnsop-nsec-ttl``, NSEC(3) TTL values are now set to
|
||||
the minimum of the SOA MINIMUM value and the SOA TTL. :gl:`#2347`
|
||||
|
||||
- Zones that want to transition from secure to insecure mode without making it
|
||||
bogus in the process should now first change their ``dnssec-policy`` to
|
||||
``insecure`` (as opposed to ``none``). Only after the DNSSEC records have
|
||||
been removed from the zone (in a timely manner), the ``dnssec-policy`` can
|
||||
be set to ``none`` (or be removed from the configuration). Setting the
|
||||
``dnssec-policy`` to ``insecure`` will cause CDS and CDNSKEY DELETE records
|
||||
to be published. :gl:`#2645`
|
||||
|
||||
Bug Fixes
|
||||
~~~~~~~~~
|
||||
|
@ -2634,6 +2634,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
||||
|
||||
if (strcmp(kaspname, "default") == 0) {
|
||||
has_dnssecpolicy = true;
|
||||
} else if (strcmp(kaspname, "insecure") == 0) {
|
||||
has_dnssecpolicy = true;
|
||||
} else if (strcmp(kaspname, "none") == 0) {
|
||||
has_dnssecpolicy = false;
|
||||
} else {
|
||||
|
@ -686,32 +686,6 @@ dns_zone_getkasp(dns_zone_t *zone);
|
||||
*\li 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_zone_secure_to_insecure(dns_zone_t *zone, bool reconfig);
|
||||
/*%<
|
||||
* Returns true if the zone is transitioning to insecure.
|
||||
* Only can happen if a zone previously used a dnssec-policy,
|
||||
* but changed the value to "none" (or removed the configuration
|
||||
* option). If 'reconfig' is true, only check the key files,
|
||||
* because the zone structure is not yet updated with the
|
||||
* newest configuration.
|
||||
*
|
||||
* Require:
|
||||
*\li 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_zone_use_kasp(dns_zone_t *zone);
|
||||
/*%<
|
||||
* Check if zone needs to use kasp.
|
||||
* True if there is a policy that is not "none",
|
||||
* or if there are state files associated with the keys
|
||||
* related to this zone.
|
||||
*
|
||||
* Require:
|
||||
*\li 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t *kasp);
|
||||
/*%<
|
||||
|
@ -1087,6 +1087,7 @@ add_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
|
||||
bool keyset_kskonly) {
|
||||
isc_result_t result;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_kasp_t *kasp = dns_zone_getkasp(zone);
|
||||
dns_rdataset_t rdataset;
|
||||
dns_rdata_t sig_rdata = DNS_RDATA_INIT;
|
||||
dns_stats_t *dnssecsignstats = dns_zone_getdnssecsignstats(zone);
|
||||
@ -1097,7 +1098,7 @@ add_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
|
||||
bool use_kasp = false;
|
||||
isc_mem_t *mctx = diff->mctx;
|
||||
|
||||
if (dns_zone_use_kasp(zone)) {
|
||||
if (kasp != NULL) {
|
||||
check_ksk = false;
|
||||
keyset_kskonly = true;
|
||||
use_kasp = true;
|
||||
|
@ -1292,7 +1292,6 @@ dns_zone_rekey
|
||||
dns_zone_replacedb
|
||||
dns_zone_rpz_enable
|
||||
dns_zone_rpz_enable_db
|
||||
dns_zone_secure_to_insecure
|
||||
dns_zone_set_parentcatz
|
||||
dns_zone_setadded
|
||||
dns_zone_setalsonotify
|
||||
@ -1378,7 +1377,6 @@ dns_zone_setzeronosoattl
|
||||
dns_zone_signwithkey
|
||||
dns_zone_synckeyzone
|
||||
dns_zone_unload
|
||||
dns_zone_use_kasp
|
||||
dns_zone_verifydb
|
||||
dns_zonekey_iszonekey
|
||||
dns_zonemgr_attach
|
||||
|
106
lib/dns/zone.c
106
lib/dns/zone.c
@ -5736,82 +5736,6 @@ dns_zone_getkasp(dns_zone_t *zone) {
|
||||
return (zone->kasp);
|
||||
}
|
||||
|
||||
static bool
|
||||
statefile_exist(dns_zone_t *zone) {
|
||||
isc_result_t ret;
|
||||
dns_dnsseckeylist_t keys;
|
||||
dns_dnsseckey_t *key = NULL;
|
||||
isc_stdtime_t now;
|
||||
isc_time_t timenow;
|
||||
bool found = false;
|
||||
|
||||
TIME_NOW(&timenow);
|
||||
now = isc_time_seconds(&timenow);
|
||||
|
||||
ISC_LIST_INIT(keys);
|
||||
|
||||
ret = dns_dnssec_findmatchingkeys(dns_zone_getorigin(zone),
|
||||
dns_zone_getkeydirectory(zone), now,
|
||||
dns_zone_getmctx(zone), &keys);
|
||||
if (ret == ISC_R_SUCCESS) {
|
||||
for (key = ISC_LIST_HEAD(keys); key != NULL;
|
||||
key = ISC_LIST_NEXT(key, link)) {
|
||||
if (dst_key_haskasp(key->key)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up keys */
|
||||
while (!ISC_LIST_EMPTY(keys)) {
|
||||
key = ISC_LIST_HEAD(keys);
|
||||
ISC_LIST_UNLINK(keys, key, link);
|
||||
dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key);
|
||||
}
|
||||
|
||||
return (found);
|
||||
}
|
||||
|
||||
bool
|
||||
dns_zone_secure_to_insecure(dns_zone_t *zone, bool reconfig) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
/*
|
||||
* If checking during reconfig, the zone is not yet updated
|
||||
* with the new kasp configuration, so only check the key
|
||||
* files.
|
||||
*/
|
||||
if (reconfig) {
|
||||
return (statefile_exist(zone));
|
||||
}
|
||||
|
||||
if (zone->kasp == NULL) {
|
||||
return (false);
|
||||
}
|
||||
if (strcmp(dns_kasp_getname(zone->kasp), "none") != 0) {
|
||||
return (false);
|
||||
}
|
||||
/*
|
||||
* "dnssec-policy none", but if there are key state files
|
||||
* this zone used to be secure but is transitioning back to
|
||||
* insecure.
|
||||
*/
|
||||
return (statefile_exist(zone));
|
||||
}
|
||||
|
||||
bool
|
||||
dns_zone_use_kasp(dns_zone_t *zone) {
|
||||
dns_kasp_t *kasp = dns_zone_getkasp(zone);
|
||||
|
||||
if (kasp == NULL) {
|
||||
return (false);
|
||||
} else if (strcmp(dns_kasp_getname(kasp), "none") != 0) {
|
||||
return (true);
|
||||
}
|
||||
return dns_zone_secure_to_insecure(zone, false);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option, bool value) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
@ -6793,7 +6717,7 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_zone_t *zone,
|
||||
unsigned int i, j;
|
||||
bool use_kasp = false;
|
||||
|
||||
if (dns_zone_use_kasp(zone)) {
|
||||
if (dns_zone_getkasp(zone) != NULL) {
|
||||
check_ksk = false;
|
||||
keyset_kskonly = true;
|
||||
use_kasp = true;
|
||||
@ -7311,7 +7235,7 @@ signed_with_good_key(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
|
||||
dns_rdata_reset(&rdata);
|
||||
}
|
||||
|
||||
if (dns_zone_use_kasp(zone)) {
|
||||
if (dns_zone_getkasp(zone) != NULL) {
|
||||
dns_kasp_key_t *kkey;
|
||||
int zsk_count = 0;
|
||||
bool approved;
|
||||
@ -7523,7 +7447,7 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
|
||||
} else if (is_zsk && !dst_key_is_signing(key, DST_BOOL_ZSK,
|
||||
inception, &when)) {
|
||||
/* Only applies to dnssec-policy. */
|
||||
if (dns_zone_use_kasp(zone)) {
|
||||
if (dns_zone_getkasp(zone) != NULL) {
|
||||
goto next_rdataset;
|
||||
}
|
||||
}
|
||||
@ -9262,7 +9186,7 @@ zone_sign(dns_zone_t *zone) {
|
||||
signing = ISC_LIST_HEAD(zone->signing);
|
||||
first = true;
|
||||
|
||||
if (dns_zone_use_kasp(zone)) {
|
||||
if (dns_zone_getkasp(zone) != NULL) {
|
||||
check_ksk = false;
|
||||
keyset_kskonly = true;
|
||||
use_kasp = true;
|
||||
@ -16659,7 +16583,7 @@ copy_non_dnssec_records(dns_zone_t *zone, dns_db_t *db, dns_db_t *version,
|
||||
* Allow DNSSEC records with dnssec-policy.
|
||||
* WMM: Perhaps add config option for it.
|
||||
*/
|
||||
if (!dns_zone_use_kasp(zone)) {
|
||||
if (dns_zone_getkasp(zone) == NULL) {
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
continue;
|
||||
}
|
||||
@ -19961,7 +19885,7 @@ zone_rekey(dns_zone_t *zone) {
|
||||
dns__zonediff_t zonediff;
|
||||
bool commit = false, newactive = false;
|
||||
bool newalg = false;
|
||||
bool fullsign, use_kasp;
|
||||
bool fullsign;
|
||||
dns_ttl_t ttl = 3600;
|
||||
const char *dir = NULL;
|
||||
isc_mem_t *mctx = NULL;
|
||||
@ -20035,7 +19959,6 @@ zone_rekey(dns_zone_t *zone) {
|
||||
fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN);
|
||||
|
||||
kasp = dns_zone_getkasp(zone);
|
||||
use_kasp = dns_zone_use_kasp(zone);
|
||||
if (kasp != NULL) {
|
||||
LOCK(&kasp->lock);
|
||||
}
|
||||
@ -20048,10 +19971,14 @@ zone_rekey(dns_zone_t *zone) {
|
||||
isc_result_totext(result));
|
||||
}
|
||||
|
||||
if (use_kasp && (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND)) {
|
||||
if (kasp != NULL &&
|
||||
(result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND)) {
|
||||
result = dns_keymgr_run(&zone->origin, zone->rdclass, dir, mctx,
|
||||
&keys, kasp, now, &nexttime);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (kasp != NULL) {
|
||||
UNLOCK(&kasp->lock);
|
||||
}
|
||||
dnssec_log(zone, ISC_LOG_ERROR,
|
||||
"zone_rekey:dns_dnssec_keymgr failed: %s",
|
||||
isc_result_totext(result));
|
||||
@ -20064,12 +19991,17 @@ zone_rekey(dns_zone_t *zone) {
|
||||
}
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
bool cds_delete = false;
|
||||
isc_stdtime_t when;
|
||||
|
||||
/*
|
||||
* Publish CDS/CDNSKEY DELETE records if the zone is
|
||||
* transitioning from secure to insecure.
|
||||
*/
|
||||
bool cds_delete = dns_zone_secure_to_insecure(zone, false);
|
||||
isc_stdtime_t when;
|
||||
if (kasp != NULL &&
|
||||
strcmp(dns_kasp_getname(kasp), "insecure") == 0) {
|
||||
cds_delete = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only update DNSKEY TTL if we have a policy.
|
||||
@ -20329,7 +20261,7 @@ zone_rekey(dns_zone_t *zone) {
|
||||
/*
|
||||
* If keymgr provided a next time, use the calculated next rekey time.
|
||||
*/
|
||||
if (use_kasp) {
|
||||
if (kasp != NULL) {
|
||||
isc_time_t timenext;
|
||||
uint32_t nexttime_seconds;
|
||||
|
||||
|
@ -326,9 +326,9 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx,
|
||||
}
|
||||
}
|
||||
INSIST(!(dns_kasp_keylist_empty(kasp)));
|
||||
} else if (strcmp(kaspname, "none") == 0) {
|
||||
/* "dnssec-policy none": key list must be empty */
|
||||
INSIST(strcmp(kaspname, "none") == 0);
|
||||
} else if (strcmp(kaspname, "insecure") == 0) {
|
||||
/* "dnssec-policy insecure": key list must be empty */
|
||||
INSIST(strcmp(kaspname, "insecure") == 0);
|
||||
INSIST(dns_kasp_keylist_empty(kasp));
|
||||
} else {
|
||||
/* No keys clause configured, use the "default". */
|
||||
|
Loading…
x
Reference in New Issue
Block a user