]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Test CHAOS view recursion behavior
authorEvan Hunt <each@isc.org>
Tue, 17 Mar 2026 20:45:11 +0000 (13:45 -0700)
committerMichał Kępień <michal@isc.org>
Thu, 7 May 2026 11:32:15 +0000 (13:32 +0200)
Check that recursive and forward queries to views of type CHAOS
are REFUSED, but that authoritative queries are answered correctly.

bin/tests/system/checkconf/tests.sh
bin/tests/system/checkconf/warn-chaos-recursion.conf [new file with mode: 0644]
bin/tests/system/class/ns1/chaos.db.in [new file with mode: 0644]
bin/tests/system/class/ns1/named.conf.j2 [new file with mode: 0644]
bin/tests/system/class/ns2/example.db.in [new file with mode: 0644]
bin/tests/system/class/ns2/localhost.db.in [new file with mode: 0644]
bin/tests/system/class/ns2/named.conf.j2 [new file with mode: 0644]
bin/tests/system/class/ns3/named.conf.j2 [new file with mode: 0644]
bin/tests/system/class/setup.sh [new file with mode: 0644]
bin/tests/system/class/tests_class_chaos.py [new file with mode: 0644]
bin/tests/system/isctest/check.py

index f927d789193bd26c0072d96a33a9b81988ba935f..330da510e3c84aadb7cbc31ae65eade53f67f732 100644 (file)
@@ -739,5 +739,16 @@ if [ $ret != 0 ]; then
 fi
 status=$((status + ret))
 
+n=$((n + 1))
+echo_i "check 'recursion yes;' is warned and disabled in a non-IN view ($n)"
+ret=0
+$CHECKCONF warn-chaos-recursion.conf >checkconf.out$n 2>&1 || ret=1
+grep -F "recursion will be disabled" checkconf.out$n >/dev/null || ret=1
+if [ $ret != 0 ]; then
+  echo_i "failed"
+  ret=1
+fi
+status=$((status + ret))
+
 echo_i "exit status: $status"
 [ $status -eq 0 ] || exit 1
diff --git a/bin/tests/system/checkconf/warn-chaos-recursion.conf b/bin/tests/system/checkconf/warn-chaos-recursion.conf
new file mode 100644 (file)
index 0000000..0196510
--- /dev/null
@@ -0,0 +1,12 @@
+options {
+       directory ".";
+};
+
+view chaos ch {
+        match-clients { any; };
+        recursion yes;
+        zone "." {
+                type hint;
+                file "chaos.hints";
+        };
+};
diff --git a/bin/tests/system/class/ns1/chaos.db.in b/bin/tests/system/class/ns1/chaos.db.in
new file mode 100644 (file)
index 0000000..43ca58f
--- /dev/null
@@ -0,0 +1,4 @@
+.                  CH NS ns.root.
+ns.root.           CH A ns.root. 1
+ns.root.           CH AAAA \# 1 00
+
diff --git a/bin/tests/system/class/ns1/named.conf.j2 b/bin/tests/system/class/ns1/named.conf.j2
new file mode 100644 (file)
index 0000000..76f85fc
--- /dev/null
@@ -0,0 +1,31 @@
+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; };
+};
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+       inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+view chaos ch {
+       match-clients { any; };
+       recursion yes;
+       zone "." {
+               type hint;
+               file "chaos.db";
+       };
+       zone "version.bind" {
+               type primary;
+               database "_builtin version";
+       };
+};
diff --git a/bin/tests/system/class/ns2/example.db.in b/bin/tests/system/class/ns2/example.db.in
new file mode 100644 (file)
index 0000000..a658ddb
--- /dev/null
@@ -0,0 +1,6 @@
+$TTL 300
+@ CH SOA ns.example. hostmaster.example. 1 3600 1200 604800 300
+@ CH NS ns.example.
+ns CH TXT "ns"
+a CH A target.example. 1
+target CH TXT "target"
diff --git a/bin/tests/system/class/ns2/localhost.db.in b/bin/tests/system/class/ns2/localhost.db.in
new file mode 100644 (file)
index 0000000..baa5f74
--- /dev/null
@@ -0,0 +1,6 @@
+$ORIGIN 1.0.0.127.in-addr.arpa.
+$TTL 300
+@ IN SOA ns hostmaster 1 3600 900 604800 300
+@ IN NS ns
+ns IN A 127.0.0.1
+@ IN KX 10 target.example.
diff --git a/bin/tests/system/class/ns2/named.conf.j2 b/bin/tests/system/class/ns2/named.conf.j2
new file mode 100644 (file)
index 0000000..5618c15
--- /dev/null
@@ -0,0 +1,42 @@
+options {
+       directory ".";
+       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; };
+};
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+       inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+view default {
+       match-clients { any; };
+       recursion no;
+        dnssec-validation no;
+       zone "1.0.0.127.in-addr.arpa." {
+               type primary;
+               file "localhost.db";
+               update-policy {
+                       grant * tcp-self . ANY;
+               };
+       };
+};
+
+view chaos ch {
+       match-clients { any; };
+       recursion no;
+       zone example {
+               type primary;
+               file "example.db";
+               allow-update { any; };
+       };
+};
diff --git a/bin/tests/system/class/ns3/named.conf.j2 b/bin/tests/system/class/ns3/named.conf.j2
new file mode 100644 (file)
index 0000000..3016333
--- /dev/null
@@ -0,0 +1,28 @@
+options {
+       directory ".";
+       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; };
+};
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+       inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+view chaos ch {
+       match-clients { any; };
+       recursion yes;
+        dnssec-validation no;
+        forward only;
+        forwarders port @PORT@ { 10.53.0.2; };
+        deny-answer-addresses { 0.0.0.0/0; ::/0; };
+};
diff --git a/bin/tests/system/class/setup.sh b/bin/tests/system/class/setup.sh
new file mode 100644 (file)
index 0000000..c70a2f8
--- /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
+
+cp ns1/chaos.db.in ns1/chaos.db
+cp ns2/example.db.in ns2/example.db
+cp ns2/localhost.db.in ns2/localhost.db
diff --git a/bin/tests/system/class/tests_class_chaos.py b/bin/tests/system/class/tests_class_chaos.py
new file mode 100644 (file)
index 0000000..5b4fef9
--- /dev/null
@@ -0,0 +1,54 @@
+# 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 dns.opcode
+import pytest
+
+import isctest
+
+pytestmark = pytest.mark.extra_artifacts(
+    [
+        "*/*.db",
+    ]
+)
+
+
+def test_chaos_recursion():
+    msg = isctest.query.create("foo.example.", "TXT", qclass="CH")
+    res = isctest.query.udp(msg, "10.53.0.1")
+    isctest.check.refused(res)
+
+
+def test_chaos_auth():
+    msg = isctest.query.create("a.example.", "A", qclass="CH")
+    res = isctest.query.udp(msg, "10.53.0.2")
+    isctest.check.noerror(res)
+
+
+def test_chaos_forward():
+    msg = isctest.query.create("a.example.", "A", qclass="CH")
+    res = isctest.query.udp(msg, "10.53.0.3")
+    isctest.check.refused(res)
+
+
+def test_chaos_notify():
+    msg = isctest.query.create("example.", "SOA", qclass="CH", rd=False, dnssec=False)
+    msg.set_opcode(dns.opcode.NOTIFY)
+    msg.flags = dns.opcode.to_flags(dns.opcode.NOTIFY)
+    res = isctest.query.udp(msg, "10.53.0.2")
+    isctest.check.notimp(res)
+
+
+def test_query_class_none():
+    msg = isctest.query.create("example.", "A", qclass="NONE")
+    res = isctest.query.udp(msg, "10.53.0.2")
+    isctest.check.formerr(res)
index 7c5e30c4e127206b8b6a5159a27dfb5b885dfeae..f723dd95c0859aaf72d96335ca5521c025bef4c1 100644 (file)
@@ -47,6 +47,10 @@ def servfail(message: dns.message.Message) -> None:
     rcode(message, dns.rcode.SERVFAIL)
 
 
+def formerr(message: dns.message.Message) -> None:
+    rcode(message, dns.rcode.FORMERR)
+
+
 def adflag(message: dns.message.Message) -> None:
     assert (message.flags & dns.flags.AD) != 0, str(message)