diff --git a/bin/tests/system/rpzextra/clean.sh b/bin/tests/system/rpzextra/clean.sh index def4d72678..928ee8ba87 100644 --- a/bin/tests/system/rpzextra/clean.sh +++ b/bin/tests/system/rpzextra/clean.sh @@ -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 index 224064d64f..0000000000 --- a/bin/tests/system/rpzextra/ns1/named.conf.in +++ /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 index 0000000000..1fb720cc7b --- /dev/null +++ b/bin/tests/system/rpzextra/ns2/gooddomain.db @@ -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 diff --git a/bin/tests/system/rpzextra/ns2/named.conf.in b/bin/tests/system/rpzextra/ns2/named.conf.in index 17295efc01..6317563dc9 100644 --- a/bin/tests/system/rpzextra/ns2/named.conf.in +++ b/bin/tests/system/rpzextra/ns2/named.conf.in @@ -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 index 0000000000..b3ab69ee6d --- /dev/null +++ b/bin/tests/system/rpzextra/ns2/rpz-external.local.db @@ -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 index 0000000000..aad6b89dc6 --- /dev/null +++ b/bin/tests/system/rpzextra/ns3/external-rpz.local.db @@ -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/ns1/rpz.local.db b/bin/tests/system/rpzextra/ns3/first-rpz.local.db similarity index 100% rename from bin/tests/system/rpzextra/ns1/rpz.local.db rename to bin/tests/system/rpzextra/ns3/first-rpz.local.db 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 index 0000000000..471030c3d9 --- /dev/null +++ b/bin/tests/system/rpzextra/ns3/fourth-rpz-extra.local.db @@ -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/ns1/named.args b/bin/tests/system/rpzextra/ns3/named.args similarity index 100% rename from bin/tests/system/rpzextra/ns1/named.args rename to bin/tests/system/rpzextra/ns3/named.args diff --git a/bin/tests/system/rpzextra/ns3/named.conf.in b/bin/tests/system/rpzextra/ns3/named.conf.in new file mode 100644 index 0000000000..cd459bcda6 --- /dev/null +++ b/bin/tests/system/rpzextra/ns3/named.conf.in @@ -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"; + }; +}; diff --git a/bin/tests/system/rpzextra/ns1/root.db b/bin/tests/system/rpzextra/ns3/root.db similarity index 92% rename from bin/tests/system/rpzextra/ns1/root.db rename to bin/tests/system/rpzextra/ns3/root.db index dde42dfe7e..ca499888b1 100644 --- a/bin/tests/system/rpzextra/ns1/root.db +++ b/bin/tests/system/rpzextra/ns3/root.db @@ -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 index 0000000000..a8b46faac1 --- /dev/null +++ b/bin/tests/system/rpzextra/ns3/third-rpz-extra.local.db @@ -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. diff --git a/bin/tests/system/rpzextra/setup.sh b/bin/tests/system/rpzextra/setup.sh index 28a4719e70..2dbb388f72 100644 --- a/bin/tests/system/rpzextra/setup.sh +++ b/bin/tests/system/rpzextra/setup.sh @@ -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 index 0000000000..d39eb2cf5c --- /dev/null +++ b/bin/tests/system/rpzextra/tests_rpz_multiple_views.py @@ -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") diff --git a/bin/tests/system/rpzextra/tests_rpz_passthru_logging.py b/bin/tests/system/rpzextra/tests_rpz_passthru_logging.py index 43715e197a..65cd3c5b10 100755 --- a/bin/tests/system/rpzextra/tests_rpz_passthru_logging.py +++ b/bin/tests/system/rpzextra/tests_rpz_passthru_logging.py @@ -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)