From: Matthijs Mekking Date: Fri, 5 Dec 2025 16:01:00 +0000 (+0100) Subject: Add NSEC3 optout large delegation zone test case X-Git-Tag: v9.21.17~41^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e704bbb5922b5317f362129b1ea9e768c8021a9;p=thirdparty%2Fbind9.git Add NSEC3 optout large delegation zone test case This test signs a large delegation with mostly insecure delegations with NSEC3 optout. Once the NSEC3PARAM record is published, run dnssec-verify to ensure the zone is correctly signed. --- diff --git a/bin/tests/system/optout/ns2/controls.conf.j2 b/bin/tests/system/optout/ns2/controls.conf.j2 new file mode 120000 index 00000000000..f1371a044e1 --- /dev/null +++ b/bin/tests/system/optout/ns2/controls.conf.j2 @@ -0,0 +1 @@ +../../_common/controls.conf.in \ No newline at end of file diff --git a/bin/tests/system/optout/ns2/named.conf.j2 b/bin/tests/system/optout/ns2/named.conf.j2 new file mode 100644 index 00000000000..4d9aed3ed02 --- /dev/null +++ b/bin/tests/system/optout/ns2/named.conf.j2 @@ -0,0 +1,41 @@ +/* + * 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. + */ + +options { + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.2; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + dnssec-validation no; + ixfr-from-differences yes; + sig-signing-nodes 900; + sig-signing-signatures 900; +}; + +include "controls.conf"; + +dnssec-policy "optout" { + keys { + csk lifetime unlimited algorithm ecdsa256; + }; + nsec3param iterations 0 optout yes salt-length 0; +}; + +zone "test" { + type primary; + file "test.db"; + dnssec-policy "optout"; + inline-signing yes; +}; diff --git a/bin/tests/system/optout/ns2/test.db b/bin/tests/system/optout/ns2/test.db new file mode 100644 index 00000000000..d3a930229f1 --- /dev/null +++ b/bin/tests/system/optout/ns2/test.db @@ -0,0 +1,22 @@ +; 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. + +$TTL 3600 +@ IN SOA ns2.test. hostmaster.test. 1 7200 3600 24796800 3600 + IN NS ns2 + +ns2 IN A 10.53.0.2 + +a IN A 127.0.0.1 + +$GENERATE 1-50000 child$ IN NS ns.example. + +child303 IN DS 7250 13 2 A30B3F78B6DDE9A4A9A2AD0C805518B4F49EC62E7D3F4531D33DE697 CDA01CB2 diff --git a/bin/tests/system/optout/setup.sh b/bin/tests/system/optout/setup.sh new file mode 100644 index 00000000000..bb08b9c092a --- /dev/null +++ b/bin/tests/system/optout/setup.sh @@ -0,0 +1,14 @@ +#!/bin/sh -e + +# 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. + +. ../conf.sh diff --git a/bin/tests/system/optout/tests_optout.py b/bin/tests/system/optout/tests_optout.py new file mode 100755 index 00000000000..67628c20e89 --- /dev/null +++ b/bin/tests/system/optout/tests_optout.py @@ -0,0 +1,108 @@ +#!/usr/bin/python3 + +# 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. + + +import os +import re +import sys + +import isctest +import pytest + +pytest.importorskip("dns", minversion="2.0.0") +import dns.exception +import dns.message +import dns.name +import dns.query +import dns.rcode +import dns.rdataclass +import dns.rdatatype + + +pytestmark = [ + pytest.mark.skipif( + sys.version_info < (3, 7), reason="Python >= 3.7 required [GL #3001]" + ), + pytest.mark.extra_artifacts( + [ + "*.out", + "ns2/*.infile", + "ns2/*.signed", + "ns2/*.jnl", + "ns2/*.jbk", + "ns2/controls.conf", + "ns2/dsset-*", + "ns2/K*", + ] + ), +] + + +def has_nsec3param(zone, response): + match = rf"{re.escape(zone)}\.\s+\d+\s+IN\s+NSEC3PARAM\s+1\s+0\s+0\s+-" + + for rr in response.answer: + if re.search(match, rr.to_text()): + return True + + return False + + +def do_query(server, qname, qtype, tcp=False): + msg = isctest.query.create(qname, qtype) + query_func = isctest.query.tcp if tcp else isctest.query.udp + response = query_func(msg, server.ip, expected_rcode=dns.rcode.NOERROR) + return response + + +def do_xfr(server, qname): + xfr = dns.zone.Zone(origin=f"{qname}.", relativize=False) + dns.query.inbound_xfr( + where=server.ip, txn_manager=xfr, port=int(os.environ["PORT"]) + ) + return xfr + + +def verify_zone(zone, transfer): + verify = os.getenv("VERIFY") + assert verify is not None + + filename = f"{zone}.out" + with open(filename, "w", encoding="utf-8") as file: + file.write(transfer.to_text()) + + # dnssec-verify command with default arguments. + verify_cmd = [verify, "-z", "-o", zone, filename] + + verifier = isctest.run.cmd(verify_cmd) + + if verifier.rc != 0: + isctest.log.error(f"dnssec-verify {zone} failed") + + return verifier.rc == 0 + + +def test_optout(ns2): + zone = "test" + + # Wait until the provided zone is signed and then verify its DNSSEC data. + def check_nsec3param(): + response = do_query(ns2, zone, "NSEC3PARAM") + return has_nsec3param(zone, response) + + # check zone is fully signed. + isctest.run.retry_with_timeout(check_nsec3param, timeout=300) + + # check if zone if DNSSEC valid. + transfer = do_xfr(ns2, zone) + assert verify_zone(zone, transfer)