diff --git a/CHANGES b/CHANGES index 337903517d..1d188bfff5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +5406. [func] Added a new logging category "rpz-passthru". It allows + RPZ passthru actions to be logged into a separate + channel. [GL #54] + 5405. [bug] 'named-checkconf -p' could include spurious text in server-addresses statements due to an uninitialized DSCP value. [GL #1812] diff --git a/bin/tests/system/Makefile.am b/bin/tests/system/Makefile.am index c55c5305ed..c107e2853a 100644 --- a/bin/tests/system/Makefile.am +++ b/bin/tests/system/Makefile.am @@ -214,6 +214,10 @@ if HAVE_PKCS11 TESTS += pkcs11 endif +if HAVE_PYTEST +TESTS += rpzextra +endif + else !HAVE_PERL check: echo Perl is not available, no tests were ran diff --git a/bin/tests/system/rpzextra/clean.sh b/bin/tests/system/rpzextra/clean.sh new file mode 100644 index 0000000000..dc52e5e4a3 --- /dev/null +++ b/bin/tests/system/rpzextra/clean.sh @@ -0,0 +1,17 @@ +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# 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 http://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +rm -f ns*/*.jnl +rm -f ns*/named.conf +rm -f ns*/named.lock +rm -f ns*/named.memstats +rm -f ns*/named.run +rm -f ns*/rpz*.txt +rm -rf __pycache__ +rm -f *.status diff --git a/bin/tests/system/rpzextra/conftest.py b/bin/tests/system/rpzextra/conftest.py new file mode 100644 index 0000000000..6ccbbb999e --- /dev/null +++ b/bin/tests/system/rpzextra/conftest.py @@ -0,0 +1,54 @@ +############################################################################ +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# 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 http://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. +############################################################################ + +import os +import pytest + +try: + import dns.resolver # noqa: F401 # pylint: disable=unused-import +except ModuleNotFoundError: + dns_resolver_module_found = False +else: + dns_resolver_module_found = True + + +def pytest_configure(config): + config.addinivalue_line( + "markers", "dnspython: mark tests that need dnspython to function" + ) + + +def pytest_collection_modifyitems(config, items): + # pylint: disable=unused-argument + # Test for dnspython module + if not dns_resolver_module_found: + skip_requests = pytest.mark.skip(reason="need dnspython module to run") + for item in items: + if "dnspython" in item.keywords: + item.add_marker(skip_requests) + # Test if JSON statistics channel was enabled + no_jsonstats = pytest.mark.skip(reason="need JSON statistics to be enabled") + if os.getenv("HAVEJSONSTATS") is None: + for item in items: + if "json" in item.keywords: + item.add_marker(no_jsonstats) + + +@pytest.fixture +def named_port(request): + # pylint: disable=unused-argument + port = os.getenv("PORT") + if port is None: + port = 5301 + else: + port = int(port) + + return port diff --git a/bin/tests/system/rpzextra/ns1/named.args b/bin/tests/system/rpzextra/ns1/named.args new file mode 100644 index 0000000000..e4ae75e3aa --- /dev/null +++ b/bin/tests/system/rpzextra/ns1/named.args @@ -0,0 +1 @@ + -m record,size,mctx -c named.conf -d 99 -D rpzextra-ns1 -X named.lock -U 4 diff --git a/bin/tests/system/rpzextra/ns1/named.conf.in b/bin/tests/system/rpzextra/ns1/named.conf.in new file mode 100644 index 0000000000..23cbad05a8 --- /dev/null +++ b/bin/tests/system/rpzextra/ns1/named.conf.in @@ -0,0 +1,61 @@ +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +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 master; + file "rpz.local.db"; + allow-transfer { none; }; + allow-query { localhost; }; +}; + +zone "." { + type hint; + file "root.db"; +}; + + diff --git a/bin/tests/system/rpzextra/ns1/root.db b/bin/tests/system/rpzextra/ns1/root.db new file mode 100644 index 0000000000..c5b4550dee --- /dev/null +++ b/bin/tests/system/rpzextra/ns1/root.db @@ -0,0 +1,25 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; 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 http://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 300 +. IN SOA gson.nominum.com. a.root.servers.nil. ( + 2000042100 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +. NS ns1.allowed + + +allowed. NS ns1.allowed. +ns1.allowed. A 10.53.0.2 + +baddomain. NS ns1.baddomain. +ns1.baddomain. A 10.53.0.2 diff --git a/bin/tests/system/rpzextra/ns1/rpz.local.db b/bin/tests/system/rpzextra/ns1/rpz.local.db new file mode 100644 index 0000000000..9dcf5ce725 --- /dev/null +++ b/bin/tests/system/rpzextra/ns1/rpz.local.db @@ -0,0 +1,18 @@ +$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. + +baddomain IN CNAME . +*.baddomain IN CNAME . diff --git a/bin/tests/system/rpzextra/ns2/allowed.db b/bin/tests/system/rpzextra/ns2/allowed.db new file mode 100644 index 0000000000..17f45dceeb --- /dev/null +++ b/bin/tests/system/rpzextra/ns2/allowed.db @@ -0,0 +1,7 @@ +$TTL 300 + +@ IN SOA ns1 root.allowed. 2020040101 4h 1h 1w 60 +@ IN NS ns1 +ns1 IN A 10.53.0.2 +@ IN A 10.53.0.2 +www IN A 10.53.0.2 diff --git a/bin/tests/system/rpzextra/ns2/baddomain.db b/bin/tests/system/rpzextra/ns2/baddomain.db new file mode 100644 index 0000000000..c40bf3bfae --- /dev/null +++ b/bin/tests/system/rpzextra/ns2/baddomain.db @@ -0,0 +1,16 @@ +$TTL 300 + +@ IN SOA ns1 root.baddomain. ( + 2020040101 + 4h + 1h + 1w + 60 +) + + IN NS ns1 + +ns1 IN A 10.53.0.2 + +baddomain. 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 new file mode 100644 index 0000000000..7af2f69b5a --- /dev/null +++ b/bin/tests/system/rpzextra/ns2/named.conf.in @@ -0,0 +1,33 @@ +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +options { + query-source address 10.53.0.2; + notify-source 10.53.0.2; + transfer-source 10.53.0.2; + port @PORT@; + listen-on { 10.53.0.2; }; + pid-file "named.pid"; + notify no; + dnssec-validation no; + allow-query { any; }; +}; + +zone "allowed" { + type master; + file "allowed.db"; + allow-transfer { none; }; +}; + +zone "baddomain" { + type master; + file "baddomain.db"; + allow-transfer { none; }; +}; + diff --git a/bin/tests/system/rpzextra/setup.sh b/bin/tests/system/rpzextra/setup.sh new file mode 100644 index 0000000000..1c0d9b9d49 --- /dev/null +++ b/bin/tests/system/rpzextra/setup.sh @@ -0,0 +1,20 @@ +#! /bin/sh +# +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# 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 http://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +# touch dnsrps-off to not test with DNSRPS + +set -e + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh + +copy_setports ns1/named.conf.in ns1/named.conf +copy_setports ns2/named.conf.in ns2/named.conf diff --git a/bin/tests/system/rpzextra/tests-rpz-passthru-logging.py b/bin/tests/system/rpzextra/tests-rpz-passthru-logging.py new file mode 100755 index 0000000000..0284835b24 --- /dev/null +++ b/bin/tests/system/rpzextra/tests-rpz-passthru-logging.py @@ -0,0 +1,47 @@ +#!/usr/bin/python3 +############################################################################ +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# 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 http://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. +############################################################################ + +import os +import pytest +import dns.resolver + + +# @pytest.mark.dnspython +def test_rpz_passthru_logging(named_port): + resolver = dns.resolver.Resolver() + resolver.nameservers = ['10.53.0.1'] + resolver.port = named_port + + # Should generate a log entry into rpz_passthru.txt + ans = resolver.query('allowed.', 'A') + for rd in ans: + assert rd.address == "10.53.0.2" + + # baddomain.com isn't allowed (CNAME .), should return NXDOMAIN + # Should generate a log entry into rpz.txt + with pytest.raises(dns.resolver.NXDOMAIN): + resolver.query('baddomain.', 'A') + + rpz_passthru_logfile = os.path.join("ns1", "rpz_passthru.txt") + rpz_logfile = os.path.join("ns1", "rpz.txt") + + assert os.path.isfile(rpz_passthru_logfile) + assert os.path.isfile(rpz_logfile) + + with open(rpz_passthru_logfile) as log_file: + line = log_file.read() + assert "rpz QNAME PASSTHRU rewrite allowed/A/IN" in line + + with open(rpz_logfile) as log_file: + line = log_file.read() + assert "rpz QNAME PASSTHRU rewrite allowed/A/IN" not in line + assert "rpz QNAME NXDOMAIN rewrite baddomain/A/IN" in line diff --git a/configure.ac b/configure.ac index fc66a21c53..680645c565 100644 --- a/configure.ac +++ b/configure.ac @@ -284,6 +284,7 @@ AC_PATH_PROGS([PYTEST], [pytest-3 pytest pytest-pypy], []) AS_IF([test -z "$PYTEST"], [AC_MSG_WARN([pytest not found, some system tests will be skipped])]) AC_SUBST([PYTEST]) +AM_CONDITIONAL([HAVE_PYTEST], [test -n "$PYTEST"]) AX_PYTHON_MODULE([dns]) AM_CONDITIONAL([HAVE_PYMOD_DNS], [test "$HAVE_PYMOD_DNS" = "yes"]) diff --git a/doc/arm/notes-9.17.2.xml b/doc/arm/notes-9.17.2.xml index 3290ffd0b0..173c7ad946 100644 --- a/doc/arm/notes-9.17.2.xml +++ b/doc/arm/notes-9.17.2.xml @@ -69,18 +69,24 @@ - - The OpenSSL ECDSA implementation has been updated to support PKCS#11 - via OpenSSL engine (see engine_pkcs11 from libp11 project). [GL #1534] - + + The OpenSSL ECDSA implementation has been updated to support PKCS#11 + via OpenSSL engine (see engine_pkcs11 from libp11 project). [GL #1534] + - - The OpenSSL EdDSA implementation has been updated to support PKCS#11 - via OpenSSL engine. Please note that you need EdDSA capable OpenSSL - engine and there's only proof-of-concept as of this moment. - Contributed by Aaron Thompson. [GL #1763] - + + The OpenSSL EdDSA implementation has been updated to support PKCS#11 + via OpenSSL engine. Please note that you need EdDSA capable OpenSSL + engine and there's only proof-of-concept as of this moment. + Contributed by Aaron Thompson. [GL #1763] + + + + + Added a new logging category "rpz-passthru", it allows RPZ passthru + actions to be logged into a separate channel. [GL #54] + diff --git a/lib/dns/include/dns/log.h b/lib/dns/include/dns/log.h index a687fbfc9f..4fe22e4b6a 100644 --- a/lib/dns/include/dns/log.h +++ b/lib/dns/include/dns/log.h @@ -41,6 +41,7 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[]; #define DNS_LOGCATEGORY_DNSTAP (&dns_categories[16]) #define DNS_LOGCATEGORY_ZONELOAD (&dns_categories[17]) #define DNS_LOGCATEGORY_NSID (&dns_categories[18]) +#define DNS_LOGCATEGORY_RPZ_PASSTHRU (&dns_categories[19]) /* Backwards compatibility. */ #define DNS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL diff --git a/lib/dns/log.c b/lib/dns/log.c index 5964d1ba49..98163b0ba2 100644 --- a/lib/dns/log.c +++ b/lib/dns/log.c @@ -20,26 +20,13 @@ * \#define to . */ LIBDNS_EXTERNAL_DATA isc_logcategory_t dns_categories[] = { - { "notify", 0 }, - { "database", 0 }, - { "security", 0 }, - { "_placeholder", 0 }, - { "dnssec", 0 }, - { "resolver", 0 }, - { "xfer-in", 0 }, - { "xfer-out", 0 }, - { "dispatch", 0 }, - { "lame-servers", 0 }, - { "delegation-only", 0 }, - { "edns-disabled", 0 }, - { "rpz", 0 }, - { "rate-limit", 0 }, - { "cname", 0 }, - { "spill", 0 }, - { "dnstap", 0 }, - { "zoneload", 0 }, - { "nsid", 0 }, - { NULL, 0 } + { "notify", 0 }, { "database", 0 }, { "security", 0 }, + { "_placeholder", 0 }, { "dnssec", 0 }, { "resolver", 0 }, + { "xfer-in", 0 }, { "xfer-out", 0 }, { "dispatch", 0 }, + { "lame-servers", 0 }, { "delegation-only", 0 }, { "edns-disabled", 0 }, + { "rpz", 0 }, { "rate-limit", 0 }, { "cname", 0 }, + { "spill", 0 }, { "dnstap", 0 }, { "zoneload", 0 }, + { "nsid", 0 }, { "rpz-passthru", 0 }, { NULL, 0 } }; /*% diff --git a/lib/ns/query.c b/lib/ns/query.c index 8f1a8b1162..9d3ca90df9 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -1164,8 +1164,12 @@ rpz_log_rewrite(ns_client_t *client, bool disabled, dns_rpz_policy_t policy, dns_rdataclass_format(rdataset->rdclass, classbuf, sizeof(classbuf)); dns_rdatatype_format(rdataset->type, typebuf, sizeof(typebuf)); - ns_client_log(client, DNS_LOGCATEGORY_RPZ, NS_LOGMODULE_QUERY, - DNS_RPZ_INFO_LEVEL, + /* It's possible to have a separate log channel for rpz passthru. */ + isc_logcategory_t *log_cat = (policy == DNS_RPZ_POLICY_PASSTHRU) + ? DNS_LOGCATEGORY_RPZ_PASSTHRU + : DNS_LOGCATEGORY_RPZ; + + ns_client_log(client, log_cat, NS_LOGMODULE_QUERY, DNS_RPZ_INFO_LEVEL, "%srpz %s %s rewrite %s/%s/%s via %s%s%s%s", disabled ? "disabled " : "", dns_rpz_type2str(type), dns_rpz_policy2str(policy), qname_buf, typebuf, classbuf, diff --git a/util/copyrights b/util/copyrights index be1d280c05..00f72dc61a 100644 --- a/util/copyrights +++ b/util/copyrights @@ -705,6 +705,11 @@ ./bin/tests/system/rpz/test5 X 2018,2019,2020 ./bin/tests/system/rpz/test6 X 2018,2019,2020 ./bin/tests/system/rpz/tests.sh SH 2011,2012,2013,2014,2015,2016,2017,2018,2019,2020 +./bin/tests/system/rpzextra/clean.sh SH 2020 +./bin/tests/system/rpzextra/conftest.py PYTHON 2020 +./bin/tests/system/rpzextra/ns1/named.args X 2020 +./bin/tests/system/rpzextra/setup.sh SH 2020 +./bin/tests/system/rpzextra/tests-rpz-passthru-logging.py PYTHON-BIN 2020 ./bin/tests/system/rpzrecurse/README TXT.BRIEF 2015,2016,2018,2019,2020 ./bin/tests/system/rpzrecurse/ans5/ans.pl PERL 2016,2018,2019,2020 ./bin/tests/system/rpzrecurse/clean.sh SH 2015,2016,2017,2018,2019,2020