Add a new system test directory for DNSSEC tests written in Python,
using the isctest.zone helpers for zone setup rather than shell sign
scripts.
Set up four nameservers:
- ns1: authoritative for the signed root zone
- ns2: authoritative for test zones (primary)
- ns3: authoritative for additional test zones (typically delegations)
- ns9: validating resolver
Zone configuration for ns2 and ns3 is driven by the ``zones`` template
variable via _common/zones.conf.j2, so each test module's bootstrap()
controls which zones those servers load without touching named.conf.
Individual test modules will be added in subsequent commits.
Assisted-by: Claude:claude-opus-4-8
(cherry picked from commit
7ff0321ffac6344e87216903163c5703d5a21dbc)
--- /dev/null
+# 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 pytest
+
+DNSSEC_PY_MARK = pytest.mark.extra_artifacts(
+ [
+ "ns*/dsset-*",
+ "ns*/trusted.conf",
+ ]
+)
--- /dev/null
+// NS1
+
+options {
+ query-source address @ns.ip@;
+ notify-source @ns.ip@;
+ transfer-source @ns.ip@;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { @ns.ip@; };
+ listen-on-v6 { none; };
+
+ key-directory "keys";
+
+ minimal-any no;
+ minimal-responses no;
+ recursion no;
+
+ dnssec-validation yes;
+};
+
+{% include "_common/controls.conf.j2" %}
+{% include "_common/trusted.conf.j2" %}
+
+{% include "_common/zones.conf.j2" %}
--- /dev/null
+// NS2
+
+options {
+ query-source address @ns.ip@;
+ notify-source @ns.ip@;
+ transfer-source @ns.ip@;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { @ns.ip@; };
+ listen-on-v6 { none; };
+
+ key-directory "keys";
+
+ minimal-any no;
+ minimal-responses no;
+ recursion no;
+
+ dnssec-validation yes;
+
+{% if rrset_order_none is defined %}
+ rrset-order {
+ /* Keep the RRset order static in responses for zones that depend on it. */
+{% for name in rrset_order_none %}
+ name "@name@." order none;
+{% endfor %}
+ };
+{% endif %}
+};
+
+{% include "_common/controls.conf.j2" %}
+{% include "_common/trusted.conf.j2" %}
+{% include "_common/root.hint.conf" %}
+
+{% include "_common/zones.conf.j2" %}
--- /dev/null
+// NS3
+
+options {
+ query-source address @ns.ip@;
+ notify-source @ns.ip@;
+ transfer-source @ns.ip@;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { @ns.ip@; };
+ listen-on-v6 { none; };
+
+ key-directory "keys";
+
+ minimal-any no;
+ minimal-responses no;
+ recursion no;
+
+ dnssec-validation yes;
+};
+
+{% include "_common/controls.conf.j2" %}
+{% include "_common/trusted.conf.j2" %}
+{% include "_common/root.hint.conf" %}
+
+{% include "_common/zones.conf.j2" %}
--- /dev/null
+// NS 9
+
+{% set max_validations_per_fetch = max_validations_per_fetch | default(16) %}
+
+options {
+ query-source address @ns.ip@;
+ notify-source @ns.ip@;
+ transfer-source @ns.ip@;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { @ns.ip@; };
+ listen-on-v6 { none; };
+
+ recursion yes;
+
+ dnssec-validation yes;
+
+ max-validations-per-fetch @max_validations_per_fetch@;
+};
+
+{% include "_common/controls.conf.j2" %}
+{% include "_common/trusted.conf.j2" %}
+{% include "_common/root.hint.conf" %}
+
+{% include "_common/zones.conf.j2" %}