Commit a4c60a9f authored by Evan Hunt's avatar Evan Hunt
Browse files

Merge branch...

Merge branch '865-option-to-disable-information-leak-on-rpz-rewrites-isc-support-14178' into 'master'

Resolve "Option to disable information leak on RPZ rewrites [ISC-support #14178]"

Closes #865

See merge request !1514
parents 3d512a7e 89234643
Pipeline #11311 passed with stages
in 58 seconds
5177. [func] Add the ability to specify in named.conf whether a
response-policy zone's SOA record should be added
to the additional section (add-soa yes/no). [GL #865]
5176. [tests] Remove a dependency on libxml in statschannel system
test. [GL #926]
 
......
......@@ -2115,6 +2115,7 @@ configure_rpz_name2(dns_view_t *view, const cfg_obj_t *obj, dns_name_t *name,
static isc_result_t
configure_rpz_zone(dns_view_t *view, const cfg_listelt_t *element,
bool recursive_only_default,
bool add_soa_default,
dns_ttl_t ttl_default,
uint32_t minupdateinterval_default,
const dns_rpz_zone_t *old,
......@@ -2259,6 +2260,13 @@ configure_rpz_zone(dns_view_t *view, const cfg_listelt_t *element,
!dns_name_equal(&old->cname, &zone->cname)))
*old_rpz_okp = false;
obj = cfg_tuple_get(rpz_obj, "add-soa");
if (cfg_obj_isvoid(obj)) {
zone->addsoa = add_soa_default;
} else {
zone->addsoa = cfg_obj_asboolean(obj);
}
return (ISC_R_SUCCESS);
}
......@@ -2271,7 +2279,7 @@ configure_rpz(dns_view_t *view, const cfg_obj_t **maps,
char *rps_cstr;
size_t rps_cstr_size;
const cfg_obj_t *sub_obj;
bool recursive_only_default;
bool recursive_only_default, add_soa_default;
bool nsip_enabled, nsdname_enabled;
dns_rpz_zbits_t nsip_on, nsdname_on;
dns_ttl_t ttl_default;
......@@ -2367,6 +2375,13 @@ configure_rpz(dns_view_t *view, const cfg_obj_t **maps,
recursive_only_default = true;
}
sub_obj = cfg_tuple_get(rpz_obj, "add-soa");
if (!cfg_obj_isvoid(sub_obj) && !cfg_obj_asboolean(sub_obj)) {
add_soa_default = false;
} else {
add_soa_default = true;
}
sub_obj = cfg_tuple_get(rpz_obj, "break-dnssec");
if (!cfg_obj_isvoid(sub_obj) && cfg_obj_asboolean(sub_obj)) {
zones->p.break_dnssec = true;
......@@ -2429,6 +2444,7 @@ configure_rpz(dns_view_t *view, const cfg_obj_t **maps,
}
result = configure_rpz_zone(view, zone_element,
recursive_only_default,
add_soa_default,
ttl_default,
minupdateinterval_default,
old_zone, old_rpz_okp);
......
......@@ -32,6 +32,7 @@ rm -f ns2/tld2s.db ns2/bl.tld2.db
rm -f ns3/bl*.db ns*/empty.db
rm -f ns3/manual-update-rpz.db
rm -f ns5/example.db ns5/bl.db
rm -f ns8/manual-update-rpz.db
rm -f */policy2.db
rm -f */*.jnl
......
......@@ -17,4 +17,3 @@ $TTL 300
NS ns.tld3.
walled.tld2.manual-update-rpz. 300 A 10.0.0.1
......@@ -46,6 +46,7 @@ options {
zone "bl.tld2";
zone "manual-update-rpz";
}
add-soa yes
min-ns-dots 0
qname-wait-recurse yes
min-update-interval 0
......
......@@ -29,6 +29,7 @@ options {
response-policy {
zone "policy1" min-update-interval 0;
} qname-wait-recurse yes
// add-soa yes # leave add-soa as default for unset test
nsip-enable yes
nsdname-enable yes;
......
......@@ -24,7 +24,7 @@ options {
dnssec-validation yes;
response-policy {
zone "policy2";
zone "policy2" add-soa no;
} qname-wait-recurse no
nsip-enable yes
nsdname-enable yes
......
; 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.
. 120 NS ns.
ns. 120 A 10.53.0.1
; 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.
; RPZ test
; This basic file is copied to several zone files before being used.
; Its contents are also changed with nsupdate
$TTL 300
@ SOA manual-update-rpz. hostmaster.ns.manual-rpz-update. ( 1 3600 1200 604800 60 )
NS ns.tld3.
walled.tld2.manual-update-rpz. 300 A 10.0.0.1
/*
* 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.
*/
/*
* Main rpz test DNS server.
*/
options {
query-source address 10.53.0.8;
notify-source 10.53.0.8;
transfer-source 10.53.0.8;
port @PORT@;
pid-file "named.pid";
statistics-file "named.stats";
session-keyfile "session.key";
listen-on { 10.53.0.8; };
listen-on-v6 { none; };
notify yes;
minimal-responses no;
recursion yes;
dnssec-validation yes;
response-policy {
zone "manual-update-rpz";
}
// add-soa yes // do not set testing default mode
min-ns-dots 0
qname-wait-recurse yes
min-update-interval 0
nsdname-enable yes
nsip-enable yes
;
include "../dnsrps.conf";
also-notify { 10.53.0.8 port @EXTRAPORT1@; };
notify-delay 0;
};
logging { category rpz { default_debug; }; };
key rndc_key {
secret "1234abcd8765";
algorithm hmac-sha256;
};
controls {
inet 10.53.0.8 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
zone "." { type hint; file "hints"; };
zone "manual-update-rpz." {
type master;
file "manual-update-rpz.db";
notify no;
};
......@@ -50,6 +50,7 @@ copy_setports ns4/named.conf.in ns4/named.conf
copy_setports ns5/named.conf.in ns5/named.conf
copy_setports ns6/named.conf.in ns6/named.conf
copy_setports ns7/named.conf.in ns7/named.conf
copy_setports ns8/named.conf.in ns8/named.conf
copy_setports dnsrpzd.conf.in dnsrpzd.conf
......@@ -70,6 +71,7 @@ for NM in '' -2 -given -disabled -passthru -no-op -nodata -nxdomain -cname -wild
done
# bl zones are dynamically updated. Add one zone that is updated manually.
cp ns3/manual-update-rpz.db.in ns3/manual-update-rpz.db
cp ns8/manual-update-rpz.db.in ns8/manual-update-rpz.db
# $1=directory
# $2=domain name
......
......@@ -25,6 +25,7 @@ ns4=$ns.4 # another authoritative server that is rewritten
ns5=$ns.5 # another rewriting resolver
ns6=$ns.6 # a forwarding server
ns7=$ns.7 # another rewriting resolver
ns8=$ns.8 # another rewriting resolver
HAVE_CORE=
......@@ -776,27 +777,29 @@ EOF
fi
done
# restart the main test RPZ server with a bad zone.
t=`expr $t + 1`
echo_i "checking that ns3 with broken rpz does not crash (${t})"
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} rpz ns3
cp ns3/broken.db.in ns3/bl.db
restart 3 # do not rebuild rpz zones
nocrash a3-1.tld2 -tA
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} rpz ns3
restart 3 "rebuild-bl-rpz"
# reload a RPZ zone that is now deliberately broken.
t=`expr $t + 1`
echo_i "checking rpz failed update will keep previous rpz rules (${t})"
$DIG -p ${PORT} @$ns3 walled.tld2 > dig.out.$t.before
grep "walled\.tld2\..*IN.*A.*10\.0\.0\.1" dig.out.$t.before > /dev/null || setret "failed"
cp ns3/broken.db.in ns3/manual-update-rpz.db
rndc_reload ns3 $ns3 manual-update-rpz
sleep 1
# ensure previous RPZ rules still apply.
$DIG -p ${PORT} @$ns3 walled.tld2 > dig.out.$t.after
grep "walled\.tld2\..*IN.*A.*10\.0\.0\.1" dig.out.$t.after > /dev/null || setret "failed"
if [ native = "$mode" ]; then
# restart the main test RPZ server with a bad zone.
t=`expr $t + 1`
echo_i "checking that ns3 with broken rpz does not crash (${t})"
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} rpz ns3
cp ns3/broken.db.in ns3/bl.db
restart 3 # do not rebuild rpz zones
nocrash a3-1.tld2 -tA
$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} rpz ns3
restart 3 "rebuild-bl-rpz"
# reload a RPZ zone that is now deliberately broken.
t=`expr $t + 1`
echo_i "checking rpz failed update will keep previous rpz rules (${t})"
$DIG -p ${PORT} @$ns3 walled.tld2 > dig.out.$t.before
grep "walled\.tld2\..*IN.*A.*10\.0\.0\.1" dig.out.$t.before > /dev/null || setret "failed"
cp ns3/broken.db.in ns3/manual-update-rpz.db
rndc_reload ns3 $ns3 manual-update-rpz
sleep 1
# ensure previous RPZ rules still apply.
$DIG -p ${PORT} @$ns3 walled.tld2 > dig.out.$t.after
grep "walled\.tld2\..*IN.*A.*10\.0\.0\.1" dig.out.$t.after > /dev/null || setret "failed"
fi
t=`expr $t + 1`
echo_i "checking that ttl values are not zeroed when qtype is '*' (${t})"
......@@ -825,9 +828,28 @@ EOF
$DIG z.x.servfail -p ${PORT} @$ns7 > dig.out.${t}
grep NXDOMAIN dig.out.${t} > /dev/null || setret "failed"
t=`expr $t + 1`
echo_i "checking that "add-soa no" at rpz zone level works (${t})"
$DIG z.x.servfail -p ${PORT} @$ns7 > dig.out.${t}
grep SOA dig.out.${t} > /dev/null && setret "failed"
if [ native = "$mode" ]; then
t=`expr $t + 1`
echo_i "checking that "add-soa yes" at response-policy level works (${t})"
$DIG walled.tld2 -p ${PORT} +noall +add @$ns3 > dig.out.${t}
grep "^manual-update-rpz\..*SOA" dig.out.${t} > /dev/null || setret "failed"
fi
if [ native = "$mode" ]; then
t=`expr $t + 1`
echo_i "checking that "add-soa unset" works (${t})"
$DIG walled.tld2 -p ${PORT} +noall +add @$ns8 > dig.out.${t}
grep "^manual-update-rpz\..*SOA" dig.out.${t} > /dev/null || setret "failed"
fi
# dnsrps does not allow NS RRs in policy zones, so this check
# with dnsrps results in no rewriting.
if [ "$mode" = native ]; then
if [ native = "$mode" ]; then
t=`expr $t + 1`
echo_i "checking rpz with delegation fails correctly (${t})"
$DIG -p ${PORT} @$ns3 ns example.com > dig.out.$t
......
......@@ -10133,6 +10133,14 @@ example.com CNAME rpz-tcp-only.
zone. By default, all rewrites are logged.
</para>
 
<para>
The <command>add-soa</command> option controls whether the RPZ's
SOA record is added to the additional section for traceback
of changes from this zone or not. This can be set at the
individual policy zone level or at the response-policy level.
The default is <literal>yes</literal>.
</para>
<para>
Updates to RPZ zones are processed asynchronously; if there
is more than one update pending they are bundled together.
......
......@@ -97,7 +97,10 @@
<itemizedlist>
<listitem>
<para>
None.
The new <command>add-soa</command> option specifies whether
or not the <command>response-policy</command> zone's SOA record
should be included in the additional section of RPZ responses.
[GL #865]
</para>
</listitem>
</itemizedlist>
......
......@@ -186,7 +186,7 @@ options {
fstrm-set-output-queue-model ( mpsc | spsc ); // not configured
fstrm-set-output-queue-size <integer>; // not configured
fstrm-set-reopen-interval <ttlval>; // not configured
geoip-directory ( <quoted_string> | none ); // not configured
geoip-directory ( <quoted_string> | none );
geoip-use-ecs <boolean>; // obsolete
glue-cache <boolean>;
has-old-clients <boolean>; // ancient
......@@ -207,7 +207,7 @@ options {
listen-on-v6 [ port <integer> ] [ dscp
<integer> ] {
<address_match_element>; ... }; // may occur multiple times
lmdb-mapsize <sizeval>; // non-operational
lmdb-mapsize <sizeval>;
lock-file ( <quoted_string> | none );
maintain-ixfr-base <boolean>; // ancient
managed-keys-directory <quoted_string>;
......@@ -310,11 +310,12 @@ options {
resolver-retry-interval <integer>;
response-padding { <address_match_element>; ... } block-size
<integer>;
response-policy { zone <string> [ log <boolean> ] [ max-policy-ttl
<ttlval> ] [ min-update-interval <ttlval> ] [ policy ( cname |
disabled | drop | given | no-op | nodata | nxdomain | passthru
| tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [
nsip-enable <boolean> ] [ nsdname-enable <boolean> ]; ... } [
response-policy { zone <string> [ add-soa <boolean> ] [ log
<boolean> ] [ max-policy-ttl <ttlval> ] [ min-update-interval
<ttlval> ] [ policy ( cname | disabled | drop | given | no-op |
nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [
recursive-only <boolean> ] [ nsip-enable <boolean> ] [
nsdname-enable <boolean> ]; ... } [ add-soa <boolean> ] [
break-dnssec <boolean> ] [ max-policy-ttl <ttlval> ] [
min-update-interval <ttlval> ] [ min-ns-dots <integer> ] [
nsip-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ]
......@@ -552,7 +553,7 @@ view <string> [ <class> ] {
}; // may occur multiple times
key-directory <quoted_string>;
lame-ttl <ttlval>;
lmdb-mapsize <sizeval>; // non-operational
lmdb-mapsize <sizeval>;
maintain-ixfr-base <boolean>; // ancient
managed-keys { <string> <string>
<integer> <integer> <integer>
......@@ -647,11 +648,12 @@ view <string> [ <class> ] {
resolver-retry-interval <integer>;
response-padding { <address_match_element>; ... } block-size
<integer>;
response-policy { zone <string> [ log <boolean> ] [ max-policy-ttl
<ttlval> ] [ min-update-interval <ttlval> ] [ policy ( cname |
disabled | drop | given | no-op | nodata | nxdomain | passthru
| tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [
nsip-enable <boolean> ] [ nsdname-enable <boolean> ]; ... } [
response-policy { zone <string> [ add-soa <boolean> ] [ log
<boolean> ] [ max-policy-ttl <ttlval> ] [ min-update-interval
<ttlval> ] [ policy ( cname | disabled | drop | given | no-op |
nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [
recursive-only <boolean> ] [ nsip-enable <boolean> ] [
nsdname-enable <boolean> ]; ... } [ add-soa <boolean> ] [
break-dnssec <boolean> ] [ max-policy-ttl <ttlval> ] [
min-update-interval <ttlval> ] [ min-ns-dots <integer> ] [
nsip-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ]
......
......@@ -144,14 +144,16 @@ struct dns_rpz_zone {
isc_ht_t *nodes; /* entries in zone */
dns_rpz_zones_t *rpzs; /* owner */
isc_time_t lastupdated; /* last time the zone was processed */
bool updatepending; /* there is an update pending/waiting */
bool updaterunning; /* there is an update running */
bool updatepending; /* there is an update pending/waiting */
bool updaterunning; /* there is an update running */
dns_db_t *db; /* zones database */
dns_dbversion_t *dbversion; /* version we will be updating to */
dns_db_t *updb; /* zones database we're working on */
dns_dbversion_t *updbversion; /* version we're currently working on */
dns_dbiterator_t *updbit; /* iterator to use when updating */
isc_ht_t *newnodes; /* entries in zone being updated */
bool db_registered; /* is the notify event registered? */
bool addsoa; /* add soa to the additional section */
isc_timer_t *updatetimer;
isc_event_t updateevent;
};
......@@ -190,10 +192,10 @@ struct dns_rpz_popt {
dns_rpz_zbits_t no_log;
dns_rpz_zbits_t nsip_on;
dns_rpz_zbits_t nsdname_on;
bool dnsrps_enabled;
bool break_dnssec;
bool qname_wait_recurse;
bool nsip_wait_recurse;
bool dnsrps_enabled;
bool break_dnssec;
bool qname_wait_recurse;
bool nsip_wait_recurse;
unsigned int min_ns_labels;
dns_rpz_num_t num_zones;
};
......@@ -311,8 +313,8 @@ typedef struct {
*/
struct {
isc_result_t result;
bool is_zone;
bool authoritative;
bool is_zone;
bool authoritative;
dns_zone_t *zone;
dns_db_t *db;
dns_dbnode_t *node;
......@@ -423,4 +425,3 @@ dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type,
ISC_LANG_ENDDECLS
#endif /* DNS_RPZ_H */
......@@ -1549,6 +1549,8 @@ dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp) {
zone->updbversion = NULL;
zone->updbit = NULL;
zone->rpzs = rpzs;
zone->db_registered = false;
zone->addsoa = true;
ISC_EVENT_INIT(&zone->updateevent, sizeof(zone->updateevent),
0, NULL, 0, NULL, NULL, NULL, NULL, NULL);
......
......@@ -1604,6 +1604,7 @@ static cfg_type_t cfg_type_rpz_policy = {
};
static cfg_tuplefielddef_t rpz_zone_fields[] = {
{ "zone name", &cfg_type_rpz_zone, 0 },
{ "add-soa", &cfg_type_boolean, 0 },
{ "log", &cfg_type_boolean, 0 },
{ "max-policy-ttl", &cfg_type_ttlval, 0 },
{ "min-update-interval", &cfg_type_ttlval, 0 },
......@@ -1625,6 +1626,7 @@ static cfg_type_t cfg_type_rpz_list = {
};
static cfg_tuplefielddef_t rpz_fields[] = {
{ "zone list", &cfg_type_rpz_list, 0 },
{ "add-soa", &cfg_type_boolean, 0 },
{ "break-dnssec", &cfg_type_boolean, 0 },
{ "max-policy-ttl", &cfg_type_ttlval, 0 },
{ "min-update-interval", &cfg_type_ttlval, 0 },
......
......@@ -6227,12 +6227,15 @@ query_checkrpz(query_ctx_t *qctx, isc_result_t result) {
/*
* Add SOA record to additional section
*/
rresult = query_addsoa(qctx,
dns_rdataset_isassociated(qctx->rdataset),
DNS_SECTION_ADDITIONAL);
if (rresult != ISC_R_SUCCESS) {
QUERY_ERROR(qctx, result);
return (ISC_R_COMPLETE);
if (qctx->rpz_st->m.rpz->addsoa) {
bool override_ttl =
dns_rdataset_isassociated(qctx->rdataset);
rresult = query_addsoa(qctx, override_ttl,
DNS_SECTION_ADDITIONAL);
if (rresult != ISC_R_SUCCESS) {
QUERY_ERROR(qctx, result);
return (ISC_R_COMPLETE);
}
}
switch (qctx->rpz_st->m.policy) {
......@@ -8375,10 +8378,12 @@ query_nxdomain(query_ctx_t *qctx, bool empty_wild) {
{
ttl = 0;
}
result = query_addsoa(qctx, ttl, section);
if (result != ISC_R_SUCCESS) {
QUERY_ERROR(qctx, result);
return (ns_query_done(qctx));
if (!qctx->nxrewrite || qctx->rpz_st->m.rpz->addsoa) {
result = query_addsoa(qctx, ttl, section);
if (result != ISC_R_SUCCESS) {
QUERY_ERROR(qctx, result);
return (ns_query_done(qctx));
}
}
if (WANTDNSSEC(qctx->client)) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment