diff --git a/bin/tests/system/nsec3/tests.sh b/bin/tests/system/nsec3/tests.sh index 9a4a2d22f7..d22b3fd65f 100644 --- a/bin/tests/system/nsec3/tests.sh +++ b/bin/tests/system/nsec3/tests.sh @@ -235,44 +235,6 @@ key_clear "KEY2" key_clear "KEY3" key_clear "KEY4" -# Test NSEC3 and NSEC3PARAM is the same after restart -set_zone_policy "nsec3.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" -set_key_default_values "KEY1" -echo_i "check zone ${ZONE} before restart" -check_nsec3 - -# Restart named, NSEC3 should stay the same. -ret=0 -echo "stop ns3" -stop_server --use-rndc --port ${CONTROLPORT} ${DIR} || ret=1 -test "$ret" -eq 0 || echo_i "failed" -status=$((status + ret)) - -ret=0 -echo "start ns3" -start_server --noclean --restart --port ${PORT} ${DIR} -test "$ret" -eq 0 || echo_i "failed" -status=$((status + ret)) - -prevsalt="${SALT}" -set_zone_policy "nsec3.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" -set_key_default_values "KEY1" -SALT="${prevsalt}" -echo_i "check zone ${ZONE} after restart has salt ${SALT}" -check_nsec3 - -# Zone: nsec3-fails-to-load.kasp. (should be fixed after reload) -cp ns3/template.db.in ns3/nsec3-fails-to-load.kasp.db -rndc_reload ns3 10.53.0.3 - -set_zone_policy "nsec3-fails-to-load.kasp" "nsec3" 1 3600 -set_nsec3param "0" "0" -set_key_default_values "KEY1" -echo_i "check zone ${ZONE} after reload" -check_nsec3 - # Zone: nsec3-ent.kasp (regression test for #5108) n=$((n + 1)) echo_i "check query for newly empty name does not crash ($n)" diff --git a/bin/tests/system/nsec3/tests_nsec3_reconfig.py b/bin/tests/system/nsec3/tests_nsec3_reconfig.py index 7ce5846ed3..9178d9c716 100644 --- a/bin/tests/system/nsec3/tests_nsec3_reconfig.py +++ b/bin/tests/system/nsec3/tests_nsec3_reconfig.py @@ -53,9 +53,10 @@ def after_servers_start(ns3, templates): return False + nsdir = ns3.identifier + # Extra test for nsec3-change.kasp. zone = "nsec3-change.kasp" - nsdir = ns3.identifier fqdn = f"{zone}." isctest.kasp.wait_keymgr_done(ns3, zone) shutil.copyfile(f"{nsdir}/template2.db.in", f"{nsdir}/{zone}.db") diff --git a/bin/tests/system/nsec3/tests_nsec3_reload.py b/bin/tests/system/nsec3/tests_nsec3_reload.py new file mode 100644 index 0000000000..0e5dd0cfea --- /dev/null +++ b/bin/tests/system/nsec3/tests_nsec3_reload.py @@ -0,0 +1,52 @@ +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +# pylint: disable=redefined-outer-name,unused-import + +import os +import shutil +import time + +import pytest + +pytest.importorskip("dns", minversion="2.0.0") +import isctest +from nsec3.common import ( + ALGORITHM, + SIZE, + check_nsec3_case, +) + + +def test_nsec3_case(ns3): + # Get test parameters. + params = { + "zone": "nsec3-fails-to-load.kasp", + "policy": "nsec3", + "key-properties": [ + f"csk 0 {ALGORITHM} {SIZE} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", + ], + } + zone = params["zone"] + + # nsec3-fails-to-load.kasp. fails to load (should be fixed after reload). + zone = "nsec3-fails-to-load.kasp" + with ns3.watch_log_from_start() as watcher: + watcher.wait_for_line(f"zone {zone}/IN (unsigned): not loaded due to errors.") + + shutil.copyfile(f"{ns3.identifier}/template.db.in", f"{ns3.identifier}/{zone}.db") + ns3.rndc(f"reload {zone}") + + # First make sure the zone is properly signed. + isctest.kasp.wait_keymgr_done(ns3, zone) + + # Test case. + check_nsec3_case(ns3, params) diff --git a/bin/tests/system/nsec3/tests_nsec3_restart.py b/bin/tests/system/nsec3/tests_nsec3_restart.py new file mode 100644 index 0000000000..9415040eea --- /dev/null +++ b/bin/tests/system/nsec3/tests_nsec3_restart.py @@ -0,0 +1,119 @@ +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +# pylint: disable=redefined-outer-name,unused-import + +import os + +import dns.update +import pytest + +pytest.importorskip("dns", minversion="2.0.0") +import isctest +import isctest.mark +from nsec3.common import ( + ALGORITHM, + SIZE, + default_config, + pytestmark, + check_auth_nsec3, + check_nsec3param, +) + + +def perform_nsec3_tests(server, params): + # Get test parameters. + zone = params["zone"] + fqdn = f"{zone}." + policy = params["policy"] + keydir = server.identifier + config = default_config + ttl = int(config.get("dnskey-ttl", 3600).total_seconds()) + minimum = params.get("soa-minimum", 3600) + expected = isctest.kasp.policy_to_properties(ttl=ttl, keys=params["key-properties"]) + + iterations = 0 + optout = 0 + saltlen = 0 + if "nsec3param" in params: + optout = params["nsec3param"].get("optout", 0) + saltlen = params["nsec3param"].get("salt-length", 0) + + match = f"{fqdn} {minimum} IN NSEC3PARAM 1 0 {iterations}" + + # Test case. + isctest.log.info(f"check nsec3 case zone {zone} policy {policy}") + + # First make sure the zone is properly signed. + isctest.kasp.wait_keymgr_done(server, zone) + + keys = isctest.kasp.keydir_to_keylist(zone, keydir) + isctest.kasp.check_keys(zone, keys, expected) + isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_apex(server, zone, keys, []) + + query = isctest.query.create(fqdn, dns.rdatatype.NSEC3PARAM) + response = isctest.query.tcp(query, server.ip) + assert response.rcode() == dns.rcode.NOERROR + + salt = check_nsec3param(response, match, saltlen) + + query = isctest.query.create(f"nosuchname.{fqdn}", dns.rdatatype.A) + response = isctest.query.tcp(query, server.ip) + assert response.rcode() == dns.rcode.NXDOMAIN + check_auth_nsec3(response, iterations, optout, salt) + + return salt + + +@pytest.mark.parametrize( + "params", + [ + pytest.param( + { + "zone": "nsec3.kasp", + "policy": "nsec3", + "key-properties": [ + f"csk 0 {ALGORITHM} {SIZE} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", + ], + }, + id="nsec3.kasp", + ), + pytest.param( + { + "zone": "nsec3-other.kasp", + "policy": "nsec3-other", + "nsec3param": { + "optout": 1, + "salt-length": 8, + }, + "key-properties": [ + f"csk 0 {ALGORITHM} {SIZE} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", + ], + }, + id="nsec3-other.kasp", + ), + ], +) +def test_nsec3_case(ns3, params): + zone = params["zone"] + salt = perform_nsec3_tests(ns3, params) + + # Test NSEC3 and NSEC3PARAM is the same after restart + isctest.log.info(f"check zone {zone} after restart has salt {salt}") + prevsalt = salt + + # Restart named, NSEC3 should stay the same. + ns3.stop() + ns3.start(["--noclean", "--restart", "--port", os.environ["PORT"]]) + + salt = perform_nsec3_tests(ns3, params) + assert prevsalt == salt