dns_zone_t *raw = NULL; /* New or reused raw zone */
dns_zone_t *dupzone = NULL;
const cfg_obj_t *options = NULL;
+ const cfg_obj_t *voptions = NULL;
const cfg_obj_t *zoptions = NULL;
const cfg_obj_t *typeobj = NULL;
const cfg_obj_t *forwarders = NULL;
const char *ztypestr;
dns_rpz_num_t rpz_num;
bool zone_is_catz = false;
+ bool zone_maybe_inline = false;
+ bool inline_signing = false;
options = NULL;
(void)cfg_map_get(config, "options", &options);
zoptions = cfg_tuple_get(zconfig, "options");
+ if (vconfig != NULL) {
+ voptions = cfg_tuple_get(vconfig, "options");
+ }
/*
* Get the zone origin as a dns_name_t.
*/
dns_zone_setadded(zone, added);
+ /*
+ * Determine if we need to set up inline signing.
+ */
+ zone_maybe_inline = ((strcasecmp(ztypestr, "primary") == 0 ||
+ strcasecmp(ztypestr, "master") == 0 ||
+ strcasecmp(ztypestr, "secondary") == 0 ||
+ strcasecmp(ztypestr, "slave") == 0));
+
+ signing = NULL;
+ inline_signing = (zone_maybe_inline &&
+ ((cfg_map_get(zoptions, "inline-signing", &signing) ==
+ ISC_R_SUCCESS &&
+ cfg_obj_asboolean(signing))));
+
+ /*
+ * If inline-signing is not set, perhaps implictly through a
+ * dnssec-policy. Since automated DNSSEC maintenance requires
+ * a dynamic zone, or inline-siging to be enabled, check if
+ * the zone with dnssec-policy allows updates. If not, enable
+ * inline-signing.
+ */
signing = NULL;
- if ((strcasecmp(ztypestr, "primary") == 0 ||
- strcasecmp(ztypestr, "master") == 0 ||
- strcasecmp(ztypestr, "secondary") == 0 ||
- strcasecmp(ztypestr, "slave") == 0) &&
- ((cfg_map_get(zoptions, "inline-signing", &signing) ==
- ISC_R_SUCCESS &&
- cfg_obj_asboolean(signing)) ||
- (cfg_map_get(zoptions, "dnssec-policy", &signing) ==
- ISC_R_SUCCESS &&
- signing != NULL &&
- strcmp(cfg_obj_asstring(signing), "none") != 0)))
+ if (zone_maybe_inline && !inline_signing &&
+ cfg_map_get(zoptions, "dnssec-policy", &signing) == ISC_R_SUCCESS &&
+ signing != NULL && strcmp(cfg_obj_asstring(signing), "none") != 0)
{
+ isc_result_t res;
+ bool zone_is_dynamic = false;
+ const cfg_obj_t *au = NULL;
+ const cfg_obj_t *up = NULL;
+
+ if (cfg_map_get(zoptions, "update-policy", &up) ==
+ ISC_R_SUCCESS) {
+ zone_is_dynamic = true;
+ } else {
+ res = cfg_map_get(zoptions, "allow-update", &au);
+ if (res != ISC_R_SUCCESS && voptions != NULL) {
+ res = cfg_map_get(voptions, "allow-update",
+ &au);
+ }
+ if (res != ISC_R_SUCCESS && options != NULL) {
+ res = cfg_map_get(options, "allow-update", &au);
+ }
+ if (res == ISC_R_SUCCESS) {
+ dns_acl_t *acl = NULL;
+ cfg_aclconfctx_t *actx = NULL;
+ res = cfg_acl_fromconfig(au, config,
+ named_g_lctx, actx,
+ mctx, 0, &acl);
+ if (res == ISC_R_SUCCESS && acl != NULL &&
+ !dns_acl_isnone(acl)) {
+ zone_is_dynamic = true;
+ }
+ if (acl != NULL) {
+ dns_acl_detach(&acl);
+ }
+ }
+ }
+
+ if (!zone_is_dynamic) {
+ inline_signing = true;
+ }
+ }
+
+ if (inline_signing) {
dns_zone_getraw(zone, &raw);
if (raw == NULL) {
CHECK(dns_zone_create(&raw, mctx));
next_key_event_threshold=$((next_key_event_threshold+i))
-#
-# Zone: default.kasp.
-#
-
-# Check the zone with default kasp policy has loaded and is signed.
-set_zone "default.kasp"
-set_policy "default" "1" "3600"
-set_server "ns3" "10.53.0.3"
-# Key properties.
-set_keyrole "KEY1" "csk"
-set_keylifetime "KEY1" "0"
-set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
-set_keysigning "KEY1" "yes"
-set_zonesigning "KEY1" "yes"
-
-# The first key is immediately published and activated.
-set_keytime "KEY1" "PUBLISHED" "yes"
-set_keytime "KEY1" "ACTIVE" "yes"
-# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait.
-set_keystate "KEY1" "GOAL" "omnipresent"
-set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
-set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
-set_keystate "KEY1" "STATE_ZRRSIG" "rumoured"
-set_keystate "KEY1" "STATE_DS" "hidden"
-
-n=$((n+1))
-echo_i "check key is created for zone ${ZONE} ($n)"
-ret=0
-ids=$(get_keyids "$DIR" "$ZONE")
-for id in $ids; do
- check_key "KEY1" "$id"
-done
-test "$ret" -eq 0 || echo_i "failed"
-status=$((status+ret))
-
-# Verify signed zone.
-dnssec_verify "$ZONE"
-
-# Test DNSKEY query.
-qtype="DNSKEY"
-n=$((n+1))
-echo_i "check ${qtype} rrset is signed correctly for zone ${ZONE} ($n)"
-ret=0
-dig_with_opts "$ZONE" "@${SERVER}" $qtype > "dig.out.$DIR.test$n" || log_error "dig ${ZONE} ${qtype} failed"
-grep "status: NOERROR" "dig.out.$DIR.test$n" > /dev/null || log_error "mismatch status in DNS response"
-grep "${ZONE}\..*${DNSKEY_TTL}.*IN.*${qtype}.*257.*.3.*$(key_get KEY1 ALG_NUM)" "dig.out.$DIR.test$n" > /dev/null || log_error "missing ${qtype} record in response"
-lines=$(get_keys_which_signed $qtype "dig.out.$DIR.test$n" | wc -l)
-test "$lines" -eq 1 || log_error "bad number ($lines) of RRSIG records in DNS response"
-get_keys_which_signed $qtype "dig.out.$DIR.test$n" | grep "^${KEY_ID}$" > /dev/null || log_error "${qtype} RRset not signed with key ${KEY_ID}"
-test "$ret" -eq 0 || echo_i "failed"
-status=$((status+ret))
-
-# Test SOA query.
-qtype="SOA"
-n=$((n+1))
-echo_i "check ${qtype} rrset is signed correctly for zone ${ZONE} ($n)"
-ret=0
-dig_with_opts "$ZONE" "@${SERVER}" $qtype > "dig.out.$DIR.test$n" || log_error "dig ${ZONE} ${qtype} failed"
-grep "status: NOERROR" "dig.out.$DIR.test$n" > /dev/null || log_error "mismatch status in DNS response"
-grep "${ZONE}\..*${DEFAULT_TTL}.*IN.*${qtype}.*mname1\..*\." "dig.out.$DIR.test$n" > /dev/null || log_error "missing ${qtype} record in response"
-lines=$(get_keys_which_signed $qtype "dig.out.$DIR.test$n" | wc -l)
-test "$lines" -eq 1 || log_error "bad number ($lines) of RRSIG records in DNS response"
-get_keys_which_signed $qtype "dig.out.$DIR.test$n" | grep "^${KEY_ID}$" > /dev/null || log_error "${qtype} RRset not signed with key ${KEY_ID}"
-test "$ret" -eq 0 || echo_i "failed"
-status=$((status+ret))
-
-# Update zone.
-n=$((n+1))
-echo_i "check that we can update unsigned zone file and new record gets signed for zone ${ZONE} ($n)"
-ret=0
-cp "${DIR}/template2.db.in" "${DIR}/${ZONE}.db"
-rndccmd 10.53.0.3 reload "$ZONE" > /dev/null || log_error "rndc reload zone ${ZONE} failed"
-_log=0
-i=0
-while [ $i -lt 5 ]
-do
- ret=0
-
- dig_with_opts "a.${ZONE}" "@${SERVER}" A > "dig.out.$DIR.test$n.a" || log_error "dig a.${ZONE} A failed"
- grep "status: NOERROR" "dig.out.$DIR.test$n.a" > /dev/null || log_error "mismatch status in DNS response"
- grep "a.${ZONE}\..*${DEFAULT_TTL}.*IN.*A.*10\.0\.0\.11" "dig.out.$DIR.test$n.a" > /dev/null || log_error "missing a.${ZONE} A record in response"
- lines=$(get_keys_which_signed A "dig.out.$DIR.test$n.a" | wc -l)
- test "$lines" -eq 1 || log_error "bad number ($lines) of RRSIG records in DNS response"
- get_keys_which_signed A "dig.out.$DIR.test$n.a" | grep "^${KEY_ID}$" > /dev/null || log_error "A RRset not signed with key ${KEY_ID}"
-
- dig_with_opts "d.${ZONE}" "@${SERVER}" A > "dig.out.$DIR.test$n".d || log_error "dig d.${ZONE} A failed"
- grep "status: NOERROR" "dig.out.$DIR.test$n".d > /dev/null || log_error "mismatch status in DNS response"
- grep "d.${ZONE}\..*${DEFAULT_TTL}.*IN.*A.*10\.0\.0\.4" "dig.out.$DIR.test$n".d > /dev/null || log_error "missing d.${ZONE} A record in response"
- lines=$(get_keys_which_signed A "dig.out.$DIR.test$n".d | wc -l)
- test "$lines" -eq 1 || log_error "bad number ($lines) of RRSIG records in DNS response"
- get_keys_which_signed A "dig.out.$DIR.test$n".d | grep "^${KEY_ID}$" > /dev/null || log_error "A RRset not signed with key ${KEY_ID}"
-
- i=$((i+1))
- if [ $ret = 0 ]; then break; fi
- echo_i "waiting ... ($i)"
- sleep 1
-done
-_log=1
-test "$ret" -eq 0 || echo_i "failed"
-status=$((status+ret))
-
-#
-# Zone: rsasha1.kasp.
-#
-set_zone "rsasha1.kasp"
-set_policy "rsasha1" "3" "1234"
-set_server "ns3" "10.53.0.3"
-# Key properties.
-key_clear "KEY1"
-set_keyrole "KEY1" "ksk"
-set_keylifetime "KEY1" "315360000"
-set_keyalgorithm "KEY1" "5" "RSASHA1" "2048"
-set_keysigning "KEY1" "yes"
-set_zonesigning "KEY1" "no"
-
-key_clear "KEY2"
-set_keyrole "KEY2" "zsk"
-set_keylifetime "KEY2" "157680000"
-set_keyalgorithm "KEY2" "5" "RSASHA1" "2048"
-set_keysigning "KEY2" "no"
-set_zonesigning "KEY2" "yes"
-
-key_clear "KEY3"
-set_keyrole "KEY3" "zsk"
-set_keylifetime "KEY3" "31536000"
-set_keyalgorithm "KEY3" "5" "RSASHA1" "2000"
-set_keysigning "KEY3" "no"
-set_zonesigning "KEY3" "yes"
-# The first keys are immediately published and activated.
-# Because lifetime > 0, retired timing is also set.
-set_keytime "KEY1" "PUBLISHED" "yes"
-set_keytime "KEY1" "ACTIVE" "yes"
-set_keytime "KEY1" "RETIRED" "yes"
-
-set_keytime "KEY2" "PUBLISHED" "yes"
-set_keytime "KEY2" "ACTIVE" "yes"
-set_keytime "KEY2" "RETIRED" "yes"
-
-set_keytime "KEY3" "PUBLISHED" "yes"
-set_keytime "KEY3" "ACTIVE" "yes"
-set_keytime "KEY3" "RETIRED" "yes"
-# KSK: DNSKEY, RRSIG (ksk) published. DS needs to wait.
-# ZSK: DNSKEY, RRSIG (zsk) published.
-set_keystate "KEY1" "GOAL" "omnipresent"
-set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
-set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
-set_keystate "KEY1" "STATE_DS" "hidden"
-
-set_keystate "KEY2" "GOAL" "omnipresent"
-set_keystate "KEY2" "STATE_DNSKEY" "rumoured"
-set_keystate "KEY2" "STATE_ZRRSIG" "rumoured"
-
-set_keystate "KEY3" "GOAL" "omnipresent"
-set_keystate "KEY3" "STATE_DNSKEY" "rumoured"
-set_keystate "KEY3" "STATE_ZRRSIG" "rumoured"
-# Three keys only.
-key_clear "KEY4"
-
# Check keys for a configured zone. This verifies:
# 1. The right number of keys exist in the key pool ($1).
# 2. The right number of keys is active. Checks KEY1, KEY2, KEY3, and KEY4.
status=$((status+ret))
}
+#
+# Zone: default.kasp.
+#
+
+# Check the zone with default kasp policy has loaded and is signed.
+set_zone "default.kasp"
+set_policy "default" "1" "3600"
+set_server "ns3" "10.53.0.3"
+# Key properties.
+set_keyrole "KEY1" "csk"
+set_keylifetime "KEY1" "0"
+set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
+set_keysigning "KEY1" "yes"
+set_zonesigning "KEY1" "yes"
+
+# The first key is immediately published and activated.
+set_keytime "KEY1" "PUBLISHED" "yes"
+set_keytime "KEY1" "ACTIVE" "yes"
+# DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait.
+set_keystate "KEY1" "GOAL" "omnipresent"
+set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
+set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
+set_keystate "KEY1" "STATE_ZRRSIG" "rumoured"
+set_keystate "KEY1" "STATE_DS" "hidden"
+
+check_keys
+check_apex
+check_subdomain
+dnssec_verify
+
+# Update zone.
+n=$((n+1))
+echo_i "check that we can update unsigned zone file and new record gets signed for zone ${ZONE} ($n)"
+ret=0
+cp "${DIR}/template2.db.in" "${DIR}/${ZONE}.db"
+rndccmd 10.53.0.3 reload "$ZONE" > /dev/null || log_error "rndc reload zone ${ZONE} failed"
+_log=0
+i=0
+while [ $i -lt 5 ]
+do
+ ret=0
+
+ dig_with_opts "a.${ZONE}" "@${SERVER}" A > "dig.out.$DIR.test$n.a" || log_error "dig a.${ZONE} A failed"
+ grep "status: NOERROR" "dig.out.$DIR.test$n.a" > /dev/null || log_error "mismatch status in DNS response"
+ grep "a.${ZONE}\..*${DEFAULT_TTL}.*IN.*A.*10\.0\.0\.11" "dig.out.$DIR.test$n.a" > /dev/null || log_error "missing a.${ZONE} A record in response"
+ lines=$(get_keys_which_signed A "dig.out.$DIR.test$n.a" | wc -l)
+ test "$lines" -eq 1 || log_error "bad number ($lines) of RRSIG records in DNS response"
+ get_keys_which_signed A "dig.out.$DIR.test$n.a" | grep "^${KEY_ID}$" > /dev/null || log_error "A RRset not signed with key ${KEY_ID}"
+
+ dig_with_opts "d.${ZONE}" "@${SERVER}" A > "dig.out.$DIR.test$n".d || log_error "dig d.${ZONE} A failed"
+ grep "status: NOERROR" "dig.out.$DIR.test$n".d > /dev/null || log_error "mismatch status in DNS response"
+ grep "d.${ZONE}\..*${DEFAULT_TTL}.*IN.*A.*10\.0\.0\.4" "dig.out.$DIR.test$n".d > /dev/null || log_error "missing d.${ZONE} A record in response"
+ lines=$(get_keys_which_signed A "dig.out.$DIR.test$n".d | wc -l)
+ test "$lines" -eq 1 || log_error "bad number ($lines) of RRSIG records in DNS response"
+ get_keys_which_signed A "dig.out.$DIR.test$n".d | grep "^${KEY_ID}$" > /dev/null || log_error "A RRset not signed with key ${KEY_ID}"
+
+ i=$((i+1))
+ if [ $ret = 0 ]; then break; fi
+ echo_i "waiting ... ($i)"
+ sleep 1
+done
+_log=1
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status+ret))
+
+#
+# Zone: dynamic.kasp
+#
+set_zone "dynamic.kasp"
+set_policy "default" "1" "3600"
+set_server "ns3" "10.53.0.3"
+# Key properties, timings and states same as above.
+check_keys
+check_apex
+check_subdomain
+dnssec_verify
+
+#
+# Zone: dynamic-inline-signing.kasp
+#
+set_zone "dynamic-inline-signing.kasp"
+set_policy "default" "1" "3600"
+set_server "ns3" "10.53.0.3"
+# Key properties, timings and states same as above.
+check_keys
+check_apex
+check_subdomain
+dnssec_verify
+
+#
+# Zone: inline-signing.kasp
+#
+set_zone "inline-signing.kasp"
+set_policy "default" "1" "3600"
+set_server "ns3" "10.53.0.3"
+# Key properties, timings and states same as above.
+check_keys
+check_apex
+check_subdomain
+dnssec_verify
+
+#
+# Zone: rsasha1.kasp.
+#
+set_zone "rsasha1.kasp"
+set_policy "rsasha1" "3" "1234"
+set_server "ns3" "10.53.0.3"
+# Key properties.
+key_clear "KEY1"
+set_keyrole "KEY1" "ksk"
+set_keylifetime "KEY1" "315360000"
+set_keyalgorithm "KEY1" "5" "RSASHA1" "2048"
+set_keysigning "KEY1" "yes"
+set_zonesigning "KEY1" "no"
+
+key_clear "KEY2"
+set_keyrole "KEY2" "zsk"
+set_keylifetime "KEY2" "157680000"
+set_keyalgorithm "KEY2" "5" "RSASHA1" "2048"
+set_keysigning "KEY2" "no"
+set_zonesigning "KEY2" "yes"
+
+key_clear "KEY3"
+set_keyrole "KEY3" "zsk"
+set_keylifetime "KEY3" "31536000"
+set_keyalgorithm "KEY3" "5" "RSASHA1" "2000"
+set_keysigning "KEY3" "no"
+set_zonesigning "KEY3" "yes"
+# The first keys are immediately published and activated.
+# Because lifetime > 0, retired timing is also set.
+set_keytime "KEY1" "PUBLISHED" "yes"
+set_keytime "KEY1" "ACTIVE" "yes"
+set_keytime "KEY1" "RETIRED" "yes"
+
+set_keytime "KEY2" "PUBLISHED" "yes"
+set_keytime "KEY2" "ACTIVE" "yes"
+set_keytime "KEY2" "RETIRED" "yes"
+
+set_keytime "KEY3" "PUBLISHED" "yes"
+set_keytime "KEY3" "ACTIVE" "yes"
+set_keytime "KEY3" "RETIRED" "yes"
+# KSK: DNSKEY, RRSIG (ksk) published. DS needs to wait.
+# ZSK: DNSKEY, RRSIG (zsk) published.
+set_keystate "KEY1" "GOAL" "omnipresent"
+set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
+set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
+set_keystate "KEY1" "STATE_DS" "hidden"
+
+set_keystate "KEY2" "GOAL" "omnipresent"
+set_keystate "KEY2" "STATE_DNSKEY" "rumoured"
+set_keystate "KEY2" "STATE_ZRRSIG" "rumoured"
+
+set_keystate "KEY3" "GOAL" "omnipresent"
+set_keystate "KEY3" "STATE_DNSKEY" "rumoured"
+set_keystate "KEY3" "STATE_ZRRSIG" "rumoured"
+# Three keys only.
+key_clear "KEY4"
+
check_keys
check_apex
check_subdomain
for (element = cfg_list_first(kasps); element != NULL;
element = cfg_list_next(element))
{
- const char *kn = cfg_obj_asstring(cfg_tuple_get(
- cfg_listelt_value(element), "name"));
- if (strcmp(kaspname, kn) == 0) {
+ const cfg_obj_t *kobj = cfg_tuple_get(
+ cfg_listelt_value(element), "name");
+ if (strcmp(kaspname, cfg_obj_asstring(kobj)) ==
+ 0) {
has_dnssecpolicy = true;
}
}
res1 = cfg_map_get(zoptions, "inline-signing", &obj);
if (res1 == ISC_R_SUCCESS) {
signing = cfg_obj_asboolean(obj);
- }
-
- if (signing && has_dnssecpolicy) {
- cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
- "inline-signing: cannot be configured if "
- "dnssec-policy is also set");
- result = ISC_R_FAILURE;
+ if (has_dnssecpolicy && !ddns && !signing) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "'inline-signing;' cannot be set "
+ "to 'no' "
+ "if dnssec-policy is also set on a "
+ "non-dynamic DNS zone");
+ result = ISC_R_FAILURE;
+ }
}
obj = NULL;
arg = cfg_obj_asstring(obj);
}
if (strcasecmp(arg, "off") != 0) {
- if (!ddns && !signing) {
+ if (!ddns && !signing && strcasecmp(arg, "off") != 0) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"'auto-dnssec %s;' requires%s "
"inline-signing to be configured "
: "");
result = ISC_R_FAILURE;
}
- if (has_dnssecpolicy) {
+
+ if (strcasecmp(arg, "off") != 0 && has_dnssecpolicy) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"'auto-dnssec %s;' cannot be "
"configured if dnssec-policy is "
return (true);
}
+ /* Kasp zones are always dynamic. */
+ if (dns_zone_getkasp(zone) != NULL) {
+ return (true);
+ }
+
/* If !ignore_freeze, we need check whether updates are disabled. */
if (zone->type == dns_zone_master &&
(!zone->update_disabled || ignore_freeze) &&
goto cleanup;
}
- is_dynamic = dns_zone_isdynamic(zone, false) ||
- dns_zone_getkasp(zone) != NULL;
+ is_dynamic = dns_zone_isdynamic(zone, false);
if (zone->db != NULL && is_dynamic) {
/*
* This is a slave, stub, dynamically updated, or kasp enabled
bool dynamic = (zone->type == dns_zone_master)
? dns_zone_isdynamic(zone, false)
: false;
- dynamic = dynamic || dns_zone_getkasp(zone);
dns_rdataset_init(&rdataset);
result = dns_db_findnode(db, &zone->origin, false, &node);
* journal file if it isn't, as we wouldn't be able to apply
* updates otherwise.
*/
- is_dynamic = dns_zone_isdynamic(zone, true) ||
- dns_zone_getkasp(zone) != NULL;
+ is_dynamic = dns_zone_isdynamic(zone, true);
if (zone->journal != NULL && is_dynamic &&
!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS))
{
resume_addnsec3chain(zone);
}
- is_dynamic = dns_zone_isdynamic(zone, false) ||
- dns_zone_getkasp(zone) != NULL;
+ is_dynamic = dns_zone_isdynamic(zone, false);
if (zone->type == dns_zone_master &&
!DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
is_dynamic && dns_db_issecure(db))
LOCK_ZONE(zone);
if (!inline_secure(zone)) {
- if (!dns_zone_isdynamic(zone, true) &&
- dns_zone_getkasp(zone) == NULL) {
+ if (!dns_zone_isdynamic(zone, true)) {
result = DNS_R_NOTDYNAMIC;
goto failure;
}