From 55bbac8bfe0a76c041bf08757447f63837291465 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Mon, 25 Feb 2013 14:23:45 -0800 Subject: [PATCH] [v9_9] RPZ speed up (phase 1, single RPZ) 3496. [func] Improvements to RPZ performance. The "response-policy" syntax now includes a "min-ns-dots" clause, with default 1, to exclude top-level domains from NSIP and NSDNAME checking. --enable-rpz-nsip and --enable-rpz-nsdname are now the default. [RT #32251] Response policy (rpz) changes to - add zone statistics - speed up by adding min-ns-dots to the response-policy syntax with a default of 1 - detect and reject policy zones with a database other than rbt only rbtdb has rpz hooks - allow empty response-policy{} statement - make --enable-rpz-nsip and --enable-rpz-nsdname the default --- CHANGES | 6 + bin/named/include/named/server.h | 4 +- bin/named/query.c | 105 ++++++++-- bin/named/server.c | 273 +++++++++++++++---------- bin/named/statschannel.c | 2 + bin/tests/system/rpz/Makefile.in | 3 +- bin/tests/system/rpz/clean.sh | 7 +- bin/tests/system/rpz/ns1/named.conf | 3 +- bin/tests/system/rpz/ns1/root.db | 12 +- bin/tests/system/rpz/ns2/base-tld2s.db | 1 - bin/tests/system/rpz/ns2/hints | 8 +- bin/tests/system/rpz/ns2/named.conf | 3 +- bin/tests/system/rpz/ns2/tld2.db | 3 +- bin/tests/system/rpz/ns3/base.db | 10 +- bin/tests/system/rpz/ns3/crash1 | 3 +- bin/tests/system/rpz/ns3/crash2 | 3 +- bin/tests/system/rpz/ns3/hints | 8 +- bin/tests/system/rpz/ns3/named.conf | 17 +- bin/tests/system/rpz/ns4/hints | 7 +- bin/tests/system/rpz/ns4/named.conf | 3 +- bin/tests/system/rpz/ns4/tld4.db | 3 +- bin/tests/system/rpz/ns5/hints | 8 +- bin/tests/system/rpz/ns5/named.args | 3 + bin/tests/system/rpz/ns5/named.conf | 15 +- bin/tests/system/rpz/ns5/tld5.db | 67 ++++++ bin/tests/system/rpz/qperf.sh | 1 - bin/tests/system/rpz/rpz.c | 3 +- bin/tests/system/rpz/setup.sh | 43 ++-- bin/tests/system/rpz/test1 | 5 +- bin/tests/system/rpz/test2 | 5 +- bin/tests/system/rpz/test3 | 9 +- bin/tests/system/rpz/test4 | 3 +- bin/tests/system/rpz/test4a | 30 +++ bin/tests/system/rpz/test5 | 3 +- bin/tests/system/rpz/tests.sh | 167 +++++++++------ configure | 13 +- configure.in | 10 +- doc/arm/Bv9ARM-book.xml | 59 +++--- lib/dns/db.c | 5 +- lib/dns/include/dns/db.h | 8 +- lib/dns/include/dns/rpz.h | 19 +- lib/dns/include/dns/view.h | 1 + lib/dns/include/dns/zone.h | 10 + lib/dns/rbtdb.c | 49 ++--- lib/dns/rpz.c | 35 +--- lib/dns/win32/libdns.def | 6 +- lib/dns/zone.c | 47 ++++- lib/isccfg/namedconf.c | 8 +- 48 files changed, 683 insertions(+), 433 deletions(-) create mode 100644 bin/tests/system/rpz/ns5/named.args create mode 100644 bin/tests/system/rpz/ns5/tld5.db create mode 100644 bin/tests/system/rpz/test4a diff --git a/CHANGES b/CHANGES index c29efb7b72..5712b11dca 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +3496. [func] Improvements to RPZ performance. The "response-policy" + syntax now includes a "min-ns-dots" clause, with + default 1, to exclude top-level domains from + NSIP and NSDNAME checking. --enable-rpz-nsip and + --enable-rpz-nsdname are now the default. [RT #32251] + 3493. [contrib] Added BDBHPT dynamically-lodable DLZ module, contributed by Mark Goldfinch. [RT #32549] diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h index 5fd2c85b78..7b7941d6e0 100644 --- a/bin/named/include/named/server.h +++ b/bin/named/include/named/server.h @@ -165,7 +165,9 @@ enum { dns_nsstatscounter_updatefail = 34, dns_nsstatscounter_updatebadprereq = 35, - dns_nsstatscounter_max = 36 + dns_nsstatscounter_rpz_rewrites = 36, + + dns_nsstatscounter_max = 37 }; void diff --git a/bin/named/query.c b/bin/named/query.c index 853b7955c6..5093cb243d 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -877,12 +877,29 @@ query_getzonedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, } static void -rpz_log_rewrite(ns_client_t *client, const char *disabled, +rpz_log_rewrite(ns_client_t *client, isc_boolean_t disabled, dns_rpz_policy_t policy, dns_rpz_type_t type, - dns_name_t *rpz_qname) { + dns_zone_t *zone, dns_name_t *rpz_qname) +{ + isc_stats_t *zonestats; char qname_buf[DNS_NAME_FORMATSIZE]; char rpz_qname_buf[DNS_NAME_FORMATSIZE]; + /* + * Count enabled rewrites in the global counter. + * Count both enabled and disabled rewrites for each zone. + */ + if (!disabled && policy != DNS_RPZ_POLICY_PASSTHRU) { + isc_stats_increment(ns_g_server->nsstats, + dns_nsstatscounter_rpz_rewrites); + } + if (zone != NULL) { + zonestats = dns_zone_getrequeststats(zone); + if (zonestats != NULL) + isc_stats_increment(zonestats, + dns_nsstatscounter_rpz_rewrites); + } + if (!isc_log_wouldlog(ns_g_lctx, DNS_RPZ_INFO_LEVEL)) return; @@ -891,7 +908,7 @@ rpz_log_rewrite(ns_client_t *client, const char *disabled, ns_client_log(client, DNS_LOGCATEGORY_RPZ, NS_LOGMODULE_QUERY, DNS_RPZ_INFO_LEVEL, "%srpz %s %s rewrite %s via %s", - disabled, + disabled ? "disabled " : "", dns_rpz_type2str(type), dns_rpz_policy2str(policy), qname_buf, rpz_qname_buf); } @@ -907,6 +924,9 @@ rpz_log_fail(ns_client_t *client, int level, if (!isc_log_wouldlog(ns_g_lctx, level)) return; + /* + * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". + */ dns_name_format(client->query.qname, namebuf1, sizeof(namebuf1)); dns_name_format(name, namebuf2, sizeof(namebuf2)); ns_client_log(client, NS_LOGCATEGORY_QUERY_EERRORS, @@ -4131,6 +4151,8 @@ rpz_rewrite_rrset(ns_client_t *client, dns_rpz_type_t rpz_type, rdatasetp, resuming); switch (result) { case ISC_R_SUCCESS: + case DNS_R_GLUE: + case DNS_R_ZONECUT: result = rpz_rewrite_ip(client, *rdatasetp, rpz_type); break; case DNS_R_EMPTYNAME: @@ -4315,26 +4337,32 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, result = DNS_R_CNAME; } break; + case DNS_R_NXRRSET: + policy = DNS_RPZ_POLICY_NODATA; + break; case DNS_R_DNAME: /* * DNAME policy RRs have very few if any uses that are not * better served with simple wildcards. Making the work would * require complications to get the number of labels matched * in the name or the found name to the main DNS_R_DNAME case - * in query_find(). So fall through to treat them as NODATA. + * in query_find(). + */ + dns_rdataset_disassociate(*rdatasetp); + dns_db_detachnode(*dbp, nodep); + /* + * Fall through to treat it as a miss. */ - case DNS_R_NXRRSET: - policy = DNS_RPZ_POLICY_NODATA; - break; case DNS_R_NXDOMAIN: case DNS_R_EMPTYNAME: /* * If we don't get a qname hit, * see if it is worth looking for other types. */ - dns_db_rpz_enabled(*dbp, client->query.rpz_st); + (void)dns_db_rpz_enabled(*dbp, client->query.rpz_st); dns_db_detach(dbp); dns_zone_detach(zonep); + result = DNS_R_NXDOMAIN; policy = DNS_RPZ_POLICY_MISS; break; default: @@ -4342,9 +4370,7 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, dns_zone_detach(zonep); rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, rpz_type, qnamef, "", result); - policy = DNS_RPZ_POLICY_ERROR; - result = DNS_R_SERVFAIL; - break; + return (DNS_R_SERVFAIL); } *policyp = policy; @@ -4410,6 +4436,9 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, if (result == ISC_R_SUCCESS) break; INSIST(result == DNS_R_NAMETOOLONG); + /* + * Trim the name until it is not too long. + */ labels = dns_name_countlabels(prefix); if (labels < 2) { rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, @@ -4433,7 +4462,6 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, rdatasetp, &policy); switch (result) { case DNS_R_NXDOMAIN: - case DNS_R_EMPTYNAME: break; case DNS_R_SERVFAIL: rpz_clean(&zone, &db, &node, rdatasetp); @@ -4456,13 +4484,45 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, (st->m.type == rpz_type && 0 >= dns_name_compare(rpz_qname, st->qname)))) continue; +#if 0 + /* + * This code would block a customer reported information + * leak of rpz rules by rewriting requests in the + * rpz-ip, rpz-nsip, rpz-nsdname,and rpz-passthru TLDs. + * Without this code, a bad guy could request + * 24.0.3.2.10.rpz-ip. to find the policy rule for + * 10.2.3.0/14. It is an insignificant leak and this + * code is not worth its cost, because the bad guy + * could publish "evil.com A 10.2.3.4" and request + * evil.com to get the same information. + * Keep code with "#if 0" in case customer demand + * is irresistible. + * + * We have the less frequent case of a triggered + * policy. Check that we have not trigger on one + * of the pretend RPZ TLDs. + * This test would make it impossible to rewrite + * names in TLDs that start with "rpz-" should + * ICANN ever allow such TLDs. + */ + labels = dns_name_countlabels(qname); + if (labels >= 2) { + dns_label_t label; + dns_name_getlabel(qname, labels-2, &label); + if (label.length >= sizeof(DNS_RPZ_PREFIX)-1 && + strncasecmp((const char *)label.base+1, + DNS_RPZ_PREFIX, + sizeof(DNS_RPZ_PREFIX)-1) == 0) + continue; + } +#endif /* * Merely log DNS_RPZ_POLICY_DISABLED hits. */ if (rpz->policy == DNS_RPZ_POLICY_DISABLED) { - rpz_log_rewrite(client, "disabled ", - policy, rpz_type, rpz_qname); + rpz_log_rewrite(client, ISC_TRUE, policy, + rpz_type, zone, rpz_qname); continue; } @@ -4593,7 +4653,7 @@ rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, isc_result_t qresult, rdataset = NULL; if ((st->state & DNS_RPZ_DONE_QNAME) == 0) { /* - * Check rules for the query name if this it the first time + * Check rules for the query name if this is the first time * for the current qname, i.e. we've not been recursing. * There is a first time for each name in a CNAME chain. */ @@ -4635,7 +4695,7 @@ rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, isc_result_t qresult, dns_fixedname_init(&nsnamef); dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef)); - while (st->r.label > 1) { + while (st->r.label > client->view->rpz_min_ns_labels) { /* * Get NS rrset for each domain in the current qname. */ @@ -4766,8 +4826,8 @@ cleanup: st->m.policy == DNS_RPZ_POLICY_ERROR) { if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU && result != DNS_R_DELEGATION) - rpz_log_rewrite(client, "", st->m.policy, st->m.type, - st->qname); + rpz_log_rewrite(client, ISC_FALSE, st->m.policy, + st->m.type, st->m.zone, st->qname); rpz_match_clear(st); } if (st->m.policy == DNS_RPZ_POLICY_ERROR) { @@ -4782,7 +4842,7 @@ cleanup: } /* - * See if response policy zone rewriting is allowed a lack of interest + * See if response policy zone rewriting is allowed by a lack of interest * by the client in DNSSEC or a lack of signatures. */ static isc_boolean_t @@ -4877,7 +4937,8 @@ rpz_add_cname(ns_client_t *client, dns_rpz_st_t *st, fname, dns_trust_authanswer, st->m.ttl); if (result != ISC_R_SUCCESS) return (result); - rpz_log_rewrite(client, "", st->m.policy, st->m.type, st->qname); + rpz_log_rewrite(client, ISC_FALSE, st->m.policy, + st->m.type, st->m.zone, st->qname); ns_client_qnamereplace(client, fname); /* * Turn off DNSSEC because the results of a @@ -5940,8 +6001,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) query_putrdataset(client, &sigrdataset); rpz_st->q.is_zone = is_zone; is_zone = ISC_TRUE; - rpz_log_rewrite(client, "", rpz_st->m.policy, - rpz_st->m.type, rpz_st->qname); + rpz_log_rewrite(client, ISC_FALSE, rpz_st->m.policy, + rpz_st->m.type, zone, rpz_st->qname); } } diff --git a/bin/named/server.c b/bin/named/server.c index 43ce4f77b7..ce87a0cb1c 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -1515,40 +1515,58 @@ cleanup: return (result); } +static isc_result_t +configure_rpz_name(dns_view_t *view, const cfg_obj_t *obj, dns_name_t *name, + const char *str, const char *msg) +{ + isc_result_t result; + + result = dns_name_fromstring(name, str, DNS_NAME_DOWNCASE, view->mctx); + if (result != ISC_R_SUCCESS) + cfg_obj_log(obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, + "invalid %s '%s'", msg, str); + return (result); +} + +static isc_result_t +configure_rpz_name2(dns_view_t *view, const cfg_obj_t *obj, dns_name_t *name, + const char *str, const dns_name_t *origin) +{ + isc_result_t result; + + result = dns_name_fromstring2(name, str, origin, DNS_NAME_DOWNCASE, + view->mctx); + if (result != ISC_R_SUCCESS) + cfg_obj_log(obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, + "invalid zone '%s'", str); + return (result); +} + static isc_result_t configure_rpz(dns_view_t *view, const cfg_listelt_t *element, isc_boolean_t recursive_only_def, dns_ttl_t ttl_def) { - const cfg_obj_t *rpz_obj, *policy_obj, *obj; + const cfg_obj_t *rpz_obj, *obj; const char *str; dns_rpz_zone_t *old, *new; - dns_zone_t *zone = NULL; isc_result_t result; + rpz_obj = cfg_listelt_value(element); + new = isc_mem_get(view->mctx, sizeof(*new)); if (new == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; + cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, + "no memory for response policy zones"); + return (ISC_R_NOMEMORY); } memset(new, 0, sizeof(*new)); dns_name_init(&new->origin, NULL); dns_name_init(&new->nsdname, NULL); - dns_name_init(&new->cname, NULL); dns_name_init(&new->passthru, NULL); + dns_name_init(&new->cname, NULL); ISC_LIST_INITANDAPPEND(view->rpz_zones, new, link); - rpz_obj = cfg_listelt_value(element); - policy_obj = cfg_tuple_get(rpz_obj, "policy"); - if (cfg_obj_isvoid(policy_obj)) { - new->policy = DNS_RPZ_POLICY_GIVEN; - } else { - str = cfg_obj_asstring(cfg_tuple_get(policy_obj, - "policy name")); - new->policy = dns_rpz_str2policy(str); - INSIST(new->policy != DNS_RPZ_POLICY_ERROR); - } - obj = cfg_tuple_get(rpz_obj, "recursive-only"); if (cfg_obj_isvoid(obj)) { new->recursive_only = recursive_only_def; @@ -1566,47 +1584,14 @@ configure_rpz(dns_view_t *view, const cfg_listelt_t *element, } str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "zone name")); - result = dns_name_fromstring(&new->origin, str, DNS_NAME_DOWNCASE, - view->mctx); - if (result != ISC_R_SUCCESS) { + result = configure_rpz_name(view, rpz_obj, &new->origin, str, "zone"); + if (result != ISC_R_SUCCESS) + return (result); + if (dns_name_equal(&new->origin, dns_rootname)) { cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "invalid zone '%s'", str); - goto cleanup; + "invalid zone name '%s'", str); + return (DNS_R_EMPTYLABEL); } - - result = dns_name_fromstring2(&new->nsdname, DNS_RPZ_NSDNAME_ZONE, - &new->origin, DNS_NAME_DOWNCASE, - view->mctx); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "invalid zone '%s'", str); - goto cleanup; - } - - result = dns_name_fromstring(&new->passthru, DNS_RPZ_PASSTHRU_ZONE, - DNS_NAME_DOWNCASE, view->mctx); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "invalid zone '%s'", str); - goto cleanup; - } - - result = dns_view_findzone(view, &new->origin, &zone); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "unknown zone '%s'", str); - goto cleanup; - } - if (dns_zone_gettype(zone) != dns_zone_master && - dns_zone_gettype(zone) != dns_zone_slave) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "zone '%s' is neither master nor slave", str); - dns_zone_detach(&zone); - result = DNS_R_NOTMASTER; - goto cleanup; - } - dns_zone_detach(&zone); - for (old = ISC_LIST_HEAD(view->rpz_zones); old != new; old = ISC_LIST_NEXT(old, link)) { @@ -1615,26 +1600,37 @@ configure_rpz(dns_view_t *view, const cfg_listelt_t *element, cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, "duplicate '%s'", str); result = DNS_R_DUPLICATE; - goto cleanup; + return (result); } } - if (new->policy == DNS_RPZ_POLICY_CNAME) { - str = cfg_obj_asstring(cfg_tuple_get(policy_obj, "cname")); - result = dns_name_fromstring(&new->cname, str, - DNS_NAME_DOWNCASE, view->mctx); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, - "invalid cname '%s'", str); - goto cleanup; + result = configure_rpz_name2(view, rpz_obj, &new->nsdname, + DNS_RPZ_NSDNAME_ZONE, &new->origin); + if (result != ISC_R_SUCCESS) + return (result); + + result = configure_rpz_name(view, rpz_obj, &new->passthru, + DNS_RPZ_PASSTHRU_ZONE, "zone"); + if (result != ISC_R_SUCCESS) + return (result); + + obj = cfg_tuple_get(rpz_obj, "policy"); + if (cfg_obj_isvoid(obj)) { + new->policy = DNS_RPZ_POLICY_GIVEN; + } else { + str = cfg_obj_asstring(cfg_tuple_get(obj, "policy name")); + new->policy = dns_rpz_str2policy(str); + INSIST(new->policy != DNS_RPZ_POLICY_ERROR); + if (new->policy == DNS_RPZ_POLICY_CNAME) { + str = cfg_obj_asstring(cfg_tuple_get(obj, "cname")); + result = configure_rpz_name(view, rpz_obj, &new->cname, + str, "cname"); + if (result != ISC_R_SUCCESS) + return (result); } } return (ISC_R_SUCCESS); - - cleanup: - dns_rpz_view_destroy(view); - return (result); } /* @@ -1703,6 +1699,7 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL; unsigned int query_timeout, ndisp; struct cfg_context *nzctx; + dns_rpz_zone_t *rpz; REQUIRE(DNS_VIEW_VALID(view)); @@ -1800,6 +1797,53 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, &view->queryacl)); } + /* + * Make the list of response policy zone names for a view that + * is used for real lookups and so cares about hints. + */ + obj = NULL; + if (view->rdclass == dns_rdataclass_in && need_hints && + ns_config_get(maps, "response-policy", &obj) == ISC_R_SUCCESS) { + const cfg_obj_t *rpz_obj; + isc_boolean_t recursive_only_def; + dns_ttl_t ttl_def; + + rpz_obj = cfg_tuple_get(obj, "recursive-only"); + if (!cfg_obj_isvoid(rpz_obj) && + !cfg_obj_asboolean(rpz_obj)) + recursive_only_def = ISC_FALSE; + else + recursive_only_def = ISC_TRUE; + + rpz_obj = cfg_tuple_get(obj, "break-dnssec"); + if (!cfg_obj_isvoid(rpz_obj) && + cfg_obj_asboolean(rpz_obj)) + view->rpz_break_dnssec = ISC_TRUE; + else + view->rpz_break_dnssec = ISC_FALSE; + + rpz_obj = cfg_tuple_get(obj, "max-policy-ttl"); + if (cfg_obj_isuint32(rpz_obj)) + ttl_def = cfg_obj_asuint32(rpz_obj); + else + ttl_def = DNS_RPZ_MAX_TTL_DEFAULT; + + rpz_obj = cfg_tuple_get(obj, "min-ns-dots"); + if (cfg_obj_isuint32(rpz_obj)) + view->rpz_min_ns_labels = cfg_obj_asuint32(rpz_obj) + 1; + else + view->rpz_min_ns_labels = 2; + + element = cfg_list_first(cfg_tuple_get(obj, "zone list")); + while (element != NULL) { + result = configure_rpz(view, element, + recursive_only_def, ttl_def); + if (result != ISC_R_SUCCESS) + goto cleanup; + element = cfg_list_next(element); + } + } + /* * Configure the zones. */ @@ -1821,6 +1865,22 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, actx, ISC_FALSE)); } + for (rpz = ISC_LIST_HEAD(view->rpz_zones); + rpz != NULL; + rpz = ISC_LIST_NEXT(rpz, link)) + { + if (!rpz->defined) { + char namebuf[DNS_NAME_FORMATSIZE]; + + dns_name_format(&rpz->origin, namebuf, sizeof(namebuf)); + cfg_obj_log(obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL, + "'%s' is not a master or slave zone", + namebuf); + result = ISC_R_NOTFOUND; + goto cleanup; + } + } + /* * If we're allowing added zones, then load zone configuration * from the newzone file for zones that were added during previous @@ -2961,49 +3021,6 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, } } - /* - * Make the list of response policy zone names for views that - * are used for real lookups and so care about hints. - */ - obj = NULL; - if (view->rdclass == dns_rdataclass_in && need_hints && - ns_config_get(maps, "response-policy", &obj) == ISC_R_SUCCESS) { - const cfg_obj_t *recursive_only_obj; - const cfg_obj_t *break_dnssec_obj, *ttl_obj; - isc_boolean_t recursive_only_def; - dns_ttl_t ttl_def; - - recursive_only_obj = cfg_tuple_get(obj, "recursive-only"); - if (!cfg_obj_isvoid(recursive_only_obj) && - !cfg_obj_asboolean(recursive_only_obj)) - recursive_only_def = ISC_FALSE; - else - recursive_only_def = ISC_TRUE; - - break_dnssec_obj = cfg_tuple_get(obj, "break-dnssec"); - if (!cfg_obj_isvoid(break_dnssec_obj) && - cfg_obj_asboolean(break_dnssec_obj)) - view->rpz_break_dnssec = ISC_TRUE; - else - view->rpz_break_dnssec = ISC_FALSE; - - ttl_obj = cfg_tuple_get(obj, "max-policy-ttl"); - if (cfg_obj_isuint32(ttl_obj)) - ttl_def = cfg_obj_asuint32(ttl_obj); - else - ttl_def = DNS_RPZ_MAX_TTL_DEFAULT; - - for (element = cfg_list_first(cfg_tuple_get(obj, "zone list")); - element != NULL; - element = cfg_list_next(element)) { - result = configure_rpz(view, element, - recursive_only_def, ttl_def); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_rpz_set_need(ISC_TRUE); - } - } - result = ISC_R_SUCCESS; cleanup: @@ -3357,6 +3374,8 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, const char *zname; dns_rdataclass_t zclass; const char *ztypestr; + isc_boolean_t is_rpz; + dns_rpz_zone_t *rpz; options = NULL; (void)cfg_map_get(config, "options", &options); @@ -3517,6 +3536,21 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, } INSIST(dupzone == NULL); + /* + * Note whether this is a response policy zone. + */ + is_rpz = ISC_FALSE; + for (rpz = ISC_LIST_HEAD(view->rpz_zones); + rpz != NULL; + rpz = ISC_LIST_NEXT(rpz, link)) + { + if (dns_name_equal(&rpz->origin, origin)) { + is_rpz = ISC_TRUE; + rpz->defined = ISC_TRUE; + break; + } + } + /* * See if we can reuse an existing zone. This is * only possible if all of these are true: @@ -3525,6 +3559,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, * - The zone is compatible with the config * options (e.g., an existing master zone cannot * be reused if the options specify a slave zone) + * - The zone was and is or was not and is not a policy zone */ result = dns_viewlist_find(&ns_g_server->viewlist, view->name, view->rdclass, &pview); @@ -3538,6 +3573,9 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, if (zone != NULL && !ns_zone_reusable(zone, zconfig)) dns_zone_detach(&zone); + if (zone != NULL && is_rpz != dns_zone_get_rpz(zone)) + dns_zone_detach(&zone); + if (zone != NULL) { /* * We found a reusable zone. Make it use the @@ -3560,6 +3598,19 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, dns_zone_setstats(zone, ns_g_server->zonestats); } + if (is_rpz) { + result = dns_zone_rpz_enable(zone); + if (result != ISC_R_SUCCESS) { + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "zone '%s': incompatible" + " masterfile-format or database" + " for a response policy zone", + zname); + goto cleanup; + } + } + /* * If the zone contains a 'forwarders' statement, configure * selective forwarding. diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c index 9db781acce..335b600275 100644 --- a/bin/named/statschannel.c +++ b/bin/named/statschannel.c @@ -206,6 +206,8 @@ init_desc(void) { SET_NSSTATDESC(updatebadprereq, "updates rejected due to prerequisite failure", "UpdateBadPrereq"); + SET_NSSTATDESC(rpz_rewrites, "response policy zone rewrites", + "RPZRewrites"); INSIST(i == dns_nsstatscounter_max); /* Initialize resolver statistics */ diff --git a/bin/tests/system/rpz/Makefile.in b/bin/tests/system/rpz/Makefile.in index 1fa844f17b..dcbffc25c0 100644 --- a/bin/tests/system/rpz/Makefile.in +++ b/bin/tests/system/rpz/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.3 2011/01/13 04:59:24 tbox Exp $ srcdir = @srcdir@ VPATH = @srcdir@ diff --git a/bin/tests/system/rpz/clean.sh b/bin/tests/system/rpz/clean.sh index 82cfcb2909..6a22b13d1f 100644 --- a/bin/tests/system/rpz/clean.sh +++ b/bin/tests/system/rpz/clean.sh @@ -1,4 +1,4 @@ -# Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -12,13 +12,12 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: clean.sh,v 1.6 2012/01/07 23:46:53 tbox Exp $ # Clean up after rpz tests. -rm -f proto.* dsset-* random.data trusted.conf dig.out* nsupdate.tmp ns*/*tmp +rm -f proto.* dsset-* random.data trusted.conf dig.out* nsupdate.tmp ns*/*tmp rm -f ns*/*.key ns*/*.private ns2/tld2s.db rm -f ns3/bl*.db ns*/*switch ns5/requests ns5/example.db ns5/bl.db ns5/*.perf -rm -f */named.memstats */named.run */named.rpz */session.key +rm -f */named.memstats */named.run */named.stats */session.key rm -f */*.jnl */*.core */*.pid diff --git a/bin/tests/system/rpz/ns1/named.conf b/bin/tests/system/rpz/ns1/named.conf index 82de8029d5..9b3b8a33f5 100644 --- a/bin/tests/system/rpz/ns1/named.conf +++ b/bin/tests/system/rpz/ns1/named.conf @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.3 2011/01/13 04:59:24 tbox Exp $ */ controls { /* empty */ }; diff --git a/bin/tests/system/rpz/ns1/root.db b/bin/tests/system/rpz/ns1/root.db index c8d8671c7f..b59b312829 100644 --- a/bin/tests/system/rpz/ns1/root.db +++ b/bin/tests/system/rpz/ns1/root.db @@ -1,4 +1,4 @@ -; Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,13 +12,11 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: root.db,v 1.6 2012/01/07 23:46:53 tbox Exp $ $TTL 120 -@ SOA ns. hostmaster.ns. ( 1 3600 1200 604800 60 ) -@ NS ns. +. SOA ns. hostmaster.ns. ( 1 3600 1200 604800 60 ) + NS ns. ns. A 10.53.0.1 -. A 10.53.0.1 ; rewrite responses from this zone tld2. NS ns.tld2. @@ -34,3 +32,7 @@ ns.tld3. A 10.53.0.3 ; rewrite responses from this zone tld4. NS ns.tld4. ns.tld4. A 10.53.0.4 + +; performance test +tld5. NS ns.tld5. +ns.tld5. A 10.53.0.5 diff --git a/bin/tests/system/rpz/ns2/base-tld2s.db b/bin/tests/system/rpz/ns2/base-tld2s.db index 463f2cee3a..991a5040e4 100644 --- a/bin/tests/system/rpz/ns2/base-tld2s.db +++ b/bin/tests/system/rpz/ns2/base-tld2s.db @@ -12,7 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: base-tld2s.db,v 1.1.2.1 2012/02/24 17:22:37 vjs Exp $ ; RPZ rewrite responses from this signed zone diff --git a/bin/tests/system/rpz/ns2/hints b/bin/tests/system/rpz/ns2/hints index 849e2e3ab4..2393dd4992 100644 --- a/bin/tests/system/rpz/ns2/hints +++ b/bin/tests/system/rpz/ns2/hints @@ -1,4 +1,4 @@ -; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,8 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: hints,v 1.4 2011/10/13 01:32:33 vjs Exp $ - -. 0 NS ns1. -ns1. 0 A 10.53.0.1 +. 120 NS ns. +ns. 120 A 10.53.0.1 diff --git a/bin/tests/system/rpz/ns2/named.conf b/bin/tests/system/rpz/ns2/named.conf index a2fcd8254f..80f00f0c4d 100644 --- a/bin/tests/system/rpz/ns2/named.conf +++ b/bin/tests/system/rpz/ns2/named.conf @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.6 2012/01/07 23:46:53 tbox Exp $ */ controls { /* empty */ }; diff --git a/bin/tests/system/rpz/ns2/tld2.db b/bin/tests/system/rpz/ns2/tld2.db index 932a168581..a212c05e29 100644 --- a/bin/tests/system/rpz/ns2/tld2.db +++ b/bin/tests/system/rpz/ns2/tld2.db @@ -1,4 +1,4 @@ -; Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: tld2.db,v 1.4.4.2 2012/02/24 17:22:37 vjs Exp $ ; RPZ rewrite responses from this zone diff --git a/bin/tests/system/rpz/ns3/base.db b/bin/tests/system/rpz/ns3/base.db index 18710f90fd..c60181a5e8 100644 --- a/bin/tests/system/rpz/ns3/base.db +++ b/bin/tests/system/rpz/ns3/base.db @@ -1,4 +1,4 @@ -; Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: base.db,v 1.6.4.1 2011/10/15 23:03:38 vjs Exp $ ; RPZ test @@ -40,3 +39,10 @@ ns A 10.53.0.3 redirect A 127.0.0.1 *.redirect A 127.0.0.1 *.credirect CNAME google.com. + + +; names in the RPZ TLDs that some say should not be rewritten. +; This is not a bug, because any data leaked by writing 24.4.3.2.10.rpz-ip +; (or whatever) is available by publishing "foo A 10.2.3.4" and then +; resolving foo. +32.3.2.1.127.rpz-ip CNAME walled.invalid. diff --git a/bin/tests/system/rpz/ns3/crash1 b/bin/tests/system/rpz/ns3/crash1 index c241f75a21..d0862edc97 100644 --- a/bin/tests/system/rpz/ns3/crash1 +++ b/bin/tests/system/rpz/ns3/crash1 @@ -1,4 +1,4 @@ -; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: crash1,v 1.2 2011/10/13 04:53:06 marka Exp $ ; a bad zone that caused a crash related to dns_rdataset_disassociate() diff --git a/bin/tests/system/rpz/ns3/crash2 b/bin/tests/system/rpz/ns3/crash2 index cd613bce90..25f4fcf6c0 100644 --- a/bin/tests/system/rpz/ns3/crash2 +++ b/bin/tests/system/rpz/ns3/crash2 @@ -1,4 +1,4 @@ -; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: crash2,v 1.3 2011/11/18 19:32:13 each Exp $ ; a valid zone containing records that caused crashes diff --git a/bin/tests/system/rpz/ns3/hints b/bin/tests/system/rpz/ns3/hints index 849e2e3ab4..2393dd4992 100644 --- a/bin/tests/system/rpz/ns3/hints +++ b/bin/tests/system/rpz/ns3/hints @@ -1,4 +1,4 @@ -; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,8 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: hints,v 1.4 2011/10/13 01:32:33 vjs Exp $ - -. 0 NS ns1. -ns1. 0 A 10.53.0.1 +. 120 NS ns. +ns. 120 A 10.53.0.1 diff --git a/bin/tests/system/rpz/ns3/named.conf b/bin/tests/system/rpz/ns3/named.conf index 0906e7b32b..228632bb4a 100644 --- a/bin/tests/system/rpz/ns3/named.conf +++ b/bin/tests/system/rpz/ns3/named.conf @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.5 2011/10/28 11:46:50 marka Exp $ */ /* @@ -27,6 +26,7 @@ options { transfer-source 10.53.0.3; port 5300; pid-file "named.pid"; + statistics-file "named.stats"; session-keyfile "session.key"; listen-on { 10.53.0.3; }; listen-on-v6 { none; }; @@ -44,7 +44,7 @@ options { zone "bl-cname" policy cname txt-only.tld2.; zone "bl-wildcname" policy cname *.tld4.; zone "bl-garden" policy cname a12.tld2.; - }; + } min-ns-dots 0; }; key rndc_key { @@ -55,17 +55,6 @@ controls { inet 10.53.0.3 port 9953 allow { any; } keys { rndc_key; }; }; -logging { - # change "-c named.conf -d 99 -g" to "-c named.conf -d 99 -f" - # in ../start.pl to check the rpz log category - channel rpz { severity debug 10; - print-category yes; print-time yes; print-severity yes; - file "named.rpz";}; - category rpz { default_stderr; rpz; }; - category queries { default_stderr; rpz; }; - category query-errors { default_stderr; }; -}; - // include "../trusted.conf"; zone "." { type hint; file "hints"; }; diff --git a/bin/tests/system/rpz/ns4/hints b/bin/tests/system/rpz/ns4/hints index cbcff7c988..2393dd4992 100644 --- a/bin/tests/system/rpz/ns4/hints +++ b/bin/tests/system/rpz/ns4/hints @@ -1,4 +1,4 @@ -; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: hints,v 1.2 2011/10/13 04:53:06 marka Exp $ -. 0 NS ns1. -ns1. 0 A 10.53.0.1 +. 120 NS ns. +ns. 120 A 10.53.0.1 diff --git a/bin/tests/system/rpz/ns4/named.conf b/bin/tests/system/rpz/ns4/named.conf index 6828e86eb8..2ab7c3ca4c 100644 --- a/bin/tests/system/rpz/ns4/named.conf +++ b/bin/tests/system/rpz/ns4/named.conf @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.2.6.1 2012/02/24 17:22:37 vjs Exp $ */ controls { /* empty */ }; diff --git a/bin/tests/system/rpz/ns4/tld4.db b/bin/tests/system/rpz/ns4/tld4.db index 810189a037..5f94f494c4 100644 --- a/bin/tests/system/rpz/ns4/tld4.db +++ b/bin/tests/system/rpz/ns4/tld4.db @@ -1,4 +1,4 @@ -; Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: tld4.db,v 1.2.6.1 2012/02/24 17:22:37 vjs Exp $ ; RPZ rewrite responses from this zone diff --git a/bin/tests/system/rpz/ns5/hints b/bin/tests/system/rpz/ns5/hints index ae0e569e7f..2393dd4992 100644 --- a/bin/tests/system/rpz/ns5/hints +++ b/bin/tests/system/rpz/ns5/hints @@ -1,4 +1,4 @@ -; Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,8 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: hints,v 1.1.2.1 2011/10/15 23:00:04 vjs Exp $ - -. 0 NS ns1. -ns1. 0 A 10.53.0.1 +. 120 NS ns. +ns. 120 A 10.53.0.1 diff --git a/bin/tests/system/rpz/ns5/named.args b/bin/tests/system/rpz/ns5/named.args new file mode 100644 index 0000000000..acf35aef08 --- /dev/null +++ b/bin/tests/system/rpz/ns5/named.args @@ -0,0 +1,3 @@ +# run the performace test close to real life + +-c named.conf -g diff --git a/bin/tests/system/rpz/ns5/named.conf b/bin/tests/system/rpz/ns5/named.conf index 533dce8216..28c515c8f9 100644 --- a/bin/tests/system/rpz/ns5/named.conf +++ b/bin/tests/system/rpz/ns5/named.conf @@ -14,7 +14,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.1.2.2 2012/02/24 17:22:38 vjs Exp $ */ /* @@ -27,12 +26,13 @@ options { transfer-source 10.53.0.5; port 5300; pid-file "named.pid"; + statistics-file "named.stats"; session-keyfile "session.key"; listen-on { 10.53.0.5; }; listen-on-v6 { none; }; notify no; - # Eventually turn rpz on. + # turn rpz on or off include "rpz-switch"; }; @@ -40,12 +40,17 @@ key rndc_key { secret "1234abcd8765"; algorithm hmac-md5; }; -controls { inet 10.53.0.5 port 9953 allow { any; } keys { rndc_key; }; }; +controls { + inet 10.53.0.5 port 9953 allow { any; } keys { rndc_key; }; +}; include "../trusted.conf"; zone "." {type hint; file "hints"; }; -zone "example.com." {type master; file "example.db"; }; +zone "tld5." {type master; file "tld5.db"; }; +zone "example.tld5." {type master; file "example.db"; }; -zone "bl." {type master; file "bl.db"; }; +zone "bl0." {type master; file "bl.db"; }; +zone "bl1." {type master; file "bl.db"; }; +zone "bl2." {type master; file "bl.db"; }; diff --git a/bin/tests/system/rpz/ns5/tld5.db b/bin/tests/system/rpz/ns5/tld5.db new file mode 100644 index 0000000000..a40877a2f5 --- /dev/null +++ b/bin/tests/system/rpz/ns5/tld5.db @@ -0,0 +1,67 @@ +; Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + + + +; RPZ preformance test + +$TTL 120 +@ SOA . hostmaster.ns.example.tld5. ( 1 3600 1200 604800 60 ) + NS ns + NS ns1 + NS ns2 + NS ns3 + NS ns4 + NS ns5 + NS ns6 + NS ns7 + NS ns8 + NS ns9 + NS ns10 + NS ns11 + NS ns12 + NS ns13 + NS ns14 + NS ns15 + NS ns16 + NS ns17 + NS ns18 + NS ns19 +ns A 10.53.0.5 +ns1 A 10.53.0.5 +ns2 A 10.53.0.5 +ns3 A 10.53.0.5 +ns4 A 10.53.0.5 +ns5 A 10.53.0.5 +ns6 A 10.53.0.5 +ns7 A 10.53.0.5 +ns8 A 10.53.0.5 +ns9 A 10.53.0.5 +ns10 A 10.53.0.5 +ns11 A 10.53.0.5 +ns12 A 10.53.0.5 +ns13 A 10.53.0.5 +ns14 A 10.53.0.5 +ns15 A 10.53.0.5 +ns16 A 10.53.0.5 +ns17 A 10.53.0.5 +ns18 A 10.53.0.5 +ns19 A 10.53.0.5 + + +$ORIGIN example.tld5. +example.tld5. NS ns + NS ns1 +ns A 10.53.0.5 +ns1 A 10.53.0.5 diff --git a/bin/tests/system/rpz/qperf.sh b/bin/tests/system/rpz/qperf.sh index a823f1b690..c5877516fd 100644 --- a/bin/tests/system/rpz/qperf.sh +++ b/bin/tests/system/rpz/qperf.sh @@ -14,7 +14,6 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: qperf.sh,v 1.1.2.1 2011/10/15 23:03:37 vjs Exp $ for QDIR in `echo "$PATH" | tr : ' '` ../../../../contrib/queryperf; do QPERF=$QDIR/queryperf diff --git a/bin/tests/system/rpz/rpz.c b/bin/tests/system/rpz/rpz.c index 8a357ddbaf..2fae00a4f8 100644 --- a/bin/tests/system/rpz/rpz.c +++ b/bin/tests/system/rpz/rpz.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rpz.c,v 1.3.226.1 2011/10/15 23:03:37 vjs Exp $ */ #include diff --git a/bin/tests/system/rpz/setup.sh b/bin/tests/system/rpz/setup.sh index 1bc879c789..7da7a0e7f4 100644 --- a/bin/tests/system/rpz/setup.sh +++ b/bin/tests/system/rpz/setup.sh @@ -1,6 +1,6 @@ #! /bin/sh # -# Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,6 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: setup.sh,v 1.6 2012/01/07 23:46:53 tbox Exp $ set -e @@ -48,19 +47,22 @@ signzone ns2 tld2s. base-tld2s.db tld2s.db # Performance checks. -# First with rpz off. cat <ns5/rpz-switch -response-policy {zone "bl";} - recursive-only no - max-policy-ttl 90 - break-dnssec yes; +response-policy { + zone "bl0"; zone "bl1"; zone "bl2"; + } recursive-only no + max-policy-ttl 90 + # min-ns-dots 0 + break-dnssec yes; EOF cat <ns5/example.db \$TTL 120 -@ SOA . hostmaster.ns.example. ( 1 3600 1200 604800 60 ) +@ SOA . hostmaster.ns.example.tld5. ( 1 3600 1200 604800 60 ) NS ns + NS ns1 ns A 10.53.0.5 +ns1 A 10.53.0.5 EOF cat <ns5/bl.db @@ -71,31 +73,26 @@ ns A 10.53.0.5 ; used only in failure for "recursive-only no" in #8 test5 a3-5.tld2 CNAME *. -; for "break-dnssec" in #9 test5 +; for "break-dnssec" in #9 & #10 test5 a3-5.tld2s CNAME *. -; for "max-policy-ttl 90" in test5 +; for "max-policy-ttl 90" in #17 test5 a3-17.tld2 500 A 17.17.17.17 -; dummy NSDNAME policies to trigger lookups -ns-1.example.com.rpz-nsdname CNAME . -ns-2.example.com.rpz-nsdname CNAME . -ns-3.example.com.rpz-nsdname CNAME . -ns-4.example.com.rpz-nsdname CNAME . -ns-5.example.com.rpz-nsdname CNAME . +; dummy NSDNAME policy to trigger lookups +ns1.x.rpz-nsdname CNAME . EOF if test -n "$QPERF"; then # do not build the full zones if we will not use them to avoid the long # time otherwise required to shut down the server $PERL -e 'for ($val = 1; $val <= 65535; ++$val) { - printf("host-%d-%d\tA 192.168.%d.%d\n", - $val/256, $val%256, $val/256, $val%256); + printf("host-%05d\tA 192.168.%d.%d\n", $val, $val/256, $val%256); }' >>ns5/example.db echo >>ns5/bl.db echo "; rewrite some names" >>ns5/bl.db $PERL -e 'for ($val = 2; $val <= 65535; $val += 69) { - printf("host-%d.sub%d.example.com\tCNAME\t.\n", $val/256, $val%256); + printf("host-%05d.example.tld5\tCNAME\t.\n", $val); }' >>ns5/bl.db echo >>ns5/bl.db @@ -103,13 +100,11 @@ if test -n "$QPERF"; then $PERL -e 'for ($val = 3; $val <= 65535; $val += 69) { printf("32.%d.%d.168.192.rpz-ip \tCNAME\t.\n", $val%256, $val/256); - printf("32.%d.%d.168.192.rpz-nsip\tCNAME\t.\n", - ($val+1)%256, ($val+1)/256); }' >>ns5/bl.db fi # some psuedo-random queryperf requests -$PERL -e 'for ($cnt = $val = 1; $cnt <= 2000; ++$cnt) { - printf("host-%d.sub%d.example.com A\n", $val%256, $val/256); - $val = ($val * 9 + 32771) % 65536; +$PERL -e 'for ($cnt = $val = 1; $cnt <= 3000; ++$cnt) { + printf("host-%05d.example.tld5 A\n", $val); + $val = ($val * 9 + 32771) % 65536; }' >ns5/requests diff --git a/bin/tests/system/rpz/test1 b/bin/tests/system/rpz/test1 index aa885c3ed8..95c1c0b149 100644 --- a/bin/tests/system/rpz/test1 +++ b/bin/tests/system/rpz/test1 @@ -1,4 +1,4 @@ -; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: test1,v 1.8 2012/01/07 00:19:59 each Exp $ ; Use comment lines instead of blank lines to combine update requests into @@ -31,7 +30,7 @@ update add a0-1.tld2.bl. 300 CNAME . ; 3, 21 update add a3-1.tld2.bl. 300 CNAME *. ; and no assert-botch -; 5, 22 +; 4, 5, 22, 23 update add a3-2.tld2.bl. 300 DNAME example.com. ; ; NXDOMAIN for a4-2-cname.tld2 via its target a4-2.tld2. diff --git a/bin/tests/system/rpz/test2 b/bin/tests/system/rpz/test2 index 2a467af930..ff231fa980 100644 --- a/bin/tests/system/rpz/test2 +++ b/bin/tests/system/rpz/test2 @@ -1,4 +1,4 @@ -; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: test2,v 1.6 2011/11/18 19:32:13 each Exp $ ; Use comment lines instead of blank lines to combine update requests into @@ -45,7 +44,7 @@ update add 32.3.4.168.192.rpz-ip.bl 300 CNAME *. ; 9 update add 128.1.zz.3.2.2001.rpz-ip.bl 300 CNAME . ; -; apply the policy with the lexically smallest address of 192.168.5.1 +; apply the policy with the lexically smaller trigger address of 192.168.5.1 ; to an RRset of more than one A RR ; 11 update add 32.1.5.168.192.rpz-ip.bl 300 A 127.0.0.1 diff --git a/bin/tests/system/rpz/test3 b/bin/tests/system/rpz/test3 index fa8575f1b1..fe7ec0ba68 100644 --- a/bin/tests/system/rpz/test3 +++ b/bin/tests/system/rpz/test3 @@ -1,4 +1,4 @@ -; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: test3,v 1.5 2011/10/13 01:32:32 vjs Exp $ ; Use comment lines instead of blank lines to combine update requests into @@ -24,20 +23,24 @@ server 10.53.0.3 5300 +; 3, 4, 5 ; NXDOMAIN for *.sub1.tld2 by NSDNAME update add *.sub1.tld2.rpz-nsdname.bl. 300 CNAME . ; +; 6 ; walled garden for *.sub2.tld2 update add *.sub2.tld2.rpz-nsdname.bl. 300 CNAME a12-cname.tld2. ; +; 7, 8 ; exempt a3-2.tld2 and anything in 192.168.0.0/24 ; also checks that IP policies are preferred over NSDNAME policies update add a3-2.tld2.bl 300 CNAME a3-2.tld2. update add 24.0.0.168.192.rpz-ip.bl 300 CNAME 24.0.0.168.192. ; +; 9 ; prefer QNAME policy to NSDNAME policy update add a4-1.tld2.bl. 300 A 12.12.12.12 -; +; 10 ; prefer policy for largest NS name update add ns.sub3.tld2.rpz-nsdname.bl. 300 A 127.0.0.1 update add ns.subsub.sub3.tld2.rpz-nsdname.bl. 300 A 127.0.0.2 diff --git a/bin/tests/system/rpz/test4 b/bin/tests/system/rpz/test4 index 40bd83fa9d..d383362dfc 100644 --- a/bin/tests/system/rpz/test4 +++ b/bin/tests/system/rpz/test4 @@ -1,4 +1,4 @@ -; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: test4,v 1.5 2011/10/13 01:32:33 vjs Exp $ ; Use comment lines instead of blank lines to combine update requests into diff --git a/bin/tests/system/rpz/test4a b/bin/tests/system/rpz/test4a new file mode 100644 index 0000000000..7360f627a1 --- /dev/null +++ b/bin/tests/system/rpz/test4a @@ -0,0 +1,30 @@ +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + + + +; Use comment lines instead of blank lines to combine update requests into +; single requests +; Separate update requests for distinct TLDs with blank lines or 'send' +; End the file with a blank line or 'send' + +; walled-garden NSIP tests + +server 10.53.0.3 5300 + +; rewrite all of tld2 based on its server IP address +update add 32.2.0.53.10.rpz-nsip.bl. 300 A 41.41.41.41 +update add 32.2.0.53.10.rpz-nsip.bl. 300 AAAA 2041::41 +update add 32.2.0.53.10.rpz-nsip.bl. 300 TXT "NSIP walled garden" +send diff --git a/bin/tests/system/rpz/test5 b/bin/tests/system/rpz/test5 index a6510d30bd..42dbac8ba4 100644 --- a/bin/tests/system/rpz/test5 +++ b/bin/tests/system/rpz/test5 @@ -1,4 +1,4 @@ -; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") ; ; Permission to use, copy, modify, and/or distribute this software for any ; purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: test5,v 1.5.4.1 2012/02/24 17:22:37 vjs Exp $ ; Use comment lines instead of blank lines to combine update requests into diff --git a/bin/tests/system/rpz/tests.sh b/bin/tests/system/rpz/tests.sh index a669ed4c7b..8ffc7d8957 100644 --- a/bin/tests/system/rpz/tests.sh +++ b/bin/tests/system/rpz/tests.sh @@ -1,4 +1,4 @@ -# Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -12,7 +12,6 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.12 2012/01/07 23:46:53 tbox Exp $ # test response policy zones (RPZ) @@ -27,6 +26,8 @@ ns4=$ns.4 # another server that is rewritten ns5=$ns.5 # check performance with this server HAVE_CORE= +SAVE_RESULTS= +NS3_STATS=47 USAGE="$0: [-x]" while getopts "x" c; do @@ -43,11 +44,18 @@ fi # really quit on control-C trap 'exit 1' 1 2 15 +TS='%H:%M:%S ' +TS= +comment () { + if test -n "$TS"; then + date "+I:${TS}$*" + fi +} RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s" digcmd () { - digcmd_args="+noadd +nosearch +time=1 +tries=1 -p 5300 $*" + digcmd_args="+noadd +time=1 +tries=1 -p 5300 $*" expr "$digcmd_args" : '.*@' >/dev/null || \ digcmd_args="$digcmd_args @$ns3" expr "$digcmd_args" : '.*+[no]*auth' >/dev/null || \ @@ -70,13 +78,14 @@ make_dignm () { setret () { ret=1 + status=`expr $status + 1` echo "$*" } # (re)load the reponse policy zones with the rules in the file $TEST_FILE load_db () { if test -n "$TEST_FILE"; then - if $NSUPDATE -v $TEST_FILE; then : ; else + if ! $NSUPDATE -v $TEST_FILE; then echo "I:failed to update policy zone with $TEST_FILE" exit 1 fi @@ -122,10 +131,21 @@ ckalive () { return 1 } +# check that statistics for $1 in $2 = $3 +ckstats () { + $RNDCCMD $1 stats + CNT=`sed -n -e 's/[ ]*\([0-9]*\).response policy.*/\1/p' \ + $2/named.stats` + CNT=`expr 0$CNT + 0` + if test "$CNT" -ne $3; then + setret "I:wrong $2 statistics of $CNT instead of $3" + fi +} + # $1=message $2=optional test file name start_group () { ret=0 - test -n "$1" && echo "I:checking $1" + test -n "$1" && date "+I:${TS}checking $1" TEST_FILE=$2 if test -n "$TEST_FILE"; then GROUP_NM="-$TEST_FILE" @@ -138,33 +158,25 @@ start_group () { end_group () { if test -n "$TEST_FILE"; then + # remove the previous set of test rules sed -e 's/[ ]add[ ]/ delete /' $TEST_FILE | $NSUPDATE TEST_FILE= fi ckalive $ns3 "I:failed; ns3 server crashed and restarted" - if test "$status" -eq 0; then - # look for complaints from rpz.c - EMSGS=`grep -l 'invalid rpz' */*.run` - if test -n "$EMSGS"; then - setret "I:'invalid rpz' complaints in $EMSGS starting with:" - grep 'invalid rpz' */*.run | sed -e '4,$d' -e 's/^/I: /' - fi - # look for complaints from rpz.c and query.c - EMSGS=`grep -l 'rpz .*failed' */*.run` - if test -n "$EMSGS"; then - setret "I:'rpz failed' complaints in $EMSGS starting with:" - grep 'rpz .*failed' */*.run | sed -e '4,$d' -e 's/^/I: /' - fi - fi - status=`expr $status + $ret` GROUP_NM= } +clean_result () { + if test -z "$SAVE_RESULTS"; then + rm -f $* + fi +} + # $1=dig args $2=other dig output file ckresult () { #ckalive "$1" "I:server crashed by 'dig $1'" || return 1 if $PERL $SYSTEMTESTTOP/digcomp.pl $DIGNM $2 >/dev/null; then - rm -f ${DIGNM}* + clean_result ${DIGNM}* return 0 fi setret "I:'dig $1' wrong; diff $DIGNM $2" @@ -208,7 +220,7 @@ addr () { digcmd $2 >$DIGNM #ckalive "$2" "I:server crashed by 'dig $2'" || return 1 ADDR_ESC=`echo "$ADDR" | sed -e 's/\./\\\\./g'` - ADDR_TTL=`sed -n -e "s/^[-.a-z0-9]\{1,\} *\([0-9]*\) IN A\{1,4\} ${ADDR_ESC}\$/\1/p" $DIGNM` + ADDR_TTL=`sed -n -e "s/^[-.a-z0-9]\{1,\} *\([0-9]*\) IN AA* ${ADDR_ESC}\$/\1/p" $DIGNM` if test -z "$ADDR_TTL"; then setret "I:'dig $2' wrong; no address $ADDR record in $DIGNM" return 1 @@ -217,7 +229,7 @@ addr () { setret "I:'dig $2' wrong; TTL=$ADDR_TTL instead of $3 in $DIGNM" return 1 fi - rm -f ${DIGNM}* + clean_result ${DIGNM}* } # check that a response is not rewritten @@ -226,7 +238,7 @@ nochange () { make_dignm digcmd $* >$DIGNM digcmd $* @$ns2 >${DIGNM}_OK - ckresult "$*" ${DIGNM}_OK && rm -f ${DIGNM}_OK + ckresult "$*" ${DIGNM}_OK && clean_result ${DIGNM}_OK } # check against a 'here document' @@ -248,8 +260,8 @@ start_group "QNAME rewrites" test1 nochange . # 1 do not crash or rewrite root nxdomain a0-1.tld2 # 2 nodata a3-1.tld2 # 3 -nodata a3-2.tld2 # 4 no crash on DNAME -nodata sub.a3-2.tld2 +nodata a3-2.tld2 # 4 nodata at DNAME itself +nochange sub.a3-2.tld2 # 5 miss where DNAME might work nxdomain a4-2.tld2 # 6 rewrite based on CNAME target nxdomain a4-2-cname.tld2 # 7 nodata a4-3-cname.tld2 # 8 @@ -313,8 +325,9 @@ nochange a5-1-2.tld2 end_group if ./rpz nsdname; then + # these tests assume "min-ns-dots 0" start_group "NSDNAME rewrites" test3 - nochange a3-1.tld2 + nochange a3-1.tld2 # 1 nochange a3-1.tld2 +dnssec # 2 this once caused problems nxdomain a3-1.sub1.tld2 # 3 NXDOMAIN *.sub1.tld2 by NSDNAME nxdomain a3-1.subsub.sub1.tld2 @@ -327,19 +340,31 @@ if ./rpz nsdname; then addr 127.0.0.2 a3-1.subsub.sub3.tld2 nxdomain xxx.crash1.tld2 # 12 dns_db_detachnode() crash end_group + NS3_STATS=`expr $NS3_STATS + 7` else - echo "I:NSDNAME not checked; named not configured with --enable-rpz-nsdname" + echo "I:NSDNAME not checked; named configured with --disable-rpz-nsdname" fi if ./rpz nsip; then + # these tests assume "min-ns-dots 0" start_group "NSIP rewrites" test4 - nxdomain a3-1.tld2 # 1 NXDOMAIN for all of tld2 by NSIP + nxdomain a3-1.tld2 # 1 NXDOMAIN for all of tld2 nochange a3-2.tld2. # 2 exempt rewrite by name nochange a0-1.tld2. # 3 exempt rewrite by address block nochange a3-1.tld4 # 4 different NS IP address end_group + +# start_group "walled garden NSIP rewrites" test4a +# addr 41.41.41.41 a3-1.tld2 # 1 walled garden for all of tld2 +# addr 2041::41 'a3-1.tld2 AAAA' # 2 walled garden for all of tld2 +# here a3-1.tld2 TXT <<'EOF' # 3 text message for all of tld2 +# ;; status: NOERROR, x +# a3-1.tld2. x IN TXT "NSIP walled garden" +#EOF +# end_group + NS3_STATS=`expr $NS3_STATS + 1` else - echo "I:NSIP not checked; named not configured with --enable-rpz-nsip" + echo "I:NSIP not checked; named configured with --disable-rpz-nsip" fi # policies in ./test5 overridden by response-policy{} in ns3/named.conf @@ -377,6 +402,11 @@ for Q in RRSIG SIG ANY 'ANY +dnssec'; do nocrash www.redirect -t$Q nocrash www.credirect -t$Q done + +# This is not a bug, because any data leaked by writing 24.4.3.2.10.rpz-ip +# (or whatever) is available by publishing "foo A 10.2.3.4" and then +# resolving foo. +# nxdomain 32.3.2.1.127.rpz-ip end_group @@ -384,55 +414,56 @@ end_group QPERF=`sh qperf.sh` if test -n "$QPERF"; then perf () { - echo "I:checking performance $1" - # don't measure the costs of -d99 - $RNDCCMD $ns5 notrace >/dev/null - $QPERF -1 -l2 -d ns5/requests -s $ns5 -p 5300 >ns5/$2.perf + date "+I:${TS}checking performance $1" + # Dry run to prime everything + comment "before dry run $1" + $QPERF -c -1 -l30 -d ns5/requests -s $ns5 -p 5300 >/dev/null + comment "before real test $1" + PFILE="ns5/$2.perf" + $QPERF -c -1 -l30 -d ns5/requests -s $ns5 -p 5300 >$PFILE + comment "after test $1" + X=`sed -n -e 's/.*Returned *\([^ ]*:\) *\([0-9]*\) .*/\1\2/p' $PFILE \ + | tr '\n' ' '` + if test "$X" != "$3"; then + setret "I:wrong results '$X' in $PFILE" + fi ckalive $ns5 "I:failed; server #5 crashed" } trim () { sed -n -e 's/.*Queries per second: *\([0-9]*\).*/\1/p' ns5/$1.perf } - # Dry run to prime disk cache - # Otherwise a first test of either flavor is 25% low - perf 'to prime disk cache' rpz - - # get queries/second with rpz - perf 'with rpz' rpz - - # turn off rpz and measure queries/second again - # Don't wait for a clean stop. Clean stops of this server need seconds - # until the sockets are closed. 5 or 10 seconds after that, the - # server really stops and deletes named.pid. - echo "# rpz off" >ns5/rpz-switch - PID=`cat ns5/named.pid` - test -z "$PID" || kill -9 "$PID" - $PERL $SYSTEMTESTTOP/start.pl --noclean --restart . ns5 - perf 'without rpz' norpz - - # Don't wait for a clean stop. Clean stops of this server need seconds - # until the sockets are closed. 5 or 10 seconds after that, the - # server really stops and deletes named.pid. - echo "# rpz off" >ns5/rpz-switch - PID=`cat ns5/named.pid` - test -z "$PID" || kill -9 "$PID" && rm -f ns5/named.pid - - NORPZ=`trim norpz` + # get qps with rpz + perf 'with rpz' rpz 'NOERROR:2900 NXDOMAIN:100 ' RPZ=`trim rpz` - echo "I:$RPZ qps with RPZ versus $NORPZ qps without" - # fail if RPZ costs more than 100% - NORPZ2=`expr "$NORPZ" / 2` - if test "$RPZ" -le "$NORPZ2"; then - echo "I:rpz $RPZ qps too far below non-RPZ $NORPZ qps" - status=`expr $status + 1` + # turn off rpz and measure qps again + echo "# rpz off" >ns5/rpz-switch + RNDCCMD_OUT=`$RNDCCMD $ns5 reload` + perf 'without rpz' norpz 'NOERROR:3000 ' + NORPZ=`trim norpz` + + PERCENT=`expr \( "$RPZ" \* 100 + \( $NORPZ / 2 \) \) / $NORPZ` + echo "I:$RPZ qps with rpz is $PERCENT% of $NORPZ qps without rpz" + + MIN_PERCENT=30 + if test "$PERCENT" -lt $MIN_PERCENT; then + setret "I:$RPZ qps with rpz or $PERCENT% is below $MIN_PERCENT% of $NORPZ qps" fi + + if test "$PERCENT" -ge 100; then + setret "I:$RPZ qps with RPZ or $PERCENT% of $NORPZ qps without RPZ is too high" + fi + + ckstats $ns5 ns5 203 + else echo "I:performance not checked; queryperf not available" fi +ckstats $ns3 ns3 55 + # restart the main test RPZ server to see if that creates a core file if test -z "$HAVE_CORE"; then $PERL $SYSTEMTESTTOP/stop.pl . ns3 @@ -441,6 +472,12 @@ if test -z "$HAVE_CORE"; then test -z "$HAVE_CORE" || setret "I:found $HAVE_CORE; memory leak?" fi +# look for complaints from lib/dns/rpz.c and bin/name/query.c +EMSGS=`egrep -l 'invalid rpz|rpz.*failed' ns*/named.run` +if test -n "$EMSGS"; then + setret "I:error messages in $EMSGS starting with:" + egrep 'invalid rpz|rpz.*failed' ns*/named.run | sed -e '10,$d' -e 's/^/I: /' +fi echo "I:exit status: $status" exit $status diff --git a/configure b/configure index 4648b751cb..d7ea837a2f 100755 --- a/configure +++ b/configure @@ -2149,10 +2149,9 @@ Optional Features: [default=autodetect] --enable-fixed-rrset enable fixed rrset ordering [default=no] - --enable-rpz-nsip enable rpz-nsip rules [default=no] - --enable-rpz-nsdname enable rpz-nsdname rules [default=no] - --enable-filter-aaaa enable filtering of AAAA records over IPv4 - [default=no] + --disable-rpz-nsip disable rpz-nsip rules [default=enabled] + --disable-rpz-nsdname disable rpz-nsdname rules [default=enabled] + --enable-filter-aaaa enable filtering of AAAA records [default=no] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -11862,8 +11861,6 @@ yes) test "${enable_fixed_rrset+set}" = set || enable_fixed_rrset=yes test "${with_atf+set}" = set || with_atf=yes test "${enable_filter_aaaa+set}" = set || enable_filter_aaaa=yes - test "${enable_rpz_nsip+set}" = set || enable_rpz_nsip=yes - test "${enable_rpz_nsdname+set}" = set || enable_rpz_nsdname=yes test "${with_dlz_filesystem+set}" = set || with_dlz_filesystem=yes case "$host" in *-darwin*) @@ -18613,7 +18610,7 @@ esac if test "${enable_rpz_nsip+set}" = set; then : enableval=$enable_rpz_nsip; enable_nsip="$enableval" else - enable_nsip="no" + enable_nsip="yes" fi case "$enable_nsip" in @@ -18635,7 +18632,7 @@ esac if test "${enable_rpz_nsdname+set}" = set; then : enableval=$enable_rpz_nsdname; enable_nsdname="$enableval" else - enable_nsdname="no" + enable_nsdname="yes" fi case "$enable_nsdname" in diff --git a/configure.in b/configure.in index b522c183d1..f0a2b6f032 100644 --- a/configure.in +++ b/configure.in @@ -70,8 +70,6 @@ yes) test "${enable_fixed_rrset+set}" = set || enable_fixed_rrset=yes test "${with_atf+set}" = set || with_atf=yes test "${enable_filter_aaaa+set}" = set || enable_filter_aaaa=yes - test "${enable_rpz_nsip+set}" = set || enable_rpz_nsip=yes - test "${enable_rpz_nsdname+set}" = set || enable_rpz_nsdname=yes test "${with_dlz_filesystem+set}" = set || with_dlz_filesystem=yes case "$host" in *-darwin*) @@ -2963,9 +2961,9 @@ esac # Enable response policy rewriting using NS IP addresses # AC_ARG_ENABLE(rpz-nsip, - [ --enable-rpz-nsip enable rpz-nsip rules [[default=no]]], + [ --disable-rpz-nsip disable rpz-nsip rules [[default=enabled]]], enable_nsip="$enableval", - enable_nsip="no") + enable_nsip="yes") case "$enable_nsip" in yes) AC_DEFINE(ENABLE_RPZ_NSIP, 1, @@ -2981,9 +2979,9 @@ esac # Enable response policy rewriting using NS name # AC_ARG_ENABLE(rpz-nsdname, - [ --enable-rpz-nsdname enable rpz-nsdname rules [[default=no]]], + [ --disable-rpz-nsdname disable rpz-nsdname rules [[default=enabled]]], enable_nsdname="$enableval", - enable_nsdname="no") + enable_nsdname="yes") case "$enable_nsdname" in yes) AC_DEFINE(ENABLE_RPZ_NSDNAME, 1, diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 1ef0cbc77d..f6285ae339 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -5339,7 +5339,7 @@ badresp:1,adberr:0,findfail:0,valfail:0] policy given | disabled | passthru | nxdomain | nodata | cname domain recursive-only yes_or_no max-policy-ttl number ; } recursive-only yes_or_no max-policy-ttl number - break-dnssec yes_or_no ; + break-dnssec yes_or_no min-ns-dots number ; }; @@ -9620,14 +9620,15 @@ deny-answer-aliases { "example.net"; }; They are encoded as subdomains of rpz-nsdomain relativized to the RPZ origin name. - - - NSIP triggers match IP addresses in A and AAAA RRsets for domains that can be checked against NSDNAME policy records. NSIP triggers are encoded like IP triggers except as subdomains of rpz-nsip. + NSDNAME and NSIP triggers are checked only for names with at + least min-ns-dots dots. + The default value of min-ns-dots is 1 to + exclude top level domains. @@ -9666,17 +9667,6 @@ deny-answer-aliases { "example.net"; }; and addresses. - - Authority verification issues and variations in authority data - can cause inconsistent results for NSIP and NSDNAME policy records. - Glue NS records often differ from authoritative NS records. - So they are available - only when BIND is built with the - --enable-rpz-nsip or - --enable-rpz-nsdname options - on the "configure" command line. - - RPZ record sets are sets of any types of DNS record except DNAME or DNSSEC that encode actions or responses to queries. @@ -9815,20 +9805,26 @@ bzone.domain.com CNAME garden.example.com. ns.domain.com.rpz-nsdname CNAME . 48.zz.2.2001.rpz-nsip CNAME . - - Note: RPZ may impact server performance. Each configured - response policy zone requires the server to perform one to four - additional database lookups before a query can be answered. + + RPZ can affect server performance. + Each configured response policy zone requires the server to + perform one to four additional database lookups before a + query can be answered. For example, a DNS server with four policy zones, each with all - four kinds of response triggers — QNAME, IP, NSIP, and - NSDNAME — requires a total of 17 times as many database + four kinds of response triggers, QNAME, IP, NSIP, and + NSDNAME, requires a total of 17 times as many database lookups as a similar DNS server with no response policy zones. A BIND9 server with adequate memory and one response policy zone with QNAME and IP triggers might achieve a - maximum queries-per-second rate about 20% lower. A server with - four response policy zones with QNAME and IP triggers might - have a maximum QPS rate about 50% lower. - + maximum queries-per-second rate about 20% lower. + A server with four response policy zones with QNAME and IP + triggers might have a maximum QPS rate about 50% lower. + + + + Responses rewritten by RPZ are counted in the + RPZRewrites statistics. + @@ -14491,6 +14487,19 @@ HOST-127.EXAMPLE. MX 0 . + + + RPZRewrites + + + + + + + Response policy zone rewrites. + + + diff --git a/lib/dns/db.c b/lib/dns/db.c index 77547268e4..6b03b8c235 100644 --- a/lib/dns/db.c +++ b/lib/dns/db.c @@ -1007,11 +1007,12 @@ dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset, (db->methods->resigned)(db, rdataset, version); } -void +isc_result_t dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) { if (db->methods->rpz_enabled != NULL) - (db->methods->rpz_enabled)(db, st); + return ((db->methods->rpz_enabled)(db, st)); + return (ISC_R_SUCCESS); } void diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h index a5edbce24b..b0fe8fb1d2 100644 --- a/lib/dns/include/dns/db.h +++ b/lib/dns/include/dns/db.h @@ -172,7 +172,7 @@ typedef struct dns_dbmethods { dns_dbversion_t *version); isc_boolean_t (*isdnssec)(dns_db_t *db); dns_stats_t *(*getrrsetstats)(dns_db_t *db); - void (*rpz_enabled)(dns_db_t *db, dns_rpz_st_t *st); + isc_result_t (*rpz_enabled)(dns_db_t *db, dns_rpz_st_t *st); void (*rpz_findips)(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, dns_zone_t *zone, dns_db_t *db, @@ -1542,11 +1542,11 @@ dns_db_getrrsetstats(dns_db_t *db); * dns_rdatasetstats_create(); otherwise NULL. */ -void +isc_result_t dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st); /*%< - * See if a policy database has DNS_RPZ_TYPE_IP, DNS_RPZ_TYPE_NSIP, or - * DNS_RPZ_TYPE_NSDNAME records. + * Mark a database for response policy rewriting + * or find which RPZ data is available. */ void diff --git a/lib/dns/include/dns/rpz.h b/lib/dns/include/dns/rpz.h index 03db8d3312..4f88291bb5 100644 --- a/lib/dns/include/dns/rpz.h +++ b/lib/dns/include/dns/rpz.h @@ -14,7 +14,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rpz.h,v 1.5 2011/10/28 11:46:50 marka Exp $ */ #ifndef DNS_RPZ_H #define DNS_RPZ_H 1 @@ -27,10 +26,11 @@ ISC_LANG_BEGINDECLS -#define DNS_RPZ_IP_ZONE "rpz-ip" -#define DNS_RPZ_NSIP_ZONE "rpz-nsip" -#define DNS_RPZ_NSDNAME_ZONE "rpz-nsdname" -#define DNS_RPZ_PASSTHRU_ZONE "rpz-passthru" +#define DNS_RPZ_PREFIX "rpz-" +#define DNS_RPZ_IP_ZONE DNS_RPZ_PREFIX"ip" +#define DNS_RPZ_NSIP_ZONE DNS_RPZ_PREFIX"nsip" +#define DNS_RPZ_NSDNAME_ZONE DNS_RPZ_PREFIX"nsdname" +#define DNS_RPZ_PASSTHRU_ZONE DNS_RPZ_PREFIX"passthru" typedef isc_uint8_t dns_rpz_cidr_bits_t; @@ -75,6 +75,7 @@ struct dns_rpz_zone { dns_ttl_t max_policy_ttl; dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */ isc_boolean_t recursive_only; + isc_boolean_t defined; }; /* @@ -168,12 +169,6 @@ dns_rpz_str2policy(const char *str); const char * dns_rpz_policy2str(dns_rpz_policy_t policy); -void -dns_rpz_set_need(isc_boolean_t need); - -isc_boolean_t -dns_rpz_needed(void); - void dns_rpz_cidr_free(dns_rpz_cidr_t **cidr); @@ -184,7 +179,7 @@ isc_result_t dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin, dns_rpz_cidr_t **rbtdb_cidr); void -dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st); +dns_rpz_enabled_get(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st); void dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name); diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 0634dcebd4..233cca9c21 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -165,6 +165,7 @@ struct dns_view { ISC_LIST(dns_rpz_zone_t) rpz_zones; isc_boolean_t rpz_recursive_only; isc_boolean_t rpz_break_dnssec; + unsigned int rpz_min_ns_labels; /* * Configurable data for server use only, diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 00944e75ae..b83497b181 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -2068,6 +2069,15 @@ dns_zone_synckeyzone(dns_zone_t *zone); * maintenance timer. */ +isc_result_t +dns_zone_rpz_enable(dns_zone_t *zone); +/*% + * Set the response policy associated with a zone. + */ + +isc_boolean_t +dns_zone_get_rpz(dns_zone_t *zone); + ISC_LANG_ENDDECLS #endif /* DNS_ZONE_H */ diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 56053f5d71..74b4179649 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -1550,15 +1550,16 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, - "delete_nsecnode(): " + "delete_node(): " "dns_rbt_deletenode(nsecnode): %s", isc_result_totext(result)); } } - result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE); #ifdef BIND9 - dns_rpz_cidr_deleteip(rbtdb->rpz_cidr, name); + if (rbtdb->rpz_cidr != NULL) + dns_rpz_cidr_deleteip(rbtdb->rpz_cidr, name); #endif + result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE); break; case DNS_RBT_NSEC_NSEC: result = dns_rbt_deletenode(rbtdb->nsec, node, ISC_FALSE); @@ -1572,7 +1573,7 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, - "delete_nsecnode(): " + "delete_cnode(): " "dns_rbt_deletenode: %s", isc_result_totext(result)); } @@ -4547,19 +4548,29 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep, } /* - * Mark a database for response policy rewriting. + * Mark a database for response policy rewriting + * or find which RPZ data is available. */ #ifdef BIND9 -static void -get_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) +static isc_result_t +rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) { dns_rbtdb_t *rbtdb; + isc_result_t result; + result = ISC_R_SUCCESS; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); - dns_rpz_enabled(rbtdb->rpz_cidr, st); + if (st != NULL) { + dns_rpz_enabled_get(rbtdb->rpz_cidr, st); + } else { + result = dns_rpz_new_cidr(rbtdb->common.mctx, + &rbtdb->common.origin, + &rbtdb->rpz_cidr); + } RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); + return (result); } /* @@ -6863,7 +6874,7 @@ loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep, noderesult = dns_rbt_addnode(rbtdb->tree, name, nodep); #ifdef BIND9 - if (noderesult == ISC_R_SUCCESS) + if (noderesult == ISC_R_SUCCESS && rbtdb->rpz_cidr != NULL) dns_rpz_cidr_addip(rbtdb->rpz_cidr, name); #endif @@ -7450,7 +7461,7 @@ static dns_dbmethods_t zone_methods = { isdnssec, NULL, #ifdef BIND9 - get_rpz_enabled, + rpz_enabled, rpz_findips, #else NULL, @@ -7688,24 +7699,6 @@ dns_rbtdb_create return (result); } -#ifdef BIND9 - /* - * Get ready for response policy IP address searching if at least one - * zone has been configured as a response policy zone and this - * is not a cache zone. - * It would be better to know that this database is for a policy - * zone named for a view, but that would require knowledge from - * above such as an argv[] set from data in the zone. - */ - if (type == dns_dbtype_zone && !dns_name_equal(origin, dns_rootname)) { - result = dns_rpz_new_cidr(mctx, origin, &rbtdb->rpz_cidr); - if (result != ISC_R_SUCCESS) { - free_rbtdb(rbtdb, ISC_FALSE, NULL); - return (result); - } - } -#endif - /* * In order to set the node callback bit correctly in zone databases, * we need to know if the node has the origin name of the zone. diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c index 65c94baf83..97e6b32a30 100644 --- a/lib/dns/rpz.c +++ b/lib/dns/rpz.c @@ -14,7 +14,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ /*! \file */ @@ -123,8 +122,6 @@ struct dns_rpz_cidr { dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.origin */ }; -static isc_boolean_t have_rpz_zones = ISC_FALSE; - const char * dns_rpz_type2str(dns_rpz_type_t type) { switch (type) { @@ -266,21 +263,6 @@ dns_rpz_view_destroy(dns_view_t *view) { } } -/* - * Note that we have at least one response policy zone. - * It would be better for something to tell the rbtdb code that the - * zone is in at least one view's list of policy zones. - */ -void -dns_rpz_set_need(isc_boolean_t need) { - have_rpz_zones = need; -} - -isc_boolean_t -dns_rpz_needed(void) { - return (have_rpz_zones); -} - /* * Start a new radix tree for a response policy zone. */ @@ -293,12 +275,6 @@ dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin, REQUIRE(rbtdb_cidr != NULL && *rbtdb_cidr == NULL); - /* - * Only if there is at least one response policy zone. - */ - if (!have_rpz_zones) - return (ISC_R_SUCCESS); - cidr = isc_mem_get(mctx, sizeof(*cidr)); if (cidr == NULL) return (ISC_R_NOMEMORY); @@ -340,7 +316,7 @@ dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin, * See if a policy zone has IP, NSIP, or NSDNAME rules or records. */ void -dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) { +dns_rpz_enabled_get(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) { if (cidr == NULL) return; if (cidr->root != NULL && @@ -433,6 +409,9 @@ static void badname(int level, dns_name_t *name, const char *str1, const char *str2) { char printname[DNS_NAME_FORMATSIZE]; + /* + * bin/tests/system/rpz/tests.sh looks for "invalid rpz". + */ if (level < DNS_RPZ_DEBUG_QUIET && isc_log_wouldlog(dns_lctx, level)) { dns_name_format(name, printname, sizeof(printname)); @@ -957,8 +936,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) { dns_rpz_cidr_bits_t tgt_prefix; dns_rpz_type_t type; - if (cidr == NULL) - return; + REQUIRE(cidr != NULL); /* * No worries if the new name is not an IP address. @@ -986,6 +964,9 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) { { char printname[DNS_NAME_FORMATSIZE]; + /* + * bin/tests/system/rpz/tests.sh looks for "rpz.*failed". + */ dns_name_format(name, printname, sizeof(printname)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL, diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def index fd00e5ec86..b590a0b099 100644 --- a/lib/dns/win32/libdns.def +++ b/lib/dns/win32/libdns.def @@ -643,11 +643,9 @@ dns_rpz_cidr_deleteip dns_rpz_cidr_find dns_rpz_cidr_free dns_rpz_decode_cname -dns_rpz_enabled -dns_rpz_needed +dns_rpz_enabled_get dns_rpz_new_cidr dns_rpz_policy2str -dns_rpz_set_need dns_rpz_str2policy dns_rpz_type2str dns_rpz_view_destroy @@ -807,6 +805,7 @@ dns_zone_flush dns_zone_forcereload dns_zone_forwardupdate dns_zone_fulldumptostream +dns_zone_get_rpz dns_zone_getadded dns_zone_getchecknames dns_zone_getclass @@ -870,6 +869,7 @@ dns_zone_nscheck dns_zone_refresh dns_zone_rekey dns_zone_replacedb +dns_zone_rpz_enable dns_zone_setacache dns_zone_setadded dns_zone_setalsonotify diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 8e2dccfee6..ad67b30d99 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -345,9 +345,9 @@ struct dns_zone { isc_boolean_t added; /*% - * whether a rpz radix was needed when last loaded + * whether this is a response policy zone */ - isc_boolean_t rpz_zone; + isc_boolean_t is_rpz; /*% * Serial number update method. @@ -915,7 +915,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->nodes = 100; zone->privatetype = (dns_rdatatype_t)0xffffU; zone->added = ISC_FALSE; - zone->rpz_zone = ISC_FALSE; + zone->is_rpz = ISC_FALSE; ISC_LIST_INIT(zone->forwards); zone->raw = NULL; zone->secure = NULL; @@ -1507,6 +1507,31 @@ dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) { } +/* + * Set the response policy index and information for a zone. + */ +isc_result_t +dns_zone_rpz_enable(dns_zone_t *zone) { + /* + * Only RBTDB zones can be used for response policy zones, + * because only they have the code to load the create the summary data. + * Only zones that are loaded instead of mmap()ed create the + * summary data and so can be policy zones. + */ + if (strcmp(zone->db_argv[0], "rbt") != 0 && + strcmp(zone->db_argv[0], "rbt64") != 0) + return (ISC_R_NOTIMPLEMENTED); + + zone->is_rpz = ISC_TRUE; + + return (ISC_R_SUCCESS); +} + +isc_boolean_t +dns_zone_get_rpz(dns_zone_t *zone) { + return (zone->is_rpz); +} + static isc_result_t zone_load(dns_zone_t *zone, unsigned int flags) { isc_result_t result; @@ -1584,8 +1609,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) { * "rndc reconfig", we are done. */ if (!isc_time_isepoch(&zone->loadtime) && - (flags & DNS_ZONELOADFLAG_NOSTAT) != 0 && - zone->rpz_zone == dns_rpz_needed()) { + (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) { result = ISC_R_SUCCESS; goto cleanup; } @@ -1594,8 +1618,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) { if (result == ISC_R_SUCCESS) { if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) && - isc_time_compare(&filetime, &zone->loadtime) <= 0 && - zone->rpz_zone == dns_rpz_needed()) { + isc_time_compare(&filetime, &zone->loadtime) <= 0) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "skipping load: master file " "older than last load"); @@ -1603,7 +1626,6 @@ zone_load(dns_zone_t *zone, unsigned int flags) { goto cleanup; } loadtime = filetime; - zone->rpz_zone = dns_rpz_needed(); } } @@ -1963,8 +1985,15 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { isc_result_t tresult; unsigned int options; - options = get_master_options(zone); +#ifdef BIND9 + if (zone->is_rpz) { + result = dns_db_rpz_enabled(db, NULL); + if (result != ISC_R_SUCCESS) + return (result); + } +#endif + options = get_master_options(zone); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) options |= DNS_MASTER_MANYERRORS; diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 541f078b5b..784dd94457 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1030,10 +1030,9 @@ static cfg_type_t cfg_type_masterformat = { * response-policy { * zone [ policy (given|disabled|passthru| * nxdomain|nodata|cname ) ] - * [ recursive-only yes|no ] - * [ max-policy-ttl number ] ; - * } [ recursive-only yes|no ] [ break-dnssec yes|no ] - * [ max-policy-ttl number ] ; + * [ recursive-only yes|no ] [ max-policy-ttl number ] ; + * } [ recursive-only yes|no ] [ max-policy-ttl number ] ; + * [ break-dnssec yes|no ] [ min-ns-dots number ] ; */ static void @@ -1235,6 +1234,7 @@ static cfg_tuplefielddef_t rpz_fields[] = { { "recursive-only", &cfg_type_boolean, 0 }, { "break-dnssec", &cfg_type_boolean, 0 }, { "max-policy-ttl", &cfg_type_uint32, 0 }, + { "min-ns-dots", &cfg_type_uint32, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_rpz = {