]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add system test for the chase DS fix
authorColin Vidal <colin@isc.org>
Wed, 15 Apr 2026 12:00:06 +0000 (14:00 +0200)
committerOndřej Surý <ondrej@isc.org>
Thu, 16 Apr 2026 10:34:52 +0000 (12:34 +0200)
Add a system test which ensures, whenever the DS record can't be found
in the local cache, that the resolver first tries to get the parent NS
from the delegation cache to ask them the DS record, directly, rather
than running the fallback flow where the resolver attempts to query the
DS record from NS of the validating name (which would fails, then the
resolver would remove one label and fetch again, fails, and so on until
it reach the closest zonecut).

The test relies on the fact that when the fallback flow is run, the
`rctx_chaseds()` function is run, adding the "chase DS servers ..." and
"suspending DS lookup to find parent's..." logs.

bin/tests/system/chase_ds/ns1/named.conf.j2 [new file with mode: 0644]
bin/tests/system/chase_ds/ns1/root.db.in [new file with mode: 0644]
bin/tests/system/chase_ds/ns1/sign.sh [new file with mode: 0644]
bin/tests/system/chase_ds/ns2/example.db.in [new file with mode: 0644]
bin/tests/system/chase_ds/ns2/named.conf.j2 [new file with mode: 0644]
bin/tests/system/chase_ds/ns2/sign.sh [new file with mode: 0644]
bin/tests/system/chase_ds/ns3/named.conf.j2 [new file with mode: 0644]
bin/tests/system/chase_ds/setup.sh [new file with mode: 0644]
bin/tests/system/chase_ds/tests_chase_ds.py [new file with mode: 0644]

diff --git a/bin/tests/system/chase_ds/ns1/named.conf.j2 b/bin/tests/system/chase_ds/ns1/named.conf.j2
new file mode 100644 (file)
index 0000000..7c45a46
--- /dev/null
@@ -0,0 +1,19 @@
+options {
+       query-source address 10.53.0.1;
+       notify-source 10.53.0.1;
+       transfer-source 10.53.0.1;
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.1; };
+       listen-on-v6 { none; };
+       recursion no;
+       notify yes;
+       dnssec-validation yes;
+};
+
+zone "." {
+       type primary;
+       file "root.db.signed";
+};
+
+include "trusted.conf";
diff --git a/bin/tests/system/chase_ds/ns1/root.db.in b/bin/tests/system/chase_ds/ns1/root.db.in
new file mode 100644 (file)
index 0000000..3f546f9
--- /dev/null
@@ -0,0 +1,13 @@
+$TTL 300
+.                      IN SOA  gson.nominum.com. a.root.servers.nil. (
+                               2000042100      ; serial
+                               600             ; refresh
+                               600             ; retry
+                               1200            ; expire
+                               600             ; minimum
+                               )
+.                      NS      a.root-servers.nil.
+a.root-servers.nil.    A       10.53.0.1
+
+example.               NS      ns.example.
+ns.example.            A       10.53.0.2
diff --git a/bin/tests/system/chase_ds/ns1/sign.sh b/bin/tests/system/chase_ds/ns1/sign.sh
new file mode 100644 (file)
index 0000000..0b1a38f
--- /dev/null
@@ -0,0 +1,46 @@
+#!/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.
+
+# shellcheck source=conf.sh
+. ../../conf.sh
+
+set -e
+
+zone=.
+infile=root.db.in
+zonefile=root.db
+
+(cd ../ns2 && $SHELL sign.sh)
+
+cp "../ns2/dsset-example." .
+
+keyname=$($KEYGEN -q -a "${DEFAULT_ALGORITHM}" -b "${DEFAULT_BITS}" $zone)
+
+cat "$infile" "$keyname.key" >"$zonefile"
+
+$SIGNER -P -g -o $zone $zonefile >/dev/null
+
+# Override the DS key with a way lower TTL (Also done from dsset-example. but
+# this seems to be ignored when signing the zone.)
+sed -E '/^example\./{
+    n
+    s/.*300[[:space:]]\+DS/ 2 DS/
+}' "$zonefile.signed" >"$zonefile.signed.tmp"
+mv "$zonefile.signed.tmp" "$zonefile.signed"
+
+# Configure the resolving server with a static key.
+keyfile_to_static_ds "$keyname" >trusted.conf
+cp trusted.conf ../ns3/trusted.conf
+
+# ...or with an initializing key.
+keyfile_to_initial_ds "$keyname" >managed.conf
diff --git a/bin/tests/system/chase_ds/ns2/example.db.in b/bin/tests/system/chase_ds/ns2/example.db.in
new file mode 100644 (file)
index 0000000..9240abd
--- /dev/null
@@ -0,0 +1,12 @@
+$TTL 300
+@                      IN SOA  mname1. . (
+                               2000042407 ; serial
+                               20         ; refresh (20 seconds)
+                               20         ; retry (20 seconds)
+                               1814400    ; expire (3 weeks)
+                               3600       ; minimum (1 hour)
+                               )
+                       NS      ns
+ns                     A       10.53.0.2
+
+a 2    IN              A       10.0.0.1
diff --git a/bin/tests/system/chase_ds/ns2/named.conf.j2 b/bin/tests/system/chase_ds/ns2/named.conf.j2
new file mode 100644 (file)
index 0000000..55036d2
--- /dev/null
@@ -0,0 +1,17 @@
+options {
+       query-source address 10.53.0.2;
+       notify-source 10.53.0.2;
+       transfer-source 10.53.0.2;
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.2; };
+       listen-on-v6 { none; };
+       recursion no;
+       notify yes;
+};
+
+zone "example" {
+       type primary;
+       file "example.db.signed";
+       allow-update { any; };
+};
diff --git a/bin/tests/system/chase_ds/ns2/sign.sh b/bin/tests/system/chase_ds/ns2/sign.sh
new file mode 100644 (file)
index 0000000..e294bf0
--- /dev/null
@@ -0,0 +1,35 @@
+#!/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.
+
+# shellcheck source=conf.sh
+. ../../conf.sh
+
+set -e
+
+zone=example.
+infile=example.db.in
+zonefile=example.db
+
+keyname1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone")
+keyname2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone")
+
+cat "$infile" "$keyname1.key" "$keyname2.key" >"$zonefile"
+
+"$SIGNER" -P -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" >/dev/null
+
+# Override the DS key with a way lower TTL
+"$DSFROMKEY" -T 2 "$keyname1.key" >"dsset-$zone"
+
+# Override the DNSKEY with a way lower TTL
+sed -E 's/.*300[[:space:]]+DNSKEY/ 2 DNSKEY/' "$zonefile.signed" >"$zonefile.signed.tmp"
+mv "$zonefile.signed.tmp" "$zonefile.signed"
diff --git a/bin/tests/system/chase_ds/ns3/named.conf.j2 b/bin/tests/system/chase_ds/ns3/named.conf.j2
new file mode 100644 (file)
index 0000000..6cca441
--- /dev/null
@@ -0,0 +1,27 @@
+options {
+       query-source address 10.53.0.3;
+       notify-source 10.53.0.3;
+       transfer-source 10.53.0.3;
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.3; };
+       listen-on-v6 { none; };
+       recursion yes;
+       dnssec-validation yes;
+};
+
+zone "." {
+       type hint;
+       file "../../_common/root.hint";
+};
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+       inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+include "trusted.conf";
diff --git a/bin/tests/system/chase_ds/setup.sh b/bin/tests/system/chase_ds/setup.sh
new file mode 100644 (file)
index 0000000..a2d4aed
--- /dev/null
@@ -0,0 +1,19 @@
+#!/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.
+
+# shellcheck source=conf.sh
+. ../conf.sh
+
+set -e
+
+cd ns1 && $SHELL sign.sh && cd ..
diff --git a/bin/tests/system/chase_ds/tests_chase_ds.py b/bin/tests/system/chase_ds/tests_chase_ds.py
new file mode 100644 (file)
index 0000000..5c6f04e
--- /dev/null
@@ -0,0 +1,36 @@
+# 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 time
+
+import isctest
+
+
+def test_chase_ds(ns3):
+    msg = isctest.query.create("a.example.", "A")
+    res = isctest.query.udp(msg, ns3.ip)
+    isctest.check.noerror(res)
+
+    # Wait for example./DS and example./DNSKEY to expire
+    time.sleep(5)
+
+    msg = isctest.query.create("a.example.", "A")
+    res = isctest.query.udp(msg, ns3.ip)
+    isctest.check.noerror(res)
+
+    # The validator `get_dsset()` function found example. parent NS
+    # (which is./NS) using `dns_view_bestzonecut()`, so there is no
+    # need to chase the DS starting form `example./NS`).
+    prohibited_log = "chase DS servers resolving 'example/DS/IN'"
+    assert prohibited_log not in ns3.log
+
+    prohibited_log = "suspending DS lookup to find parent's NS records"
+    assert prohibited_log not in ns3.log