]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add test for RPZ in multiple views
authorOndřej Surý <ondrej@isc.org>
Wed, 22 Mar 2023 14:11:17 +0000 (15:11 +0100)
committerOndřej Surý <ondrej@isc.org>
Tue, 4 Apr 2023 14:27:46 +0000 (16:27 +0200)
This adds rudimentary test for response-policy zones in multiple
views.  Different combinations are tested:

- two views with response-policy inherited from options {};
- two views view explicit response-policy using same RPZ zone name
- two views view explicit response-policy using secondary RPZ zone

(cherry picked from commit 1649c768e94a3774fe66d35387c6b208f2bc0ed1)

15 files changed:
bin/tests/system/rpzextra/clean.sh
bin/tests/system/rpzextra/ns1/named.conf.in [deleted file]
bin/tests/system/rpzextra/ns2/gooddomain.db [new file with mode: 0644]
bin/tests/system/rpzextra/ns2/named.conf.in
bin/tests/system/rpzextra/ns2/rpz-external.local.db [new file with mode: 0644]
bin/tests/system/rpzextra/ns3/external-rpz.local.db [new file with mode: 0644]
bin/tests/system/rpzextra/ns3/first-rpz.local.db [moved from bin/tests/system/rpzextra/ns1/rpz.local.db with 100% similarity]
bin/tests/system/rpzextra/ns3/fourth-rpz-extra.local.db [new file with mode: 0644]
bin/tests/system/rpzextra/ns3/named.args [moved from bin/tests/system/rpzextra/ns1/named.args with 100% similarity]
bin/tests/system/rpzextra/ns3/named.conf.in [new file with mode: 0644]
bin/tests/system/rpzextra/ns3/root.db [moved from bin/tests/system/rpzextra/ns1/root.db with 92% similarity]
bin/tests/system/rpzextra/ns3/third-rpz-extra.local.db [new file with mode: 0644]
bin/tests/system/rpzextra/setup.sh
bin/tests/system/rpzextra/tests_rpz_multiple_views.py [new file with mode: 0644]
bin/tests/system/rpzextra/tests_rpz_passthru_logging.py

index def4d72678b441573184ddc5e2ae61636ababd5d..928ee8ba87d8efb7e6d368624a4475859c20c633 100644 (file)
@@ -18,3 +18,4 @@ rm -f ns*/named.memstats
 rm -f ns*/named.run
 rm -f ns*/rpz*.txt
 rm -rf __pycache__
+rm -f ns3/*-rpz-external.local.db
diff --git a/bin/tests/system/rpzextra/ns1/named.conf.in b/bin/tests/system/rpzextra/ns1/named.conf.in
deleted file mode 100644 (file)
index 202ffa7..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.
- */
-
-key rndc_key {
-    secret "1234abcd8765";
-       algorithm @DEFAULT_HMAC@;
-};
-
-controls {
-       inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
-};
-
-options {
-       query-source address 10.53.0.1;
-       notify-source 10.53.0.1;
-       transfer-source 10.53.0.1;
-       port @PORT@;
-       listen-on { 10.53.0.1; };
-       pid-file "named.pid";
-       notify no;
-       dnssec-validation no;
-       allow-query { any; };
-       recursion yes;
-       allow-recursion { any; };
-
-       response-policy {
-               zone "rpz.local";
-       };
-};
-
-logging {
-     channel rpz_passthru {
-          file "rpz_passthru.txt" versions 3 size 5m;
-          print-time yes;
-          print-category yes;
-          print-severity yes;
-          severity info;
-     };
-
-     channel rpz_log {
-          file "rpz.txt" versions 3 size 20m;
-          print-time yes;
-          print-category yes;
-          print-severity yes;
-          severity info;
-     };
-
-     category rpz { rpz_log; default_debug; };
-        category rpz-passthru { rpz_passthru; default_debug; };
-};
-
-zone "rpz.local" {
-    type primary;
-    file "rpz.local.db";
-    allow-transfer { none; };
-    allow-query { localhost; };
-};
-
-zone "." {
-       type hint;
-       file "root.db";
-};
-
-
diff --git a/bin/tests/system/rpzextra/ns2/gooddomain.db b/bin/tests/system/rpzextra/ns2/gooddomain.db
new file mode 100644 (file)
index 0000000..1fb720c
--- /dev/null
@@ -0,0 +1,27 @@
+; 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 300
+
+@      IN      SOA ns1 root.gooddomain. (
+       2020040101
+       4h
+       1h
+       1w
+       60
+)
+
+            IN NS    ns1
+
+ns1         IN A     10.53.0.2
+
+gooddomain. IN A     10.53.0.2
+www         IN A     10.53.0.3
index 17295efc01f5eff7129beddb6a69bc08453024d4..6317563dc9921d961be7f27e94cc8c5f0671adf9 100644 (file)
@@ -44,3 +44,14 @@ zone "baddomain" {
     allow-transfer { none; };
 };
 
+zone "gooddomain" {
+    type primary;
+    file "gooddomain.db";
+    allow-transfer { none; };
+};
+
+zone "rpz-external.local" {
+    type primary;
+    file "rpz-external.local.db";
+    allow-transfer { any; };
+};
diff --git a/bin/tests/system/rpzextra/ns2/rpz-external.local.db b/bin/tests/system/rpzextra/ns2/rpz-external.local.db
new file mode 100644 (file)
index 0000000..b3ab69e
--- /dev/null
@@ -0,0 +1,26 @@
+; 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 300
+
+@      IN      SOA     localhost.rpz-external.local root.rpz-external.local. (
+       2020022500      ; serial number
+       60                      ; refresh every minute
+       60                      ; retry every minute
+       432000          ; expire in 5 days
+       60                      ; negative caching ttl, 1 minute
+)
+
+
+                IN     NS      LOCALHOST.
+
+allowed       IN       CNAME   .
+*.allowed     IN       CNAME   .
diff --git a/bin/tests/system/rpzextra/ns3/external-rpz.local.db b/bin/tests/system/rpzextra/ns3/external-rpz.local.db
new file mode 100644 (file)
index 0000000..aad6b89
--- /dev/null
@@ -0,0 +1,29 @@
+; 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 300
+
+@      IN      SOA     localhost.rpz.local root.rpz.local. (
+       2020022500      ; serial number
+       60                      ; refresh every minute
+       60                      ; retry every minute
+       432000          ; expire in 5 days
+       60                      ; negative caching ttl, 1 minute
+)
+
+
+              IN       NS      LOCALHOST.
+
+allowed       IN       CNAME   rpz-passthru.
+*.allowed     IN       CNAME   rpz-passthru.
+
+gooddomain     IN      CNAME   .
+*.gooddomain   IN      CNAME   .
diff --git a/bin/tests/system/rpzextra/ns3/fourth-rpz-extra.local.db b/bin/tests/system/rpzextra/ns3/fourth-rpz-extra.local.db
new file mode 100644 (file)
index 0000000..471030c
--- /dev/null
@@ -0,0 +1,32 @@
+; 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 300
+
+@      IN      SOA     localhost.rpz-extra.local root.rpz-extra.local. (
+       2020022500      ; serial number
+       60                      ; refresh every minute
+       60                      ; retry every minute
+       432000          ; expire in 5 days
+       60                      ; negative caching ttl, 1 minute
+)
+
+
+                IN     NS      LOCALHOST.
+
+allowed       IN       CNAME   rpz-passthru.
+*.allowed     IN       CNAME   rpz-passthru.
+
+gooddomain     IN      CNAME   .
+*.gooddomain   IN      CNAME   .
+
+baddomain     IN       CNAME   .
+*.baddomain   IN       CNAME   .
diff --git a/bin/tests/system/rpzextra/ns3/named.conf.in b/bin/tests/system/rpzextra/ns3/named.conf.in
new file mode 100644 (file)
index 0000000..cd459bc
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+key rndc_key {
+    secret "1234abcd8765";
+       algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+       inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+       query-source address 10.53.0.3;
+       notify-source 10.53.0.3;
+       transfer-source 10.53.0.3;
+       port @PORT@;
+       listen-on { 10.53.0.3; };
+       pid-file "named.pid";
+       notify no;
+       dnssec-validation no;
+       allow-query { any; };
+       recursion yes;
+       allow-recursion { any; };
+       empty-zones-enable false;
+       response-policy {
+               zone "rpz-extra.local";
+       };
+};
+
+logging {
+       channel rpz_passthru {
+               file "rpz_passthru.txt" versions 3 size 5m;
+               print-time yes;
+               print-category yes;
+               print-severity yes;
+               severity info;
+       };
+
+       channel rpz_log {
+               file "rpz.txt" versions 3 size 20m;
+               print-time yes;
+               print-category yes;
+               print-severity yes;
+               severity info;
+       };
+
+       category rpz { rpz_log; default_debug; };
+       category rpz-passthru { rpz_passthru; default_debug; };
+};
+
+view "first" {
+       match-clients { 10.53.0.1; };
+       zone "." {
+               type hint;
+               file "root.db";
+       };
+       zone "rpz.local" {
+               type primary;
+               file "first-rpz.local.db";
+               allow-transfer { none; };
+               allow-query { localhost; };
+       };
+       response-policy {
+               zone "rpz.local";
+       };
+};
+
+view "second" {
+       match-clients { 10.53.0.2; };
+       zone "." {
+               type hint;
+               file "root.db";
+       };
+       zone "rpz-external.local" {
+               type secondary;
+               primaries { 10.53.0.2; };
+               file "second-rpz-external.local.db";
+               allow-query { 10.53.0.2; };
+       };
+       response-policy {
+               zone "rpz-external.local";
+       };
+};
+
+view "third" {
+       match-clients { 10.53.0.3; };
+       zone "." {
+               type hint;
+               file "root.db";
+       };
+       zone "rpz-extra.local" {
+               type primary;
+               file "third-rpz-extra.local.db";
+               allow-transfer { none; };
+               allow-query { localhost; };
+       };
+};
+
+view "fourth" {
+       match-clients { 10.53.0.4; };
+       zone "." {
+               type hint;
+               file "root.db";
+       };
+       zone "rpz-extra.local" {
+               type primary;
+               file "fourth-rpz-extra.local.db";
+               allow-transfer { none; };
+               allow-query { localhost; };
+       };
+};
+
+view "external" {
+       match-clients { any; };
+       zone "." {
+               type hint;
+               file "root.db";
+       };
+       zone "rpz.local" {
+               type primary;
+               file "external-rpz.local.db";
+               allow-transfer { none; };
+               allow-query { localhost; };
+       };
+       zone "rpz-external.local" {
+               type secondary;
+               masterfile-format text;
+               primaries { 10.53.0.2; };
+               file "external-rpz-external.local.db";
+               allow-query { 10.53.0.5; };
+       };
+       response-policy {
+               zone "rpz-external.local";
+               zone "rpz.local";
+       };
+};
similarity index 92%
rename from bin/tests/system/rpzextra/ns1/root.db
rename to bin/tests/system/rpzextra/ns3/root.db
index dde42dfe7e0f8b8d12ab0a28922d409994bc7265..ca499888b1c2b2abb48cb9646e8aa793e9745a2f 100644 (file)
@@ -25,3 +25,6 @@ ns1.allowed.  A       10.53.0.2
 
 baddomain.             NS      ns1.baddomain.
 ns1.baddomain. A       10.53.0.2
+
+gooddomain.            NS      ns1.gooddomain.
+ns1.gooddomain.        A       10.53.0.2
diff --git a/bin/tests/system/rpzextra/ns3/third-rpz-extra.local.db b/bin/tests/system/rpzextra/ns3/third-rpz-extra.local.db
new file mode 100644 (file)
index 0000000..a8b46fa
--- /dev/null
@@ -0,0 +1,26 @@
+; 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 300
+
+@      IN      SOA     localhost.rpz-extra.local root.rpz-extra.local. (
+       2020022500      ; serial number
+       60                      ; refresh every minute
+       60                      ; retry every minute
+       432000          ; expire in 5 days
+       60                      ; negative caching ttl, 1 minute
+)
+
+
+                IN     NS      LOCALHOST.
+
+allowed       IN       CNAME   rpz-passthru.
+*.allowed     IN       CNAME   rpz-passthru.
index 28a4719e70a6256c8d4cb2497d25ffb5a754562b..2dbb388f7224f5961394fcde81792afaa9239f33 100644 (file)
@@ -17,5 +17,5 @@ set -e
 
 . ../conf.sh
 
-copy_setports ns1/named.conf.in ns1/named.conf
 copy_setports ns2/named.conf.in ns2/named.conf
+copy_setports ns3/named.conf.in ns3/named.conf
diff --git a/bin/tests/system/rpzextra/tests_rpz_multiple_views.py b/bin/tests/system/rpzextra/tests_rpz_multiple_views.py
new file mode 100644 (file)
index 0000000..d39eb2c
--- /dev/null
@@ -0,0 +1,117 @@
+#!/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 time
+
+import pytest
+
+pytest.importorskip("dns")
+import dns.resolver
+
+
+def wait_for_transfer(ip, port, client_ip, name, rrtype):
+    resolver = dns.resolver.Resolver()
+    resolver.nameservers = [ip]
+    resolver.port = port
+
+    for _ in range(10):
+        try:
+            resolver.resolve(name, rrtype, source=client_ip)
+        except dns.resolver.NoNameservers:
+            time.sleep(1)
+        else:
+            break
+    else:
+        raise RuntimeError(
+            "zone transfer failed: "
+            f"client {client_ip} got NXDOMAIN for {name} {rrtype} from @{ip}:{port}")
+
+
+def test_rpz_multiple_views(named_port):
+    resolver = dns.resolver.Resolver()
+    resolver.nameservers = ["10.53.0.3"]
+    resolver.port = named_port
+
+    wait_for_transfer("10.53.0.3", named_port, "10.53.0.2", "rpz-external.local", "SOA")
+    wait_for_transfer("10.53.0.3", named_port, "10.53.0.5", "rpz-external.local", "SOA")
+
+    # For 10.53.0.1 source IP:
+    # - baddomain.com isn't allowed (CNAME .), should return NXDOMAIN
+    # - gooddomain.com is allowed
+    # - allowed. is allowed
+    with pytest.raises(dns.resolver.NXDOMAIN):
+        resolver.resolve("baddomain.", "A", source="10.53.0.1")
+
+    ans = resolver.resolve("gooddomain.", "A", source="10.53.0.1")
+    for rd in ans:
+        assert rd.address == "10.53.0.2"
+
+    ans = resolver.resolve("allowed.", "A", source="10.53.0.1")
+    assert ans[0].address == "10.53.0.2"
+
+    # For 10.53.0.2 source IP:
+    # - allowed.com isn't allowed (CNAME .), should return NXDOMAIN
+    # - baddomain.com is allowed
+    # - gooddomain.com is allowed
+    ans = resolver.resolve("baddomain.", "A", source="10.53.0.2")
+    for rd in ans:
+        assert rd.address == "10.53.0.2"
+
+    ans = resolver.resolve("gooddomain.", "A", source="10.53.0.2")
+    for rd in ans:
+        assert rd.address == "10.53.0.2"
+
+    with pytest.raises(dns.resolver.NXDOMAIN):
+        resolver.resolve("allowed.", "A", source="10.53.0.2")
+
+    # For 10.53.0.3 source IP:
+    # - gooddomain.com is allowed
+    # - baddomain.com is allowed
+    # - allowed. is allowed
+    ans = resolver.resolve("baddomain.", "A", source="10.53.0.3")
+    for rd in ans:
+        assert rd.address == "10.53.0.2"
+
+    ans = resolver.resolve("gooddomain.", "A", source="10.53.0.3")
+    for rd in ans:
+        assert rd.address == "10.53.0.2"
+
+    ans = resolver.resolve("allowed.", "A", source="10.53.0.3")
+    assert ans[0].address == "10.53.0.2"
+
+    # For 10.53.0.4 source IP:
+    # - gooddomain.com isn't allowed (CNAME .), should return NXDOMAIN
+    # - baddomain.com isn't allowed (CNAME .), should return NXDOMAIN
+    # - allowed. is allowed
+    with pytest.raises(dns.resolver.NXDOMAIN):
+        resolver.resolve("baddomain.", "A", source="10.53.0.4")
+
+    with pytest.raises(dns.resolver.NXDOMAIN):
+        resolver.resolve("gooddomain.", "A", source="10.53.0.4")
+
+    ans = resolver.resolve("allowed.", "A", source="10.53.0.4")
+    assert ans[0].address == "10.53.0.2"
+
+    # For 10.53.0.5 (any) source IP:
+    # - baddomain.com is allowed
+    # - gooddomain.com isn't allowed (CNAME .), should return NXDOMAIN
+    # - allowed.com isn't allowed (CNAME .), should return NXDOMAIN
+    ans = resolver.resolve("baddomain.", "A", source="10.53.0.5")
+    for rd in ans:
+        assert rd.address == "10.53.0.2"
+
+    with pytest.raises(dns.resolver.NXDOMAIN):
+        resolver.resolve("gooddomain.", "A", source="10.53.0.5")
+
+    with pytest.raises(dns.resolver.NXDOMAIN):
+        resolver.resolve("allowed.", "A", source="10.53.0.5")
index 43715e197ab60358016687e2e570f1cc1be004a7..65cd3c5b1046a5490e4d6be5a8e571786fc66b74 100755 (executable)
@@ -21,7 +21,7 @@ import dns.resolver
 
 def test_rpz_passthru_logging(named_port):
     resolver = dns.resolver.Resolver()
-    resolver.nameservers = ["10.53.0.1"]
+    resolver.nameservers = ["10.53.0.3"]
     resolver.port = named_port
 
     # Should generate a log entry into rpz_passthru.txt
@@ -34,8 +34,8 @@ def test_rpz_passthru_logging(named_port):
     with pytest.raises(dns.resolver.NXDOMAIN):
         resolver.resolve("baddomain.", "A", source="10.53.0.1")
 
-    rpz_passthru_logfile = os.path.join("ns1", "rpz_passthru.txt")
-    rpz_logfile = os.path.join("ns1", "rpz.txt")
+    rpz_passthru_logfile = os.path.join("ns3", "rpz_passthru.txt")
+    rpz_logfile = os.path.join("ns3", "rpz.txt")
 
     assert os.path.isfile(rpz_passthru_logfile)
     assert os.path.isfile(rpz_logfile)