Merge branch '54-separate-logging-channel-rpz-passthru' into 'master'

Resolve "suppress logging of RPZ passthru"

Closes #54

See merge request isc-projects/bind9!3405
This commit is contained in:
Diego dos Santos Fronza 2020-05-07 15:31:59 +00:00
commit 3262aba423
19 changed files with 343 additions and 32 deletions

View file

@ -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]

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1 @@
-m record,size,mctx -c named.conf -d 99 -D rpzextra-ns1 -X named.lock -U 4

View file

@ -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";
};

View file

@ -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

View file

@ -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 .

View file

@ -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

View file

@ -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

View file

@ -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; };
};

View file

@ -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

View file

@ -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

View file

@ -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"])

View file

@ -69,18 +69,24 @@
</para>
</listitem>
<listitem>
<para>
The OpenSSL ECDSA implementation has been updated to support PKCS#11
via OpenSSL engine (see engine_pkcs11 from libp11 project). [GL #1534]
</para>
<para>
The OpenSSL ECDSA implementation has been updated to support PKCS#11
via OpenSSL engine (see engine_pkcs11 from libp11 project). [GL #1534]
</para>
</listitem>
<listitem>
<para>
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]
</para>
<para>
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]
</para>
</listitem>
<listitem>
<para>
Added a new logging category "rpz-passthru", it allows RPZ passthru
actions to be logged into a separate channel. [GL #54]
</para>
</listitem>
</itemizedlist>
</section>

View file

@ -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

View file

@ -20,26 +20,13 @@
* \#define to <dns/log.h>.
*/
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 }
};
/*%

View file

@ -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,

View file

@ -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