mirror of
https://github.com/isc-projects/bind9.git
synced 2026-03-01 21:10:55 -05:00
For rt26172:
Add
- optional "recursive-only yes|no" to the response-policy statement
- optional max-policy-ttl to limit the lies that "recursive-only no"
can introduce into resolvers' caches
- test that queries with RD=0 are not rewritten by default
- performance smoke test
Change encoding of PASSTHRU action to "rpz-passthru".
(The old encoding is still accepted.)
Fix rt26180 assert botch in zone_findrdataset() in this branch
as well.
Fix missing signatures on NOERROR results despite RPZ hits
when there are signatures and the client asks for DNSSEC,
This commit is contained in:
parent
f011dfffca
commit
f05089ea5c
32 changed files with 1104 additions and 417 deletions
15
CHANGES
15
CHANGES
|
|
@ -1,3 +1,18 @@
|
|||
3330. [func] Fix missing signatures on NOERROR results despite
|
||||
RPZ rewriting. Also
|
||||
- add optional "recursive-only yes|no" to the
|
||||
response-policy statement
|
||||
- add optional "max-policy-ttl" to the response-policy
|
||||
statement to limit the false data that
|
||||
"recursive-only no" can introduce into
|
||||
resolvers' caches
|
||||
- add a RPZ performance test to bin/tests/system/rpz
|
||||
when queryperf is available.
|
||||
- the encoding of PASSTHRU action to "rpz-passthru".
|
||||
(The old encoding is still accepted.)
|
||||
[RT #26172]
|
||||
|
||||
|
||||
3329. [bug] Handle RRSIG signer-name case consistently: We
|
||||
generate RRSIG records with the signer-name in
|
||||
lower case. We accept them with any case, but if
|
||||
|
|
|
|||
|
|
@ -3845,6 +3845,13 @@ rpz_clean(dns_zone_t **zonep, dns_db_t **dbp, dns_dbnode_t **nodep,
|
|||
dns_rdataset_disassociate(*rdatasetp);
|
||||
}
|
||||
|
||||
static void
|
||||
rpz_match_clear(dns_rpz_st_t *st)
|
||||
{
|
||||
rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset);
|
||||
st->m.version = NULL;
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
rpz_ready(ns_client_t *client, dns_zone_t **zonep, dns_db_t **dbp,
|
||||
dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp)
|
||||
|
|
@ -3864,10 +3871,9 @@ static void
|
|||
rpz_st_clear(ns_client_t *client) {
|
||||
dns_rpz_st_t *st = client->query.rpz_st;
|
||||
|
||||
rpz_clean(&st->m.zone, &st->m.db, &st->m.node, NULL);
|
||||
st->m.version = NULL;
|
||||
if (st->m.rdataset != NULL)
|
||||
query_putrdataset(client, &st->m.rdataset);
|
||||
rpz_match_clear(st);
|
||||
|
||||
rpz_clean(NULL, &st->r.db, NULL, NULL);
|
||||
if (st->r.ns_rdataset != NULL)
|
||||
|
|
@ -4023,6 +4029,9 @@ rpz_rewrite_ip(ns_client_t *client, dns_rdataset_t *rdataset,
|
|||
for (rpz = ISC_LIST_HEAD(client->view->rpz_zones);
|
||||
rpz != NULL;
|
||||
rpz = ISC_LIST_NEXT(rpz, link)) {
|
||||
if (!RECURSIONOK(client) && rpz->recursive_only)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Do not check policy zones that cannot replace a policy
|
||||
* already known to match.
|
||||
|
|
@ -4051,9 +4060,8 @@ rpz_rewrite_ip(ns_client_t *client, dns_rdataset_t *rdataset,
|
|||
* hit, if any. Note the domain name and quality of the
|
||||
* best hit.
|
||||
*/
|
||||
(void)dns_db_rpz_findips(rpz, rpz_type, zone, db, version,
|
||||
rdataset, st,
|
||||
client->query.rpz_st->qname);
|
||||
dns_db_rpz_findips(rpz, rpz_type, zone, db, version,
|
||||
rdataset, st, client->query.rpz_st->qname);
|
||||
rpz_clean(&zone, &db, NULL, NULL);
|
||||
}
|
||||
return (ISC_R_SUCCESS);
|
||||
|
|
@ -4158,8 +4166,8 @@ rpz_rewrite_rrsets(ns_client_t *client, dns_rpz_type_t rpz_type,
|
|||
*/
|
||||
static isc_result_t
|
||||
rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
|
||||
dns_name_t *sname, dns_rpz_type_t rpz_type, dns_zone_t **zonep,
|
||||
dns_db_t **dbp, dns_dbversion_t **versionp,
|
||||
dns_name_t *sname, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
|
||||
dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp,
|
||||
dns_dbnode_t **nodep, dns_rdataset_t **rdatasetp,
|
||||
dns_rpz_policy_t *policyp)
|
||||
{
|
||||
|
|
@ -4204,7 +4212,7 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
|
|||
if (result != ISC_R_SUCCESS) {
|
||||
dns_db_detachnode(*dbp, nodep);
|
||||
rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, rpz_type,
|
||||
qnamef, "allrdatasets()", result);
|
||||
qnamef, "allrdatasets() ", result);
|
||||
*policyp = DNS_RPZ_POLICY_ERROR;
|
||||
return (DNS_R_SERVFAIL);
|
||||
}
|
||||
|
|
@ -4221,7 +4229,7 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
|
|||
if (result != ISC_R_SUCCESS) {
|
||||
if (result != ISC_R_NOMORE) {
|
||||
rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL,
|
||||
rpz_type, qnamef, "rdatasetiter",
|
||||
rpz_type, qnamef, "rdatasetiter ",
|
||||
result);
|
||||
*policyp = DNS_RPZ_POLICY_ERROR;
|
||||
return (DNS_R_SERVFAIL);
|
||||
|
|
@ -4249,7 +4257,7 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
|
|||
if ((*rdatasetp)->type != dns_rdatatype_cname) {
|
||||
policy = DNS_RPZ_POLICY_RECORD;
|
||||
} else {
|
||||
policy = dns_rpz_decode_cname(*rdatasetp, sname);
|
||||
policy = dns_rpz_decode_cname(rpz, *rdatasetp, sname);
|
||||
if ((policy == DNS_RPZ_POLICY_RECORD ||
|
||||
policy == DNS_RPZ_POLICY_WILDCNAME) &&
|
||||
qtype != dns_rdatatype_cname &&
|
||||
|
|
@ -4320,6 +4328,9 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
|||
for (rpz = ISC_LIST_HEAD(client->view->rpz_zones);
|
||||
rpz != NULL;
|
||||
rpz = ISC_LIST_NEXT(rpz, link)) {
|
||||
if (!RECURSIONOK(client) && rpz->recursive_only)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Do not check policy zones that cannot replace a policy
|
||||
* already known to match.
|
||||
|
|
@ -4365,11 +4376,11 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
|||
}
|
||||
|
||||
/*
|
||||
* See if the policy record exists.
|
||||
* See if the policy record exists and get its policy.
|
||||
*/
|
||||
result = rpz_find(client, qtype, rpz_qname, qname, rpz_type,
|
||||
&zone, &db, &version, &node, rdatasetp,
|
||||
&policy);
|
||||
result = rpz_find(client, qtype, rpz_qname, qname, rpz,
|
||||
rpz_type, &zone, &db, &version, &node,
|
||||
rdatasetp, &policy);
|
||||
switch (result) {
|
||||
case DNS_R_NXDOMAIN:
|
||||
case DNS_R_EMPTYNAME:
|
||||
|
|
@ -4405,8 +4416,7 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
|||
continue;
|
||||
}
|
||||
|
||||
rpz_clean(&st->m.zone, &st->m.db, &st->m.node,
|
||||
&st->m.rdataset);
|
||||
rpz_match_clear(st);
|
||||
st->m.rpz = rpz;
|
||||
st->m.type = rpz_type;
|
||||
st->m.prefix = 0;
|
||||
|
|
@ -4420,9 +4430,11 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
|||
trdataset = st->m.rdataset;
|
||||
st->m.rdataset = *rdatasetp;
|
||||
*rdatasetp = trdataset;
|
||||
st->m.ttl = st->m.rdataset->ttl;
|
||||
st->m.ttl = ISC_MIN(st->m.rdataset->ttl,
|
||||
rpz->max_policy_ttl);
|
||||
} else {
|
||||
st->m.ttl = DNS_RPZ_TTL_DEFAULT;
|
||||
st->m.ttl = ISC_MIN(DNS_RPZ_TTL_DEFAULT,
|
||||
rpz->max_policy_ttl);
|
||||
}
|
||||
st->m.node = node;
|
||||
node = NULL;
|
||||
|
|
@ -4517,13 +4529,13 @@ rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, isc_result_t qresult,
|
|||
case DNS_R_BROKENCHAIN:
|
||||
rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL3, DNS_RPZ_TYPE_QNAME,
|
||||
client->query.qname,
|
||||
"stop on qresult in rpz_rewrite()",
|
||||
"stop on qresult in rpz_rewrite() ",
|
||||
qresult);
|
||||
return (ISC_R_SUCCESS);
|
||||
default:
|
||||
rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, DNS_RPZ_TYPE_QNAME,
|
||||
client->query.qname,
|
||||
"stop on unrecognized qresult in rpz_rewrite()",
|
||||
"stop on unrecognized qresult in rpz_rewrite() ",
|
||||
qresult);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
|
@ -4702,10 +4714,11 @@ cleanup:
|
|||
if (st->m.policy == DNS_RPZ_POLICY_MISS ||
|
||||
st->m.policy == DNS_RPZ_POLICY_PASSTHRU ||
|
||||
st->m.policy == DNS_RPZ_POLICY_ERROR) {
|
||||
if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU)
|
||||
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_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset);
|
||||
rpz_match_clear(st);
|
||||
}
|
||||
if (st->m.policy == DNS_RPZ_POLICY_ERROR) {
|
||||
st->m.type = DNS_RPZ_TYPE_BAD;
|
||||
|
|
@ -4718,6 +4731,64 @@ cleanup:
|
|||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* See if response policy zone rewriting is allowed a lack of interest
|
||||
* by the client in DNSSEC or a lack of signatures.
|
||||
*/
|
||||
static isc_boolean_t
|
||||
rpz_ck_dnssec(ns_client_t *client, isc_result_t result,
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *found;
|
||||
dns_rdataset_t trdataset;
|
||||
dns_rdatatype_t type;
|
||||
|
||||
if (client->view->rpz_break_dnssec)
|
||||
return (ISC_TRUE);
|
||||
/*
|
||||
* sigrdataset == NULL if and only !WANTDNSSEC(client)
|
||||
*/
|
||||
if (sigrdataset == NULL)
|
||||
return (ISC_TRUE);
|
||||
if (dns_rdataset_isassociated(sigrdataset))
|
||||
return (ISC_FALSE);
|
||||
|
||||
/*
|
||||
* We are happy to rewrite nothing.
|
||||
*/
|
||||
if (rdataset == NULL || !dns_rdataset_isassociated(rdataset))
|
||||
return (ISC_TRUE);
|
||||
/*
|
||||
* Do not rewrite if there is any sign of signatures.
|
||||
*/
|
||||
if (rdataset->type == dns_rdatatype_nsec ||
|
||||
rdataset->type == dns_rdatatype_nsec3 ||
|
||||
rdataset->type == dns_rdatatype_rrsig)
|
||||
return (ISC_FALSE);
|
||||
|
||||
/*
|
||||
* Look for a signature in a negative cache rdataset.
|
||||
*/
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) == 0)
|
||||
return (ISC_TRUE);
|
||||
dns_fixedname_init(&fixed);
|
||||
found = dns_fixedname_name(&fixed);
|
||||
dns_rdataset_init(&trdataset);
|
||||
for (result = dns_rdataset_first(rdataset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(rdataset)) {
|
||||
dns_ncache_current(rdataset, found, &trdataset);
|
||||
type = trdataset.type;
|
||||
dns_rdataset_disassociate(&trdataset);
|
||||
if (type == dns_rdatatype_nsec ||
|
||||
type == dns_rdatatype_nsec3 ||
|
||||
type == dns_rdatatype_rrsig)
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a CNAME to the query response, including translating foo.evil.com and
|
||||
* *.evil.com CNAME *.example.com
|
||||
|
|
@ -4762,7 +4833,8 @@ rpz_add_cname(ns_client_t *client, dns_rpz_st_t *st,
|
|||
* Turn off DNSSEC because the results of a
|
||||
* response policy zone cannot verify.
|
||||
*/
|
||||
client->attributes &= ~NS_CLIENTATTR_WANTDNSSEC;
|
||||
client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
|
||||
DNS_MESSAGEFLAG_AD);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
@ -5681,9 +5753,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
CTRACE("query_find: resume");
|
||||
|
||||
if (!ISC_LIST_EMPTY(client->view->rpz_zones) &&
|
||||
RECURSIONOK(client) && !RECURSING(client) &&
|
||||
(!WANTDNSSEC(client) || sigrdataset == NULL ||
|
||||
!dns_rdataset_isassociated(sigrdataset)) &&
|
||||
(RECURSIONOK(client) || !client->view->rpz_recursive_only) &&
|
||||
rpz_ck_dnssec(client, result, rdataset, sigrdataset) &&
|
||||
!RECURSING(client) &&
|
||||
(client->query.rpz_st == NULL ||
|
||||
(client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0) &&
|
||||
!dns_name_equal(client->query.qname, dns_rootname)) {
|
||||
|
|
@ -5757,10 +5829,22 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
break;
|
||||
case DNS_RPZ_POLICY_RECORD:
|
||||
result = rpz_st->m.result;
|
||||
if (type == dns_rdatatype_any &&
|
||||
result != DNS_R_CNAME &&
|
||||
dns_rdataset_isassociated(rdataset))
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
if (qtype == dns_rdatatype_any &&
|
||||
result != DNS_R_CNAME) {
|
||||
/*
|
||||
* We will add all of the rdatasets of
|
||||
* the node by iterating, setting the
|
||||
* TTL then.
|
||||
*/
|
||||
if (dns_rdataset_isassociated(rdataset))
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
} else {
|
||||
/*
|
||||
* We will add this rdataset.
|
||||
*/
|
||||
rdataset->ttl = ISC_MIN(rdataset->ttl,
|
||||
rpz_st->m.ttl);
|
||||
}
|
||||
break;
|
||||
case DNS_RPZ_POLICY_WILDCNAME:
|
||||
result = dns_rdataset_first(rdataset);
|
||||
|
|
@ -5799,7 +5883,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
* Turn off DNSSEC because the results of a
|
||||
* response policy zone cannot verify.
|
||||
*/
|
||||
client->attributes &= ~NS_CLIENTATTR_WANTDNSSEC;
|
||||
client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC |
|
||||
DNS_MESSAGEFLAG_AD);
|
||||
query_putrdataset(client, &sigrdataset);
|
||||
is_zone = ISC_TRUE;
|
||||
rpz_log_rewrite(client, "", rpz_st->m.policy,
|
||||
|
|
@ -6747,6 +6832,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
noqname = rdataset;
|
||||
else
|
||||
noqname = NULL;
|
||||
rpz_st = client->query.rpz_st;
|
||||
if (rpz_st != NULL)
|
||||
rdataset->ttl = ISC_MIN(rdataset->ttl,
|
||||
rpz_st->m.ttl);
|
||||
query_addrrset(client,
|
||||
fname != NULL ? &fname : &tname,
|
||||
&rdataset, NULL,
|
||||
|
|
@ -7039,8 +7128,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
*/
|
||||
rpz_st = client->query.rpz_st;
|
||||
if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) == 0) {
|
||||
rpz_clean(&rpz_st->m.zone, &rpz_st->m.db, &rpz_st->m.node,
|
||||
&rpz_st->m.rdataset);
|
||||
rpz_match_clear(rpz_st);
|
||||
rpz_st->state &= ~DNS_RPZ_DONE_QNAME;
|
||||
}
|
||||
if (rdataset != NULL)
|
||||
|
|
|
|||
|
|
@ -1440,15 +1440,14 @@ cleanup:
|
|||
}
|
||||
|
||||
static isc_result_t
|
||||
configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
|
||||
const cfg_obj_t *rpz_obj, *policy_obj;
|
||||
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 char *str;
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *origin;
|
||||
dns_rpz_zone_t *old, *new;
|
||||
dns_zone_t *zone = NULL;
|
||||
isc_result_t result;
|
||||
unsigned int l1, l2;
|
||||
|
||||
new = isc_mem_get(view->mctx, sizeof(*new));
|
||||
if (new == NULL) {
|
||||
|
|
@ -1457,9 +1456,10 @@ configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
|
|||
}
|
||||
|
||||
memset(new, 0, sizeof(*new));
|
||||
dns_name_init(&new->nsdname, NULL);
|
||||
dns_name_init(&new->origin, NULL);
|
||||
dns_name_init(&new->nsdname, NULL);
|
||||
dns_name_init(&new->cname, NULL);
|
||||
dns_name_init(&new->passthru, NULL);
|
||||
ISC_LIST_INITANDAPPEND(view->rpz_zones, new, link);
|
||||
|
||||
rpz_obj = cfg_listelt_value(element);
|
||||
|
|
@ -1467,15 +1467,31 @@ configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
|
|||
if (cfg_obj_isvoid(policy_obj)) {
|
||||
new->policy = DNS_RPZ_POLICY_GIVEN;
|
||||
} else {
|
||||
str = cfg_obj_asstring(policy_obj);
|
||||
str = cfg_obj_asstring(cfg_tuple_get(policy_obj,
|
||||
"policy name"));
|
||||
new->policy = dns_rpz_str2policy(str);
|
||||
INSIST(new->policy != DNS_RPZ_POLICY_ERROR);
|
||||
}
|
||||
|
||||
dns_fixedname_init(&fixed);
|
||||
origin = dns_fixedname_name(&fixed);
|
||||
str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "name"));
|
||||
result = dns_name_fromstring(origin, str, DNS_NAME_DOWNCASE, NULL);
|
||||
obj = cfg_tuple_get(rpz_obj, "recursive-only");
|
||||
if (cfg_obj_isvoid(obj)) {
|
||||
new->recursive_only = recursive_only_def;
|
||||
} else {
|
||||
new->recursive_only = cfg_obj_asboolean(obj);
|
||||
}
|
||||
if (!new->recursive_only)
|
||||
view->rpz_recursive_only = ISC_FALSE;
|
||||
|
||||
obj = cfg_tuple_get(rpz_obj, "max-policy-ttl");
|
||||
if (cfg_obj_isuint32(obj)) {
|
||||
new->max_policy_ttl = cfg_obj_asuint32(obj);
|
||||
} else {
|
||||
new->max_policy_ttl = ttl_def;
|
||||
}
|
||||
|
||||
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) {
|
||||
cfg_obj_log(rpz_obj, ns_g_lctx, DNS_RPZ_ERROR_LEVEL,
|
||||
"invalid zone '%s'", str);
|
||||
|
|
@ -1483,31 +1499,28 @@ configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
|
|||
}
|
||||
|
||||
result = dns_name_fromstring2(&new->nsdname, DNS_RPZ_NSDNAME_ZONE,
|
||||
origin, DNS_NAME_DOWNCASE, view->mctx);
|
||||
&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;
|
||||
}
|
||||
|
||||
/*
|
||||
* The origin is part of 'nsdname' so we don't need to keep it
|
||||
* seperately.
|
||||
*/
|
||||
l1 = dns_name_countlabels(&new->nsdname);
|
||||
l2 = dns_name_countlabels(origin);
|
||||
dns_name_getlabelsequence(&new->nsdname, l1 - l2, l2, &new->origin);
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Are we configured to with the reponse policy zone?
|
||||
*/
|
||||
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,
|
||||
|
|
@ -1531,8 +1544,9 @@ configure_rpz(dns_view_t *view, const cfg_listelt_t *element) {
|
|||
}
|
||||
|
||||
if (new->policy == DNS_RPZ_POLICY_CNAME) {
|
||||
str = cfg_obj_asstring(cfg_tuple_get(rpz_obj, "cname"));
|
||||
result = dns_name_fromstring(&new->cname, str, 0, view->mctx);
|
||||
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);
|
||||
|
|
@ -2858,19 +2872,39 @@ 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.
|
||||
*/
|
||||
zonelist = NULL;
|
||||
if (view->rdclass == dns_rdataclass_in && need_hints) {
|
||||
obj = NULL;
|
||||
result = ns_config_get(maps, "response-policy", &obj);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
cfg_map_get(obj, "zone", &zonelist);
|
||||
}
|
||||
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;
|
||||
|
||||
if (zonelist != NULL) {
|
||||
for (element = cfg_list_first(zonelist);
|
||||
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);
|
||||
result = configure_rpz(view, element,
|
||||
recursive_only_def, ttl_def);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
dns_rpz_set_need(ISC_TRUE);
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
# Clean up after rpz tests.
|
||||
|
||||
rm -f proto.* dig.out* nsupdate.tmp
|
||||
rm -f */named.memstats */named.run */named.rpz */session.key
|
||||
rm -f ns3/bl*.db */*.jnl */*.core */*.pid
|
||||
rm -f ns2/signed-tld2.db
|
||||
rm -f ns2/K*.private ns2/K*.key dsset-*
|
||||
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 */*.jnl */*.core */*.pid
|
||||
|
|
|
|||
|
|
@ -23,12 +23,9 @@ ns. A 10.53.0.1
|
|||
; rewrite responses from this zone
|
||||
tld2. NS ns.tld2.
|
||||
ns.tld2. A 10.53.0.2
|
||||
ns2.tld2. A 10.53.0.2
|
||||
|
||||
; rewrite responses from this zone unless dnssec requested
|
||||
signed-tld2. NS ns.signed-tld2.
|
||||
ns.signed-tld2. A 10.53.0.2
|
||||
ns2.signed-tld2. A 10.53.0.2
|
||||
; rewrite responses from this secure zone unless dnssec requested (DO=1)
|
||||
tld2s. NS ns.tld2.
|
||||
|
||||
; requests come from here
|
||||
tld3. NS ns.tld3.
|
||||
|
|
@ -37,4 +34,3 @@ ns.tld3. A 10.53.0.3
|
|||
; rewrite responses from this zone
|
||||
tld4. NS ns.tld4.
|
||||
ns.tld4. A 10.53.0.4
|
||||
ns2.tld4. A 10.53.0.4
|
||||
|
|
|
|||
31
bin/tests/system/rpz/ns2/base-tld2s.db
Normal file
31
bin/tests/system/rpz/ns2/base-tld2s.db
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
; Copyright (C) 2011 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.
|
||||
|
||||
; $Id: base-tld2s.db,v 1.1.2.1 2012/02/24 17:22:37 vjs Exp $
|
||||
|
||||
|
||||
; RPZ rewrite responses from this signed zone
|
||||
|
||||
$TTL 120
|
||||
@ SOA tld2s. hostmaster.ns.tld2. ( 1 3600 1200 604800 60 )
|
||||
NS ns
|
||||
NS . ; check for RT 24985
|
||||
ns A 10.53.0.2
|
||||
|
||||
|
||||
a0-1 A 192.168.0.1
|
||||
a0-1-scname CNAME a0-1.tld2.
|
||||
|
||||
a3-5 A 192.168.3.5
|
||||
|
||||
|
|
@ -31,6 +31,7 @@ options {
|
|||
notify no;
|
||||
};
|
||||
|
||||
include "../trusted.conf";
|
||||
zone "." { type hint; file "hints"; };
|
||||
|
||||
zone "tld2." {type master; file "tld2.db";};
|
||||
|
|
@ -40,4 +41,5 @@ zone "sub2.tld2." {type master; file "tld2.db";};
|
|||
zone "subsub.sub2.tld2." {type master; file "tld2.db";};
|
||||
zone "sub3.tld2." {type master; file "tld2.db";};
|
||||
zone "subsub.sub3.tld2." {type master; file "tld2.db";};
|
||||
zone "signed-tld2." {type master; file "signed-tld2.db";};
|
||||
|
||||
zone "tld2s." {type master; file "tld2s.db";};
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
; PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
; $Id: tld2.db,v 1.4 2011/10/13 01:32:33 vjs Exp $
|
||||
; $Id: tld2.db,v 1.4.4.2 2012/02/24 17:22:37 vjs Exp $
|
||||
|
||||
|
||||
; RPZ rewrite responses from this zone
|
||||
|
|
@ -20,10 +20,8 @@
|
|||
$TTL 120
|
||||
@ SOA tld2. hostmaster.ns.tld2. ( 1 3600 1200 604800 60 )
|
||||
NS ns
|
||||
NS ns2
|
||||
NS . ; check for RT 24985
|
||||
ns A 10.53.0.2
|
||||
ns2 A 10.53.0.2
|
||||
|
||||
|
||||
txt-only TXT "txt-only-tld2"
|
||||
|
|
@ -36,6 +34,8 @@ a12-cname CNAME a12
|
|||
a0-1 A 192.168.0.1
|
||||
AAAA 2001:2::1
|
||||
TXT "a0-1 tld2 text"
|
||||
a0-1-scname CNAME a0-1.tld2s.
|
||||
|
||||
|
||||
a3-1 A 192.168.3.1
|
||||
AAAA 2001:2:3::1
|
||||
|
|
@ -115,3 +115,8 @@ a5-3 A 192.168.5.3
|
|||
|
||||
a5-4 A 192.168.5.4
|
||||
TXT "a5-4 tld2 text"
|
||||
|
||||
a6-1 A 192.168.6.1
|
||||
TXT "a6-1 tld2 text"
|
||||
a6-2 A 192.168.6.2
|
||||
TXT "a6-2 tld2 text"
|
||||
|
|
|
|||
|
|
@ -12,14 +12,17 @@
|
|||
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
; PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
; $Id: base.db,v 1.6 2011/10/13 01:32:33 vjs Exp $
|
||||
; $Id: base.db,v 1.6.4.1 2011/10/15 23:03:38 vjs Exp $
|
||||
|
||||
|
||||
; RPZ test
|
||||
; This basic file is copied to several zone files before being used.
|
||||
; Its contents are also changed with nsupdate
|
||||
|
||||
|
||||
$TTL 120
|
||||
@ SOA blx. hostmaster.ns.blx. ( 1 3600 1200 604800 60 )
|
||||
NS ns.tld.
|
||||
NS ns
|
||||
ns A 10.53.0.3
|
||||
|
||||
; Poke the radix tree a little.
|
||||
|
|
@ -34,6 +37,6 @@ ns A 10.53.0.3
|
|||
|
||||
|
||||
; regression testing for some old crashes
|
||||
redirect IN A 127.0.0.1
|
||||
*.redirect IN A 127.0.0.1
|
||||
*.credirect IN CNAME google.com.
|
||||
redirect A 127.0.0.1
|
||||
*.redirect A 127.0.0.1
|
||||
*.credirect CNAME google.com.
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ $TTL 120
|
|||
NS ns
|
||||
ns A 10.53.0.3
|
||||
|
||||
; #18 in test1, crashed new ASSERT() in rbtdb.c
|
||||
c1 A 172.16.1.1
|
||||
; #24 in test1, crashed new ASSERT() in rbtdb.c
|
||||
c1 A 172.16.1.24
|
||||
|
||||
; #16 in test2, crashed new ASSERT() in rbtdb.c
|
||||
c2 A 172.16.1.16
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
/* $Id: named.conf,v 1.5 2011/10/28 11:46:50 marka Exp $ */
|
||||
|
||||
|
||||
/*
|
||||
* Main rpz test DNS server.
|
||||
*/
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.3;
|
||||
notify-source 10.53.0.3;
|
||||
|
|
@ -29,13 +33,13 @@ options {
|
|||
notify no;
|
||||
|
||||
response-policy {
|
||||
zone "bl";
|
||||
zone "bl" max-policy-ttl 100;
|
||||
zone "bl-2";
|
||||
zone "bl-given" policy given;
|
||||
zone "bl-given" policy given recursive-only yes;
|
||||
zone "bl-passthru" policy passthru;
|
||||
zone "bl-no-op" policy no-op; # obsolete for passthru
|
||||
zone "bl-no-op" policy no-op; # obsolete for passthru
|
||||
zone "bl-disabled" policy disabled;
|
||||
zone "bl-nodata" policy nodata;
|
||||
zone "bl-nodata" policy nodata recursive-only no;
|
||||
zone "bl-nxdomain" policy nxdomain;
|
||||
zone "bl-cname" policy cname txt-only.tld2.;
|
||||
zone "bl-wildcname" policy cname *.tld4.;
|
||||
|
|
@ -63,6 +67,7 @@ logging {
|
|||
};
|
||||
|
||||
|
||||
// include "../trusted.conf";
|
||||
zone "." { type hint; file "hints"; };
|
||||
|
||||
zone "bl." {type master; file "bl.db";
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: named.conf,v 1.2 2011/10/13 04:53:06 marka Exp $ */
|
||||
/* $Id: named.conf,v 1.2.6.1 2012/02/24 17:22:37 vjs Exp $ */
|
||||
|
||||
controls { /* empty */ };
|
||||
|
||||
|
|
@ -30,6 +30,7 @@ options {
|
|||
notify no;
|
||||
};
|
||||
|
||||
include "../trusted.conf";
|
||||
zone "." { type hint; file "hints"; };
|
||||
|
||||
zone "tld4." {type master; file "tld4.db";};
|
||||
|
|
|
|||
|
|
@ -12,16 +12,14 @@
|
|||
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
; PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
; $Id: tld4.db,v 1.2 2011/10/13 04:53:07 marka Exp $
|
||||
; $Id: tld4.db,v 1.2.6.1 2012/02/24 17:22:37 vjs Exp $
|
||||
|
||||
; RPZ rewrite responses from this zone
|
||||
|
||||
$TTL 120
|
||||
@ SOA tld4. hostmaster.ns.tld4. ( 1 3600 1200 604800 60 )
|
||||
NS ns
|
||||
NS ns2
|
||||
ns A 10.53.0.4
|
||||
ns2 A 10.53.0.4
|
||||
|
||||
|
||||
txt-only TXT "txt-only-tld4"
|
||||
|
|
|
|||
19
bin/tests/system/rpz/ns5/hints
Normal file
19
bin/tests/system/rpz/ns5/hints
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
; Copyright (C) 2011 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.
|
||||
|
||||
; $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
|
||||
51
bin/tests/system/rpz/ns5/named.conf
Normal file
51
bin/tests/system/rpz/ns5/named.conf
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2011 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.
|
||||
*/
|
||||
|
||||
/* $Id: named.conf,v 1.1.2.2 2012/02/24 17:22:38 vjs Exp $ */
|
||||
|
||||
|
||||
/*
|
||||
* Test rpz performance.
|
||||
*/
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.5;
|
||||
notify-source 10.53.0.5;
|
||||
transfer-source 10.53.0.5;
|
||||
port 5300;
|
||||
pid-file "named.pid";
|
||||
session-keyfile "session.key";
|
||||
listen-on { 10.53.0.5; };
|
||||
listen-on-v6 { none; };
|
||||
notify no;
|
||||
|
||||
# Eventually turn rpz on.
|
||||
include "rpz-switch";
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-md5;
|
||||
};
|
||||
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 "bl." {type master; file "bl.db"; };
|
||||
27
bin/tests/system/rpz/qperf.sh
Normal file
27
bin/tests/system/rpz/qperf.sh
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#! /bin/sh
|
||||
#
|
||||
# Copyright (C) 2011 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.
|
||||
|
||||
# $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
|
||||
if test -f $QPERF -a -x $QPERF; then
|
||||
echo $QPERF
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rpz.c,v 1.3 2011/01/13 04:59:24 tbox Exp $ */
|
||||
/* $Id: rpz.c,v 1.3.226.1 2011/10/15 23:03:37 vjs Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ main(int argc, char **argv)
|
|||
#else
|
||||
return (1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[1], "nsdname")) {
|
||||
#ifdef ENABLE_RPZ_NSDNAME
|
||||
|
|
@ -47,8 +47,8 @@ main(int argc, char **argv)
|
|||
#else
|
||||
return (1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
fputs(USAGE, stderr);
|
||||
return (1);
|
||||
fputs(USAGE, stderr);
|
||||
return (1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#! /bin/sh
|
||||
#
|
||||
# Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
|
|
@ -16,16 +16,100 @@
|
|||
|
||||
# $Id: setup.sh,v 1.6 2012/01/07 23:46:53 tbox Exp $
|
||||
|
||||
set -e
|
||||
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
. ./clean.sh
|
||||
|
||||
# NO-OP is an obsolete synonym for PASSHTRU
|
||||
QPERF=`sh qperf.sh`
|
||||
|
||||
sh clean.sh
|
||||
|
||||
# set up test policy zones. bl-2 is used to check competing zones.
|
||||
# bl-{given,disabled,passthru,no-data,nxdomain,cname,wildcard,garden}
|
||||
# are used to check policy overrides in named.conf.
|
||||
# NO-OP is an obsolete synonym for PASSHTRU
|
||||
for NM in '' -2 -given -disabled -passthru -no-op -nodata -nxdomain -cname -wildcname -garden; do
|
||||
sed -e "/SOA/s/blx/bl$NM/g" ns3/base.db >ns3/bl$NM.db
|
||||
done
|
||||
|
||||
# sign the root and a zone in ns2
|
||||
../../../tools/genrandom 400 random.data
|
||||
$KEYGEN -Kns2 -q -r random.data -3 signed-tld2. > /dev/null 2>&1
|
||||
$KEYGEN -Kns2 -q -r random.data -3fk signed-tld2. > /dev/null 2>&1
|
||||
$SIGNER -S -Kns2 -o signed-tld2. -f ns2/signed-tld2.db ns2/tld2.db > /dev/null 2>&1
|
||||
|
||||
# $1=directory, $2=domain name, $3=input zone file, $4=output file
|
||||
signzone () {
|
||||
KEYNAME=`$KEYGEN -q -r random.data -b 512 -K $1 $2`
|
||||
cat $1/$3 $1/$KEYNAME.key > $1/tmp
|
||||
$SIGNER -Pp -K $1 -o $2 -f $1/$4 $1/tmp >/dev/null
|
||||
sed -n -e 's/\(.*\) IN DNSKEY \([0-9]\{1,\} [0-9]\{1,\} [0-9]\{1,\}\) \(.*\)/trusted-keys {"\1" \2 "\3";};/p' $1/$KEYNAME.key >>trusted.conf
|
||||
rm dsset-$2 $1/tmp
|
||||
}
|
||||
signzone ns2 tld2s. base-tld2s.db tld2s.db
|
||||
|
||||
|
||||
# Performance checks.
|
||||
# First with rpz off.
|
||||
cat <<EOF >ns5/rpz-switch
|
||||
response-policy {zone "bl";}
|
||||
recursive-only no
|
||||
max-policy-ttl 90
|
||||
break-dnssec yes;
|
||||
EOF
|
||||
|
||||
cat <<EOF >ns5/example.db
|
||||
\$TTL 120
|
||||
@ SOA . hostmaster.ns.example. ( 1 3600 1200 604800 60 )
|
||||
NS ns
|
||||
ns A 10.53.0.5
|
||||
EOF
|
||||
|
||||
cat <<EOF >ns5/bl.db
|
||||
\$TTL 120
|
||||
@ SOA . hostmaster.ns.blperf. ( 1 3600 1200 604800 60 )
|
||||
NS ns
|
||||
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
|
||||
a3-5.tld2s CNAME *.
|
||||
; for "max-policy-ttl 90" in 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 .
|
||||
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);
|
||||
}' >>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);
|
||||
}' >>ns5/bl.db
|
||||
|
||||
echo >>ns5/bl.db
|
||||
echo "; rewrite with some not entirely trivial patricia trees" >>ns5/bl.db
|
||||
$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;
|
||||
}' >ns5/requests
|
||||
|
|
|
|||
|
|
@ -25,13 +25,13 @@ server 10.53.0.3 5300
|
|||
; QNAME tests
|
||||
|
||||
; NXDOMAIN
|
||||
; 2, 20, 25
|
||||
update add a0-1.tld2.bl. 300 CNAME .
|
||||
update add a0-1.signed-tld2.bl. 300 CNAME .
|
||||
;
|
||||
; NODATA
|
||||
; 3, 21
|
||||
update add a3-1.tld2.bl. 300 CNAME *.
|
||||
; and no assert-botch
|
||||
; 5
|
||||
; 5, 22
|
||||
update add a3-2.tld2.bl. 300 DNAME example.com.
|
||||
;
|
||||
; NXDOMAIN for a4-2-cname.tld2 via its target a4-2.tld2.
|
||||
|
|
@ -57,24 +57,32 @@ update add nxc2.sub1.tld2.bl. 300 CNAME a12-cname.tld2.
|
|||
;
|
||||
; prefer the first conflicting zone
|
||||
; 13
|
||||
update add a4-4.tld2.bl. 300 A 127.0.0.1
|
||||
update add a4-4.tld2.bl. 300 A 127.4.4.1
|
||||
update add a6-1.tld2.bl. 300 CNAME a6-1.tld2.
|
||||
update add a6-2.tld2.bl. 300 A 127.6.2.1
|
||||
update add a6-1.tld2.bl. 300 A 127.6.1.1
|
||||
update add a6-2.tld2.bl. 300 CNAME a6-2.tld2.
|
||||
send
|
||||
update add a4-4.tld2.bl-2. 300 A 127.0.0.2
|
||||
update add a4-4.tld2.bl-2. 300 A 127.4.4.2
|
||||
send
|
||||
;
|
||||
|
||||
; wildcard CNAME
|
||||
; 14
|
||||
update add a3-6.tld2.bl. 300 CNAME *.tld4.
|
||||
; 15
|
||||
update add *.sub1.tld2.bl. 300 CNAME *.tld4.
|
||||
; CNAME chains
|
||||
; 16
|
||||
update add a4-5.tld2.bl. 300 A 127.0.0.16
|
||||
update add a3-6.tld2.bl. 300 CNAME *.tld4.
|
||||
; 17
|
||||
update add *.sub1.tld2.bl. 300 CNAME *.tld4.
|
||||
; CNAME chain
|
||||
; 18
|
||||
update add a4-5.tld2.bl. 300 A 127.0.0.16
|
||||
; stop at first hit in CNAME chain
|
||||
; 19
|
||||
update add a4-6.tld2.bl. 300 CNAME .
|
||||
update add a4-6-cname.tld2.bl. 300 A 127.0.0.17
|
||||
|
||||
; 18
|
||||
;
|
||||
; assert in rbtdb.c
|
||||
; 24
|
||||
update add c1.crash2.tld3.bl. 300 CNAME .
|
||||
|
||||
; DO=1 without signatures, DO=0 with signatures are rewritten
|
||||
; 26 - 27
|
||||
update add a0-1.tld2s.bl. 300 CNAME .
|
||||
send
|
||||
|
|
|
|||
|
|
@ -19,41 +19,54 @@
|
|||
; single requests
|
||||
; Separate update requests for distinct TLDs with blank lines or 'send'
|
||||
; End the file with a blank line or 'send'
|
||||
; CNAME targets are absolute even without trailing "."
|
||||
|
||||
; IP tests
|
||||
|
||||
server 10.53.0.3 5300
|
||||
|
||||
; NODATA a3-1.tld2
|
||||
; 1
|
||||
update add 32.1.3.168.192.rpz-ip.bl 300 CNAME *.
|
||||
;
|
||||
; NXDOMAIN for 192.168.4.0/24, the network of a4-1.tld2
|
||||
; NXDOMAIN for 192.168.4.0/24, the network of a4-1.tld2 and a4-2.tld2
|
||||
; 4
|
||||
update add 24.0.4.168.192.rpz-ip.bl 300 CNAME .
|
||||
;
|
||||
; poke hole in NXDOMAIN CIDR block to leave a4-1.tld2 unchanged
|
||||
; old passthru in NXDOMAIN CIDR block to leave a4-1.tld2 unchanged
|
||||
; 3
|
||||
update add 32.1.4.168.192.rpz-ip.bl 300 CNAME 32.1.4.168.192
|
||||
;
|
||||
; NODATA for a4-3.tld2
|
||||
; 8
|
||||
update add 32.3.4.168.192.rpz-ip.bl 300 CNAME *.
|
||||
;
|
||||
; NXDOMAIN for IPv6 a3-1.tld2
|
||||
; 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
|
||||
; 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
|
||||
update add 32.2.5.168.192.rpz-ip.bl 300 A 127.0.0.2
|
||||
;
|
||||
; prefer first conflicting IP zone for a5-3.tld2
|
||||
; 12
|
||||
update add 32.3.5.168.192.rpz-ip.bl 300 A 127.0.0.1
|
||||
send
|
||||
update add 32.3.5.168.192.rpz-ip.bl-2 300 A 127.0.0.2
|
||||
send
|
||||
|
||||
; prefer QNAME to IP for a5-4.tld2
|
||||
; 13
|
||||
update add 32.4.5.168.192.rpz-ip.bl 300 CNAME a12.tld2.
|
||||
update add a5-4.tld2.bl 300 CNAME a14.tld4.
|
||||
;
|
||||
; poke hole in NXDOMAIN CIDR block to leave a4-4.tld2 unchanged
|
||||
; 15
|
||||
update add 32.4.4.168.192.rpz-ip.bl 300 CNAME rpz-passthru.
|
||||
;
|
||||
; assert in rbtdb.c
|
||||
; 16
|
||||
update add 32.16.1.16.172.rpz-ip.bl 300 CNAME .
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
; PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
; $Id: test5,v 1.5 2011/10/13 01:32:33 vjs Exp $
|
||||
; $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
|
||||
|
|
@ -24,22 +24,37 @@
|
|||
|
||||
server 10.53.0.3 5300
|
||||
|
||||
; 1
|
||||
update add a3-1.tld2.bl-given. 300 A 127.0.0.1
|
||||
send
|
||||
; 2
|
||||
update add a3-2.tld2.bl-passthru. 300 A 127.0.0.2
|
||||
send
|
||||
; 3
|
||||
update add a3-3.tld2.bl-no-op. 300 A 127.0.0.3
|
||||
send
|
||||
; 4
|
||||
update add a3-4.tld2.bl-disabled. 300 A 127.0.0.4
|
||||
send
|
||||
; 5 - 8
|
||||
update add a3-5.tld2.bl-nodata. 300 A 127.0.0.5
|
||||
; 9 - 10
|
||||
update add a3-5.tld2s.bl-nodata. 300 A 127.0.0.9
|
||||
send
|
||||
update add a3-6.tld2.bl-nxdomain. 300 A 127.0.0.6
|
||||
; 11
|
||||
update add a3-6.tld2.bl-nxdomain. 300 A 127.0.0.11
|
||||
send
|
||||
update add a3-7.tld2.bl-cname. 300 A 127.0.0.7
|
||||
; 12
|
||||
update add a3-7.tld2.bl-cname. 300 A 127.0.0.12
|
||||
send
|
||||
update add a3-8.tld2.bl-wildcname. 300 A 127.0.0.8
|
||||
update add *.sub9.tld2.bl-wildcname. 300 A 127.0.1.9
|
||||
; 13
|
||||
update add a3-8.tld2.bl-wildcname. 300 A 127.0.0.13
|
||||
; 14
|
||||
update add *.sub9.tld2.bl-wildcname. 300 A 127.0.1.14
|
||||
send
|
||||
update add a3-10.tld2.bl-garden. 300 A 127.0.0.10
|
||||
; 15
|
||||
update add a3-15.tld2.bl-garden. 300 A 127.0.0.15
|
||||
send
|
||||
; 16
|
||||
update add a3-16.tld2.bl. 300 A 127.0.0.16
|
||||
send
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@
|
|||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
|
||||
ns1=10.53.0.1 # root, defining the other two
|
||||
ns2=10.53.0.2 # server whose answers are rewritten
|
||||
ns3=10.53.0.3 # resolve that does the rewriting
|
||||
ns4=10.53.0.4 # another server that is rewritten
|
||||
|
||||
RNDCCMD="$RNDC -c ../common/rndc.conf -s $ns3 -p 9953"
|
||||
ns=10.53.0
|
||||
ns1=$ns.1 # root, defining the others
|
||||
ns2=$ns.2 # server whose answers are rewritten
|
||||
ns3=$ns.3 # resolve that does the rewriting
|
||||
ns4=$ns.4 # another server that is rewritten
|
||||
ns5=$ns.5 # check performance with this server
|
||||
|
||||
HAVE_CORE=
|
||||
|
||||
|
|
@ -44,9 +44,18 @@ fi
|
|||
trap 'exit 1' 1 2 15
|
||||
|
||||
|
||||
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s"
|
||||
|
||||
digcmd () {
|
||||
#echo I:dig +noadd +noauth +nosearch +time=1 +tries=1 -p 5300 $* 1>&2
|
||||
$DIG +noadd +noauth +nosearch +time=1 +tries=1 -p 5300 $*
|
||||
digcmd_args="+noadd +nosearch +time=1 +tries=1 -p 5300 $*"
|
||||
if ! expr "$digcmd_args" : '.*@' >/dev/null; then
|
||||
digcmd_args="$digcmd_args @$ns3"
|
||||
fi
|
||||
if ! expr "$digcmd_args" : '.*+[no]*auth' >/dev/null; then
|
||||
digcmd_args="+noauth $digcmd_args"
|
||||
fi
|
||||
#echo I:dig $digcmd_args 1>&2
|
||||
$DIG $digcmd_args
|
||||
}
|
||||
|
||||
# set DIGNM=file name for dig output
|
||||
|
|
@ -77,20 +86,41 @@ load_db () {
|
|||
}
|
||||
|
||||
restart () {
|
||||
$RNDCCMD stop >/dev/null 2>&1
|
||||
rm -f ns3/*.jnl
|
||||
for NM in ns3/bl*.db; do
|
||||
cp -f ns3/base.db $NM
|
||||
done
|
||||
(cd ..; $PERL start.pl --noclean --restart rpz ns3)
|
||||
# try to ensure that the server really has stopped
|
||||
# and won't mess with ns$1/name.pid
|
||||
if test -z "$HAVE_CORE" -a -f ns$1/named.pid; then
|
||||
$RNDCCMD $ns$1 halt >/dev/null 2>&1
|
||||
if test -f ns$1/named.pid; then
|
||||
sleep 1
|
||||
PID=`cat ns$1/named.pid 2>/dev/null`
|
||||
if test -n "$PID"; then
|
||||
echo "I:killing ns$1 server $PID"
|
||||
kill -9 $PID
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
rm -f ns$1/*.jnl
|
||||
if test -f ns$1/base.db; then
|
||||
for NM in ns$1/bl*.db; do
|
||||
cp -f ns$1/base.db $NM
|
||||
done
|
||||
fi
|
||||
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart . ns$1
|
||||
load_db
|
||||
}
|
||||
|
||||
# $1=server and irrelevant args $2=error message
|
||||
ckalive () {
|
||||
$RNDCCMD status >/dev/null 2>&1 && return 0
|
||||
CKALIVE_NS=`expr "$1" : '.*@ns\([1-9]\).*'`
|
||||
if test -z "$CKALIVE_NS"; then
|
||||
CKALIVE_NS=3
|
||||
fi
|
||||
eval CKALIVE_IP=\$ns$CKALIVE_NS
|
||||
$RNDCCMD $CKALIVE_IP status >/dev/null 2>&1 && return 0
|
||||
HAVE_CORE=yes
|
||||
setret "$1"
|
||||
restart
|
||||
setret "$2"
|
||||
# restart the server to avoid stalling waiting for it to stop
|
||||
restart $CKALIVE_NS
|
||||
return 1
|
||||
}
|
||||
|
||||
|
|
@ -113,15 +143,29 @@ end_group () {
|
|||
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`
|
||||
ckalive "I:failed; server crashed"
|
||||
GROUP_NM=
|
||||
}
|
||||
|
||||
# $1=dig args $2=other dig output file
|
||||
ckresult () {
|
||||
#ckalive "I:server crashed by 'dig $1'" || return 1
|
||||
if $PERL ../digcomp.pl $DIGNM $2 >/dev/null; then
|
||||
#ckalive "$1" "I:server crashed by 'dig $1'" || return 1
|
||||
if $PERL $SYSTEMTESTTOP/digcomp.pl $DIGNM $2 >/dev/null; then
|
||||
rm -f ${DIGNM}*
|
||||
return 0
|
||||
fi
|
||||
|
|
@ -132,8 +176,8 @@ ckresult () {
|
|||
# check only that the server does not crash
|
||||
# $1=target domain $2=optional query type
|
||||
nocrash () {
|
||||
digcmd $* @$ns3 >/dev/null
|
||||
ckalive "I:server crashed by 'dig $*'"
|
||||
digcmd $* >/dev/null
|
||||
ckalive "$*" "I:server crashed by 'dig $*'"
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -141,8 +185,10 @@ nocrash () {
|
|||
# $1=target domain $2=optional query type
|
||||
nxdomain () {
|
||||
make_dignm
|
||||
digcmd +noauth $* @$ns3 \
|
||||
| sed -e 's/^[a-z].* IN CNAME /;xxx &/' >$DIGNM
|
||||
digcmd $* \
|
||||
| sed -e 's/^[a-z].* IN CNAME /;xxx &/' \
|
||||
-e 's/^[a-z].* IN RRSIG /;xxx &/' \
|
||||
>$DIGNM
|
||||
ckresult "$*" proto.nxdomain
|
||||
}
|
||||
|
||||
|
|
@ -150,33 +196,37 @@ nxdomain () {
|
|||
# $1=target domain $2=optional query type
|
||||
nodata () {
|
||||
make_dignm
|
||||
digcmd +noauth $* @$ns3 \
|
||||
digcmd $* \
|
||||
| sed -e 's/^[a-z].* IN CNAME /;xxx &/' >$DIGNM
|
||||
ckresult "$*" proto.nodata
|
||||
}
|
||||
|
||||
# check rewrite to an address
|
||||
# modify the output so that it is easily compared, but save the original line
|
||||
# $1=IPv4 address, $2=target domain $3=optional query type
|
||||
# $1=IPv4 address $2=digcmd args $3=optional TTL
|
||||
addr () {
|
||||
ADDR=$1
|
||||
shift
|
||||
ADDR_ESC=`echo "$ADDR" | sed -e 's/\./\\\\./g'`
|
||||
make_dignm
|
||||
digcmd +noauth $* @$ns3 >$DIGNM
|
||||
#ckalive "I:server crashed by 'dig $*'" || return
|
||||
if grep -i '^[a-z].* A '"$ADDR_ESC"'$' $DIGNM >/dev/null; then
|
||||
rm -f ${DIGNM}*
|
||||
return 0
|
||||
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`
|
||||
if test -z "$ADDR_TTL"; then
|
||||
setret "I:'dig $2' wrong; no address $ADDR record in $DIGNM"
|
||||
return 1
|
||||
fi
|
||||
setret "I:'dig $*' wrong; no A $ADDR record in $DIGNM $2"
|
||||
if test -n "$3" && test "$ADDR_TTL" -ne "$3"; then
|
||||
setret "I:'dig $2' wrong; TTL=$ADDR_TTL instead of $3 in $DIGNM"
|
||||
return 1
|
||||
fi
|
||||
rm -f ${DIGNM}*
|
||||
}
|
||||
|
||||
# check that a response is not rewritten
|
||||
# $1=target domain $2=optional query type
|
||||
nochange () {
|
||||
make_dignm
|
||||
digcmd $* @$ns3 >$DIGNM
|
||||
digcmd $* >$DIGNM
|
||||
digcmd $* @$ns2 >${DIGNM}_OK
|
||||
ckresult "$*" ${DIGNM}_OK && rm -f ${DIGNM}_OK
|
||||
}
|
||||
|
|
@ -185,23 +235,23 @@ nochange () {
|
|||
here () {
|
||||
make_dignm
|
||||
sed -e 's/^[ ]*//' >${DIGNM}_OK
|
||||
digcmd $* @$ns3 >$DIGNM
|
||||
digcmd $* >$DIGNM
|
||||
ckresult "$*" ${DIGNM}_OK
|
||||
}
|
||||
|
||||
# make prototype files to check against rewritten results
|
||||
digcmd +noauth nonexistent @$ns2 >proto.nxdomain
|
||||
digcmd +noauth txt-only.tld2 @$ns2 >proto.nodata
|
||||
digcmd nonexistent @$ns2 >proto.nxdomain
|
||||
digcmd txt-only.tld2 @$ns2 >proto.nodata
|
||||
|
||||
|
||||
status=0
|
||||
|
||||
start_group "QNAME rewrites" test1
|
||||
nochange .
|
||||
nxdomain a0-1.tld2
|
||||
nodata a3-1.tld2
|
||||
nodata a3-2.tld2
|
||||
nodata sub.a3-2.tld2 # 5 no crash on DNAME
|
||||
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
|
||||
nxdomain a4-2.tld2 # 6 rewrite based on CNAME target
|
||||
nxdomain a4-2-cname.tld2 # 7
|
||||
nodata a4-3-cname.tld2 # 8
|
||||
|
|
@ -209,32 +259,43 @@ addr 12.12.12.12 a4-1.sub1.tld2 # 9 A replacement
|
|||
addr 12.12.12.12 a4-1.sub2.tld2 # 10 A replacement with wildcard
|
||||
addr 12.12.12.12 nxc1.sub1.tld2 # 11 replace NXDOMAIN with CNAME
|
||||
addr 12.12.12.12 nxc2.sub1.tld2 # 12 replace NXDOMAIN with CNAME chain
|
||||
addr 127.0.0.1 a4-4.tld2 # 13 prefer 1st conflicting QNAME zone
|
||||
addr 56.56.56.56 a3-6.tld2 # 14 wildcard CNAME
|
||||
addr 57.57.57.57 a3-7.sub1.tld2 # 15 wildcard CNAME
|
||||
addr 127.0.0.16 a4-5-cname3.tld2 # 16 CNAME chain
|
||||
addr 127.0.0.17 a4-6-cname3.tld2 # 17 stop short in CNAME chain
|
||||
nxdomain c1.crash2.tld3 # 18 assert in rbtdb.c
|
||||
nochange a0-1.tld2 +norecurse
|
||||
nxdomain a0-1.tld2 +dnssec
|
||||
nxdomain a0-1.signed-tld2
|
||||
nochange a0-1.signed-tld2 +dnssec
|
||||
addr 127.4.4.1 a4-4.tld2 # 13 prefer 1st conflicting QNAME zone
|
||||
nochange a6-1.tld2 # 14
|
||||
addr 127.6.2.1 a6-2.tld2 # 15
|
||||
addr 56.56.56.56 a3-6.tld2 # 16 wildcard CNAME
|
||||
addr 57.57.57.57 a3-7.sub1.tld2 # 17 wildcard CNAME
|
||||
addr 127.0.0.16 a4-5-cname3.tld2 # 18 CNAME chain
|
||||
addr 127.0.0.17 a4-6-cname3.tld2 # 19 stop short in CNAME chain
|
||||
nochange a0-1.tld2 +norecurse # 20 check that RD=1 is required
|
||||
nochange a3-1.tld2 +norecurse # 21
|
||||
nochange a3-2.tld2 +norecurse # 22
|
||||
nochange sub.a3-2.tld2 +norecurse # 23
|
||||
nxdomain c1.crash2.tld3 # 24 assert in rbtdb.c
|
||||
nxdomain a0-1.tld2 +dnssec # 25 simple DO=1 without signatures
|
||||
nxdomain a0-1.tld2s # 26 simple DO=0 with signatures
|
||||
nochange a0-1.tld2s +dnssec # 27 simple DO=1 with signatures
|
||||
nxdomain a0-1s-cname.tld2s +dnssec # 28 DNSSEC too early in CNAME chain
|
||||
nochange a0-1-scname.tld2 +dnssec # 29 DNSSEC on target in CNAME chain
|
||||
nochange a0-1.tld2s srv +auth +dnssec # 30 no write for +DNSSEC and no record
|
||||
nxdomain a0-1.tld2s srv # 31
|
||||
end_group
|
||||
|
||||
start_group "IP rewrites" test2
|
||||
nodata a3-1.tld2
|
||||
nochange a3-2.tld2
|
||||
nochange a4-1.tld2
|
||||
nxdomain a4-2.tld2
|
||||
nochange a4-2.tld2 -taaaa
|
||||
nochange a4-2.tld2 -ttxt
|
||||
nxdomain a4-2.tld2 -tany
|
||||
nodata a4-3.tld2
|
||||
nxdomain a3-1.tld2 -tAAAA
|
||||
nochange a4-1-aaaa.tld2 -tAAAA
|
||||
nodata a3-1.tld2 # 1 NODATA
|
||||
nochange a3-2.tld2 # 2 no policy record so no change
|
||||
nochange a4-1.tld2 # 3 obsolete PASSTHRU record style
|
||||
nxdomain a4-2.tld2 # 4
|
||||
nochange a4-2.tld2 -taaaa # 5 no A => no policy rewrite
|
||||
nochange a4-2.tld2 -ttxt # 6 no A => no policy rewrite
|
||||
nxdomain a4-2.tld2 -tany # 7 no A => no policy rewrite
|
||||
nodata a4-3.tld2 # 8
|
||||
nxdomain a3-1.tld2 -taaaa # 9 IPv6 policy
|
||||
nochange a4-1-aaaa.tld2 -taaaa # 10
|
||||
addr 127.0.0.1 a5-1-2.tld2 # 11 prefer smallest policy address
|
||||
addr 127.0.0.1 a5-3.tld2 # 12 prefer first conflicting IP zone
|
||||
addr 14.14.14.14 a5-4.tld2 # 13 prefer QNAME to IP
|
||||
nochange a5-4.tld2 +norecurse # 14 check that RD=1 is required
|
||||
nochange a4-4.tld2 # 15 PASSTHRU
|
||||
nxdomain c2.crash2.tld3 # 16 assert in rbtdb.c
|
||||
end_group
|
||||
|
||||
|
|
@ -256,7 +317,7 @@ end_group
|
|||
if ./rpz nsdname; then
|
||||
start_group "NSDNAME rewrites" test3
|
||||
nochange a3-1.tld2
|
||||
nochange a3-1.tld2 +dnssec # 2 this once caused problems
|
||||
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
|
||||
nxdomain a3-1.subsub.sub1.tld2 -tany
|
||||
|
|
@ -284,21 +345,29 @@ else
|
|||
fi
|
||||
|
||||
# policies in ./test5 overridden by response-policy{} in ns3/named.conf
|
||||
# and in ns5/named.conf
|
||||
start_group "policy overrides" test5
|
||||
addr 127.0.0.1 a3-1.tld2 # 1 bl-given
|
||||
nochange a3-2.tld2 # 2 bl-passthru
|
||||
nochange a3-3.tld2 # 3 bl-no-op obsolete for passthru
|
||||
nochange a3-4.tld2 # 4 bl-disabled
|
||||
nodata a3-5.tld2 # 5 bl-nodata
|
||||
nxdomain a3-6.tld2 # 6 bl-nxdomain
|
||||
here +noauth a3-7.tld2 -tany <<'EOF' # 7 bl_cname
|
||||
nodata a3-5.tld2 +norecurse # 6 bl-nodata recursive-only no
|
||||
nodata a3-5.tld2 # 7 bl-nodata
|
||||
nodata a3-5.tld2 +norecurse @$ns5 # 8 bl-nodata recursive-only no
|
||||
nodata a3-5.tld2s @$ns5 # 9 bl-nodata
|
||||
nodata a3-5.tld2s +dnssec @$ns5 # 10 bl-nodata break-dnssec
|
||||
nxdomain a3-6.tld2 # 11 bl-nxdomain
|
||||
here a3-7.tld2 -tany <<'EOF'
|
||||
;; status: NOERROR, x
|
||||
a3-7.tld2. 300 IN CNAME txt-only.tld2.
|
||||
txt-only.tld2. 120 IN TXT "txt-only-tld2"
|
||||
a3-7.tld2. x IN CNAME txt-only.tld2.
|
||||
txt-only.tld2. x IN TXT "txt-only-tld2"
|
||||
EOF
|
||||
addr 58.58.58.58 a3-8.tld2 # 8 bl_wildcname
|
||||
addr 59.59.59.59 a3-9.sub9.tld2 # 9 bl_wildcname
|
||||
addr 12.12.12.12 a3-10.tld2 # 10 bl-garden
|
||||
addr 58.58.58.58 a3-8.tld2 # 13 bl_wildcname
|
||||
addr 59.59.59.59 a3-9.sub9.tld2 # 14 bl_wildcname
|
||||
addr 12.12.12.12 a3-15.tld2 # 15 bl-garden via CNAME to a12.tld2
|
||||
addr 127.0.0.16 a3-16.tld2 100 # 16 bl max-policy-ttl 100
|
||||
addr 17.17.17.17 "a3-17.tld2 @$ns5" 90 # 17 ns5 bl max-policy-ttl 90
|
||||
end_group
|
||||
|
||||
# check that miscellaneous bugs are still absent
|
||||
|
|
@ -312,12 +381,61 @@ for Q in RRSIG SIG ANY 'ANY +dnssec'; do
|
|||
done
|
||||
end_group
|
||||
|
||||
# restart the server to see if that creates a core file
|
||||
if test -z "$HAVE_CORE"; then
|
||||
$RNDCCMD halt
|
||||
restart
|
||||
test -s ns3/named.core && setret "I:found stray core file; memory leak?"
|
||||
|
||||
# superficial test for major performance bugs
|
||||
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
|
||||
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 close. 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
|
||||
|
||||
NORPZ=`trim norpz`
|
||||
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`
|
||||
fi
|
||||
else
|
||||
echo "I:performance not checked; queryperf not available"
|
||||
fi
|
||||
|
||||
|
||||
# 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
|
||||
restart 3
|
||||
HAVE_CORE=`find ns* -name '*core*' -print`
|
||||
test -z "$HAVE_CORE" || setret "I:found $HAVE_CORE; memory leak?"
|
||||
fi
|
||||
|
||||
|
||||
echo "I:exit status: $status"
|
||||
exit $status
|
||||
|
|
|
|||
|
|
@ -5313,7 +5313,11 @@ badresp:1,adberr:0,findfail:0,valfail:0]
|
|||
<optional> resolver-query-timeout <replaceable>number</replaceable> ; </optional>
|
||||
<optional> deny-answer-addresses { <replaceable>address_match_list</replaceable> } <optional> except-from { <replaceable>namelist</replaceable> } </optional>;</optional>
|
||||
<optional> deny-answer-aliases { <replaceable>namelist</replaceable> } <optional> except-from { <replaceable>namelist</replaceable> } </optional>;</optional>
|
||||
<optional> response-policy { <replaceable>zone_name</replaceable> <optional> policy given | disabled | passthru | nxdomain | nodata | cname <replaceable>domain</replaceable> </optional> ; } ; </optional>
|
||||
<optional> response-policy { <replaceable>zone_name</replaceable>
|
||||
<optional> policy given | disabled | passthru | nxdomain | nodata | cname <replaceable>domain</replaceable> </optional>
|
||||
<optional> recursive-only <replaceable>yes_or_no</replaceable> </optional> <optional> max-policy-ttl <replaceable>number</replaceable> </optional> ;
|
||||
} <optional> recursive-only <replaceable>yes_or_no</replaceable> </optional> <optional> max-policy-ttl <replaceable>number</replaceable> </optional>
|
||||
<optional> break-dnssec <replaceable>yes_or_no</replaceable> </optional> ; </optional>
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
|
|
@ -9446,17 +9450,15 @@ deny-answer-aliases { "example.net"; };
|
|||
<sect3>
|
||||
<title>Response Policy Zone (RPZ) Rewriting</title>
|
||||
<para>
|
||||
<acronym>BIND</acronym> 9 includes an intentionally limited
|
||||
mechanism to modify DNS responses for recursive requests
|
||||
somewhat similar to email anti-spam DNS blacklists.
|
||||
<acronym>BIND</acronym> 9 includes a limited
|
||||
mechanism to modify DNS responses for requests
|
||||
analogous to email anti-spam DNS blacklists.
|
||||
Responses can be changed to deny the existence of domains(NXDOMAIN),
|
||||
deny the existence of IP addresses for domains (NODATA),
|
||||
or contain other IP addresses or data.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The actions encoded in a response policy zone (RPZ) are applied
|
||||
only to queries that ask for recursion (RD=1).
|
||||
Response policy zones are named in the
|
||||
<command>response-policy</command> option for the view or among the
|
||||
global options if there is no response-policy option for the view.
|
||||
|
|
@ -9467,22 +9469,21 @@ deny-answer-aliases { "example.net"; };
|
|||
</para>
|
||||
|
||||
<para>
|
||||
There are four kinds of RPZ records, QNAME, IP, NSIP,
|
||||
Four policy triggers are encoded in RPZ records, QNAME, IP, NSIP,
|
||||
and NSDNAME.
|
||||
QNAME records are applied to query names of requests and targets
|
||||
QNAME RPZ records triggered by query names of requests and targets
|
||||
of CNAME records resolved to generate the response.
|
||||
The owner name of a QNAME RPZ record is the query name relativized
|
||||
to the RPZ.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The second kind of RPZ record, an IP policy record,
|
||||
is triggered by addresses in A and AAAA records
|
||||
for the ANSWER sections of responses.
|
||||
IP policy records have owner names that are
|
||||
subdomains of <userinput>rpz-ip</userinput> relativized to the
|
||||
RPZ origin name and encode an IP address or address block.
|
||||
IPv4 addresses are encoded as
|
||||
The second kind of RPZ trigger is an IP address in an A and AAAA
|
||||
record in the ANSWER section of a response.
|
||||
IP address triggers are encoded in records that have owner names
|
||||
that are subdomains of <userinput>rpz-ip</userinput> relativized
|
||||
to the RPZ origin name and encode an IP address or address block.
|
||||
IPv4 trigger addresses are represented as
|
||||
<userinput>prefixlength.B4.B3.B2.B1.rpz-ip</userinput>.
|
||||
The prefix length must be between 1 and 32.
|
||||
All four bytes, B4, B3, B2, and B1, must be present.
|
||||
|
|
@ -9501,43 +9502,45 @@ deny-answer-aliases { "example.net"; };
|
|||
</para>
|
||||
|
||||
<para>
|
||||
NSDNAME policy records match names of authoritative servers
|
||||
for the query name, a parent of the query name, a CNAME,
|
||||
or a parent of a CNAME.
|
||||
NSDNAME triggers match names of authoritative servers
|
||||
for the query name, a parent of the query name, a CNAME for
|
||||
query name, or a parent of a CNAME.
|
||||
They are encoded as subdomains of
|
||||
<userinput>rpz-nsdomain</userinput> relativized
|
||||
to the RPZ origin name.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
NSIP policy records match IP addresses in A and AAAA RRsets
|
||||
for domains that can be checked against NSDNAME policy records.
|
||||
The are encoded like IP policies except as subdomains of
|
||||
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
|
||||
<userinput>rpz-nsip</userinput>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The query response is checked against all RPZs, so
|
||||
two or more policy records can apply to a single response.
|
||||
Because DNS responses can be rewritten according by at most a
|
||||
single policy record, a single policy (other than
|
||||
<command>DISABLED</command> policies) must be chosen.
|
||||
Policies are chosen in the following order:
|
||||
two or more policy records can be triggered by a response.
|
||||
Because DNS responses can be rewritten according to at most one
|
||||
policy record, a single record encoding an action (other than
|
||||
<command>DISABLED</command> actions) must be chosen.
|
||||
Triggers or the records that encode them are chosen in
|
||||
the following order:
|
||||
<itemizedlist>
|
||||
<listitem>Among applicable zones, use the RPZ that appears first
|
||||
in the response-policy option.
|
||||
<listitem>Choose the triggered record in the zone that appears
|
||||
first in the response-policy option.
|
||||
</listitem>
|
||||
<listitem>Prefer QNAME to IP to NSDNAME to NSIP policy records
|
||||
in a single RPZ
|
||||
<listitem>Prefer QNAME to IP to NSDNAME to NSIP triggers
|
||||
in a single zone.
|
||||
</listitem>
|
||||
<listitem>Among applicable NSDNAME policy records, prefer the
|
||||
policy record that matches the lexically smallest name
|
||||
<listitem>Among NSDNAME triggers, prefer the
|
||||
trigger that matches the smallest name under the DNSSEC ordering.
|
||||
</listitem>
|
||||
<listitem>Among IP or NSIP policy records, prefer the record
|
||||
<listitem>Among IP or NSIP triggers, prefer the trigger
|
||||
with the longest prefix.
|
||||
</listitem>
|
||||
<listitem>Among records with the same prefex length,
|
||||
prefer the IP or NSIP policy record that matches
|
||||
<listitem>Among triggers with the same prefex length,
|
||||
prefer the IP or NSIP trigger that matches
|
||||
the smallest IP address.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
|
@ -9545,8 +9548,8 @@ deny-answer-aliases { "example.net"; };
|
|||
|
||||
<para>
|
||||
When the processing of a response is restarted to resolve
|
||||
DNAME or CNAME records and an applicable policy record set has
|
||||
not been found,
|
||||
DNAME or CNAME records and a policy record set has
|
||||
not been triggered,
|
||||
all RPZs are again consulted for the DNAME or CNAME names
|
||||
and addresses.
|
||||
</para>
|
||||
|
|
@ -9563,55 +9566,56 @@ deny-answer-aliases { "example.net"; };
|
|||
</para>
|
||||
|
||||
<para>
|
||||
RPZ record sets are special CNAME records or one or more
|
||||
of any types of DNS record except DNAME or DNSSEC.
|
||||
Except when a policy record is a CNAME, there can be more
|
||||
more than one record and more than one type
|
||||
in a set of policy records.
|
||||
Except for three kinds of CNAME records that are illegal except
|
||||
in policy zones, the records in a set are used in the response as if
|
||||
their owner name were the query name. They are copied to the
|
||||
response as dictated by their types.
|
||||
RPZ record sets are sets of any types of DNS record except
|
||||
DNAME or DNSSEC that encode actions or responses to queries.
|
||||
<itemizedlist>
|
||||
<listitem>A CNAME whose target is the root domain (.)
|
||||
specifies the <command>NXDOMAIN</command> policy,
|
||||
which generates an NXDOMAIN response.
|
||||
<listitem>The <command>NXDOMAIN</command> response is encoded
|
||||
by a CNAME whose target is the root domain (.)
|
||||
</listitem>
|
||||
<listitem>A CNAME whose target is the wildcard top-level
|
||||
domain (*.) specifies the <command>NODATA</command> policy,
|
||||
domain (*.) specifies the <command>NODATA</command> action,
|
||||
which rewrites the response to NODATA or ANCOUNT=1.
|
||||
</listitem>
|
||||
<listitem>A CNAME whose target is a wildcard hostname such
|
||||
as *.example.com is used normally after the astrisk (*)
|
||||
<listitem>The <command>Local Data</command> action is
|
||||
represented by a set ordinary DNS records that are used
|
||||
to answer queries. Queries for record types not the
|
||||
set are answered with NODATA.
|
||||
|
||||
A special form of local data is a CNAME whose target is a
|
||||
wildcard such as *.example.com.
|
||||
It is used as if were an ordinary CNAME after the astrisk (*)
|
||||
has been replaced with the query name.
|
||||
These records are usually resolved with ordinary CNAMEs
|
||||
outside the policy zones. They can be useful for logging.
|
||||
The purpose for this special form is query logging in the
|
||||
walled garden's authority DNS server.
|
||||
</listitem>
|
||||
<listitem>The <command>PASSTHRU</command> policy is specified
|
||||
by a CNAME whose target is the variable part of its own
|
||||
owner name. It causes the response to not be rewritten
|
||||
by a CNAME whose target is <command>rpz_passthru.</command>
|
||||
It causes the response to not be rewritten
|
||||
and is most often used to "poke holes" in policies for
|
||||
CIDR blocks.
|
||||
(A CNAME whose target is the variable part of its owner name
|
||||
is an obsolete specification of the PASSTHRU policy.)
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The policies specified in individual records
|
||||
in an RPZ can be overridden with a <command>policy</command> clause
|
||||
in the <command>response-policy</command> option.
|
||||
The actions specified in an RPZ can be overridden with a
|
||||
<command>policy</command> clause in the
|
||||
<command>response-policy</command> option.
|
||||
An organization using an RPZ provided by another organization might
|
||||
use this mechanism to redirect domains to its own walled garden.
|
||||
<itemizedlist>
|
||||
<listitem><command>GIVEN</command> says "do not override."
|
||||
<listitem><command>GIVEN</command> says "do not override but
|
||||
perform the action specified in the zone."
|
||||
</listitem>
|
||||
<listitem><command>DISABLED</command> causes policy records to do
|
||||
nothing but log what they might have done.
|
||||
The response to the DNS query will be written according to
|
||||
any matching policy records that are not disabled.
|
||||
Policy zones overridden with <command>DISABLED</command> should
|
||||
appear first, because they will often not be logged
|
||||
if a higher precedence policy is found first.
|
||||
any triggered policy records that are not disabled.
|
||||
Disabled policy zones should appear first,
|
||||
because they will often not be logged
|
||||
if a higher precedence trigger is found first.
|
||||
</listitem>
|
||||
<listitem><command>PASSTHRU</command> causes all policy records
|
||||
to act as if they were CNAME records with targets the variable
|
||||
|
|
@ -9630,6 +9634,37 @@ deny-answer-aliases { "example.net"; };
|
|||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
By default, the actions encoded in an RPZ are applied
|
||||
only to queries that ask for recursion (RD=1).
|
||||
That default can be changed for a single RPZ or all RPZs in a view
|
||||
with a <command>recursive-only no</command> clause.
|
||||
This feature is useful for serving the same zone files
|
||||
both inside and outside an RFC 1918 cloud and using RPZ to
|
||||
delete answers that would otherwise contain RFC 1918 values
|
||||
on the externally visible name server or view.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Also by default, RPZ actions are applied only to DNS requests that
|
||||
either do not request DNSSEC metadata (DO=0) or when no DNSSEC
|
||||
records are available for request name in the original zone (not
|
||||
the response policy zone).
|
||||
This default can be changed for all RPZs in a view with a
|
||||
<command>break-dnssec yes</command> clause.
|
||||
In that case, RPZ actions are applied regardless of DNSSEC.
|
||||
The name of the clause option reflects the fact that results
|
||||
rewritten by RPZ actions cannot verify.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The TTL of a record modified by RPZ policies is set from the
|
||||
TTL of the relevant record in policy zone. It is then limited
|
||||
to a maximum value.
|
||||
The <command>max-policy-ttl</command> clause changes that
|
||||
maximum from its default of 5.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For example, you might use this option statement
|
||||
</para>
|
||||
|
|
@ -9652,7 +9687,7 @@ bad.domain.com A 10.0.0.1 ; redirect to a walled garden
|
|||
AAAA 2001:2::1
|
||||
|
||||
; do not rewrite (PASSTHRU) OK.DOMAIN.COM
|
||||
ok.domain.com CNAME ok.domain.com.
|
||||
ok.domain.com CNAME rpz-passthru.
|
||||
|
||||
bzone.domain.com CNAME garden.example.com.
|
||||
|
||||
|
|
@ -9662,7 +9697,7 @@ bzone.domain.com CNAME garden.example.com.
|
|||
|
||||
; IP policy records that rewrite all answers for 127/8 except 127.0.0.1
|
||||
8.0.0.0.127.rpz-ip CNAME .
|
||||
32.1.0.0.127.rpz-ip CNAME 32.1.0.0.127. ; PASSTHRU for 127.0.0.1
|
||||
32.1.0.0.127.rpz-ip CNAME rpz-passthru.
|
||||
|
||||
; NSDNAME and NSIP policy records
|
||||
ns.domain.com.rpz-nsdname CNAME .
|
||||
|
|
|
|||
11
lib/dns/db.c
11
lib/dns/db.c
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: db.c,v 1.99 2011/10/13 01:32:33 vjs Exp $ */
|
||||
/* $Id: db.c,v 1.99.4.1 2011/10/23 20:12:07 vjs Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -1014,14 +1014,13 @@ dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
|
|||
(db->methods->rpz_enabled)(db, st);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
|
||||
dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
|
||||
dns_rdataset_t *ardataset, dns_rpz_st_t *st,
|
||||
dns_name_t *query_qname)
|
||||
{
|
||||
if (db->methods->rpz_findips == NULL)
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
return ((db->methods->rpz_findips)(rpz, rpz_type, zone, db, version,
|
||||
ardataset, st, query_qname));
|
||||
if (db->methods->rpz_findips != NULL)
|
||||
(db->methods->rpz_findips)(rpz, rpz_type, zone, db, version,
|
||||
ardataset, st, query_qname);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: db.h,v 1.107 2011/10/13 01:32:34 vjs Exp $ */
|
||||
/* $Id: db.h,v 1.107.4.1 2011/10/23 20:12:08 vjs Exp $ */
|
||||
|
||||
#ifndef DNS_DB_H
|
||||
#define DNS_DB_H 1
|
||||
|
|
@ -173,7 +173,7 @@ typedef struct dns_dbmethods {
|
|||
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_findips)(dns_rpz_zone_t *rpz,
|
||||
void (*rpz_findips)(dns_rpz_zone_t *rpz,
|
||||
dns_rpz_type_t rpz_type,
|
||||
dns_zone_t *zone, dns_db_t *db,
|
||||
dns_dbversion_t *version,
|
||||
|
|
@ -1545,7 +1545,7 @@ dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st);
|
|||
* DNS_RPZ_TYPE_NSDNAME records.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
void
|
||||
dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
|
||||
dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
|
||||
dns_rdataset_t *ardataset, dns_rpz_st_t *st,
|
||||
|
|
@ -1562,10 +1562,6 @@ dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
|
|||
* \li 'ardataset' is an A or AAAA rdataset of addresses to check
|
||||
* \li 'found' specifies the previous best match if any or
|
||||
* or NULL, an empty name, 0, DNS_RPZ_POLICY_MISS, and 0
|
||||
*
|
||||
* Returns:
|
||||
* \li #ISC_R_SUCCESS
|
||||
* \li #ISC_R_UNEXPECTED
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ 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"
|
||||
|
||||
typedef isc_uint8_t dns_rpz_cidr_bits_t;
|
||||
|
||||
|
|
@ -66,11 +67,14 @@ typedef struct dns_rpz_zone dns_rpz_zone_t;
|
|||
|
||||
struct dns_rpz_zone {
|
||||
ISC_LINK(dns_rpz_zone_t) link;
|
||||
int num;
|
||||
int num; /* ordinal in list of policy zones */
|
||||
dns_name_t origin; /* Policy zone name */
|
||||
dns_name_t nsdname; /* DNS_RPZ_NSDNAME_ZONE.origin */
|
||||
dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */
|
||||
dns_name_t passthru;/* DNS_RPZ_PASSTHRU_ZONE. */
|
||||
dns_name_t cname; /* override value for ..._CNAME */
|
||||
dns_ttl_t max_policy_ttl;
|
||||
dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */
|
||||
isc_boolean_t recursive_only;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -143,6 +147,7 @@ typedef struct {
|
|||
} dns_rpz_st_t;
|
||||
|
||||
#define DNS_RPZ_TTL_DEFAULT 5
|
||||
#define DNS_RPZ_MAX_TTL_DEFAULT DNS_RPZ_TTL_DEFAULT
|
||||
|
||||
/*
|
||||
* So various response policy zone messages can be turned up or down.
|
||||
|
|
@ -152,6 +157,7 @@ typedef struct {
|
|||
#define DNS_RPZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1)
|
||||
#define DNS_RPZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2)
|
||||
#define DNS_RPZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3)
|
||||
#define DNS_RPZ_DEBUG_QUIET (DNS_RPZ_DEBUG_LEVEL3+1)
|
||||
|
||||
const char *
|
||||
dns_rpz_type2str(dns_rpz_type_t type);
|
||||
|
|
@ -192,7 +198,8 @@ dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr,
|
|||
dns_name_t *search_name, dns_rpz_cidr_bits_t *prefix);
|
||||
|
||||
dns_rpz_policy_t
|
||||
dns_rpz_decode_cname(dns_rdataset_t *, dns_name_t *selfname);
|
||||
dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
|
||||
dns_name_t *selfname);
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,8 @@ struct dns_view {
|
|||
dns_dns64list_t dns64;
|
||||
unsigned int dns64cnt;
|
||||
ISC_LIST(dns_rpz_zone_t) rpz_zones;
|
||||
isc_boolean_t rpz_recursive_only;
|
||||
isc_boolean_t rpz_break_dnssec;
|
||||
|
||||
/*
|
||||
* Configurable data for server use only,
|
||||
|
|
|
|||
|
|
@ -4572,7 +4572,7 @@ get_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
|
|||
* configured earlier than this policy zone and does not have a higher
|
||||
* precedence type.
|
||||
*/
|
||||
static isc_result_t
|
||||
static void
|
||||
rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
|
||||
dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
|
||||
dns_rdataset_t *ardataset, dns_rpz_st_t *st,
|
||||
|
|
@ -4597,7 +4597,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
|
|||
|
||||
if (rbtdb->rpz_cidr == NULL) {
|
||||
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
return (ISC_R_UNEXPECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
dns_fixedname_init(&selfnamef);
|
||||
|
|
@ -4659,7 +4659,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
|
|||
dns_name_format(qname, namebuf, sizeof(namebuf));
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
|
||||
DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
|
||||
"rpz_findips findnode(%s): %s",
|
||||
"rpz_findips findnode(%s) failed: %s",
|
||||
namebuf, isc_result_totext(result));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -4680,7 +4680,8 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
|
|||
if (zrdataset.type != dns_rdatatype_cname) {
|
||||
rpz_policy = DNS_RPZ_POLICY_RECORD;
|
||||
} else {
|
||||
rpz_policy = dns_rpz_decode_cname(&zrdataset,
|
||||
rpz_policy = dns_rpz_decode_cname(rpz,
|
||||
&zrdataset,
|
||||
selfname);
|
||||
if (rpz_policy == DNS_RPZ_POLICY_RECORD ||
|
||||
rpz_policy == DNS_RPZ_POLICY_WILDCNAME)
|
||||
|
|
@ -4738,7 +4739,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
|
|||
st->m.type = rpz_type;
|
||||
st->m.prefix = prefix;
|
||||
st->m.policy = rpz_policy;
|
||||
st->m.ttl = ttl;
|
||||
st->m.ttl = ISC_MIN(ttl, rpz->max_policy_ttl);
|
||||
st->m.result = result;
|
||||
dns_name_copy(qname, st->qname, NULL);
|
||||
if ((rpz_policy == DNS_RPZ_POLICY_RECORD ||
|
||||
|
|
@ -4755,7 +4756,6 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
|
|||
}
|
||||
|
||||
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
129
lib/dns/rpz.c
129
lib/dns/rpz.c
|
|
@ -118,9 +118,9 @@ struct dns_rpz_cidr {
|
|||
isc_mem_t *mctx;
|
||||
isc_boolean_t have_nsdname; /* zone has NSDNAME record */
|
||||
dns_rpz_cidr_node_t *root;
|
||||
dns_name_t ip_name; /* RPZ_IP_ZONE.LOCALHOST. */
|
||||
dns_name_t nsip_name; /* RPZ_NSIP_ZONE.LOCALHOST. */
|
||||
dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.LOCALHOST */
|
||||
dns_name_t ip_name; /* RPZ_IP_ZONE.origin. */
|
||||
dns_name_t nsip_name; /* RPZ_NSIP_ZONE.origin. */
|
||||
dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.origin */
|
||||
};
|
||||
|
||||
static isc_boolean_t have_rpz_zones = ISC_FALSE;
|
||||
|
|
@ -183,7 +183,7 @@ dns_rpz_policy2str(dns_rpz_policy_t policy) {
|
|||
str = "NODATA";
|
||||
break;
|
||||
case DNS_RPZ_POLICY_RECORD:
|
||||
str = "records";
|
||||
str = "Local-Data";
|
||||
break;
|
||||
case DNS_RPZ_POLICY_CNAME:
|
||||
case DNS_RPZ_POLICY_WILDCNAME:
|
||||
|
|
@ -255,6 +255,8 @@ dns_rpz_view_destroy(dns_view_t *view) {
|
|||
ISC_LIST_UNLINK(view->rpz_zones, zone, link);
|
||||
if (dns_name_dynamic(&zone->origin))
|
||||
dns_name_free(&zone->origin, view->mctx);
|
||||
if (dns_name_dynamic(&zone->passthru))
|
||||
dns_name_free(&zone->passthru, view->mctx);
|
||||
if (dns_name_dynamic(&zone->nsdname))
|
||||
dns_name_free(&zone->nsdname, view->mctx);
|
||||
if (dns_name_dynamic(&zone->cname))
|
||||
|
|
@ -427,14 +429,16 @@ new_node(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *ip,
|
|||
}
|
||||
|
||||
static void
|
||||
badname(int level, dns_name_t *name, const char *comment) {
|
||||
badname(int level, dns_name_t *name, const char *str1, const char *str2) {
|
||||
char printname[DNS_NAME_FORMATSIZE];
|
||||
|
||||
if (isc_log_wouldlog(dns_lctx, level)) {
|
||||
if (level < DNS_RPZ_DEBUG_QUIET
|
||||
&& isc_log_wouldlog(dns_lctx, level)) {
|
||||
dns_name_format(name, printname, sizeof(printname));
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
|
||||
DNS_LOGMODULE_RBTDB, level,
|
||||
"invalid rpz \"%s\"%s", printname, comment);
|
||||
"invalid rpz IP address \"%s\"%s%s",
|
||||
printname, str1, str2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -566,11 +570,11 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
|
|||
dns_rpz_type_t type, dns_rpz_cidr_key_t *tgt_ip,
|
||||
dns_rpz_cidr_bits_t *tgt_prefix)
|
||||
{
|
||||
isc_buffer_t buffer;
|
||||
unsigned char data[DNS_NAME_MAXWIRE+1];
|
||||
isc_result_t result;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name;
|
||||
const char *cp, *end;
|
||||
dns_name_t *ipname;
|
||||
char ipstr[DNS_NAME_FORMATSIZE];
|
||||
const char *prefix_str, *cp, *end;
|
||||
char *cp2;
|
||||
int ip_labels;
|
||||
dns_rpz_cidr_bits_t bits;
|
||||
|
|
@ -585,37 +589,43 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
|
|||
ip_labels -= dns_name_countlabels(&cidr->ip_name);
|
||||
ip_labels--;
|
||||
if (ip_labels < 1) {
|
||||
badname(level, src_name, ", too short");
|
||||
badname(level, src_name, "; too short", "");
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get text for the IP address without RPZ_x_ZONE.rpz.LOCALHOST.
|
||||
* Get text for the IP address
|
||||
*/
|
||||
dns_fixedname_init(&fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
ipname = dns_fixedname_name(&fname);
|
||||
dns_name_split(src_name, dns_name_countlabels(&cidr->ip_name),
|
||||
name, NULL);
|
||||
isc_buffer_init(&buffer, data, sizeof(data));
|
||||
dns_name_totext(name, ISC_TRUE, &buffer);
|
||||
isc_buffer_putuint8(&buffer, '\0');
|
||||
cp = isc_buffer_base(&buffer);
|
||||
ipname, NULL);
|
||||
dns_name_format(ipname, ipstr, sizeof(ipstr));
|
||||
end = &ipstr[strlen(ipstr)+1];
|
||||
prefix_str = ipstr;
|
||||
|
||||
prefix = strtoul(cp, &cp2, 10);
|
||||
if (prefix < 1U || prefix > 128U || *cp2 != '.') {
|
||||
badname(level, src_name, ", bad prefix length");
|
||||
prefix = strtoul(prefix_str, &cp2, 10);
|
||||
if (*cp2 != '.') {
|
||||
badname(level, src_name,
|
||||
"; invalid leading prefix length", "");
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
*cp2 = '\0';
|
||||
if (prefix < 1U || prefix > 128U) {
|
||||
badname(level, src_name,
|
||||
"; invalid prefix length of ", prefix_str);
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
cp = cp2+1;
|
||||
|
||||
end = isc_buffer_used(&buffer);
|
||||
if (ip_labels == 4 && !strchr(cp, 'z')) {
|
||||
/*
|
||||
* Convert an IPv4 address
|
||||
* from the form "prefix.w.z.y.x"
|
||||
*/
|
||||
if (prefix > 32U) {
|
||||
badname(level, src_name, "; bad IPv4 prefix length");
|
||||
badname(level, src_name,
|
||||
"; invalid IPv4 prefix length of ", prefix_str);
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
prefix += 96;
|
||||
|
|
@ -627,7 +637,10 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
|
|||
for (i = 0; i < 32; i += 8) {
|
||||
l = strtoul(cp, &cp2, 10);
|
||||
if (l > 255U || (*cp2 != '.' && *cp2 != '\0')) {
|
||||
badname(level, src_name, "; bad IPv4 address");
|
||||
if (*cp2 == '.')
|
||||
*cp2 = '\0';
|
||||
badname(level, src_name,
|
||||
"; invalid IPv4 octet ", cp);
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
tgt_ip->w[3] |= l << i;
|
||||
|
|
@ -654,7 +667,10 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
|
|||
l = strtoul(cp, &cp2, 16);
|
||||
if (l > 0xffffu ||
|
||||
(*cp2 != '.' && *cp2 != '\0')) {
|
||||
badname(level, src_name, "");
|
||||
if (*cp2 == '.')
|
||||
*cp2 = '\0';
|
||||
badname(level, src_name,
|
||||
"; invalid IPv6 word ", cp);
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
if ((i & 1) == 0)
|
||||
|
|
@ -667,7 +683,7 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
|
|||
}
|
||||
}
|
||||
if (cp != end) {
|
||||
badname(level, src_name, "");
|
||||
badname(level, src_name, "", "");
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
|
|
@ -681,7 +697,8 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
|
|||
i = bits % DNS_RPZ_CIDR_WORD_BITS;
|
||||
aword = tgt_ip->w[bits / DNS_RPZ_CIDR_WORD_BITS];
|
||||
if ((aword & ~DNS_RPZ_WORD_MASK(i)) != 0) {
|
||||
badname(level, src_name, "; wrong prefix length");
|
||||
badname(level, src_name,
|
||||
"; too small prefix length of ", prefix_str);
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
bits -= i;
|
||||
|
|
@ -689,13 +706,13 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
|
|||
}
|
||||
|
||||
/*
|
||||
* Convert the IPv6 address back to a canonical policy domain name
|
||||
* Convert the address back to a canonical policy domain name
|
||||
* to ensure that it is in canonical form.
|
||||
*/
|
||||
if (ISC_R_SUCCESS != ip2name(cidr, tgt_ip, (dns_rpz_cidr_bits_t)prefix,
|
||||
type, NULL, name) ||
|
||||
!dns_name_equal(src_name, name)) {
|
||||
badname(level, src_name, "; not canonical");
|
||||
result = ip2name(cidr, tgt_ip, (dns_rpz_cidr_bits_t) prefix,
|
||||
type, NULL, ipname);
|
||||
if (result != ISC_R_SUCCESS || !dns_name_equal(src_name, ipname)) {
|
||||
badname(level, src_name, "; not canonical", "");
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
|
|
@ -934,6 +951,7 @@ search(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip,
|
|||
*/
|
||||
void
|
||||
dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
|
||||
isc_result_t result;
|
||||
dns_rpz_cidr_key_t tgt_ip;
|
||||
dns_rpz_cidr_bits_t tgt_prefix;
|
||||
dns_rpz_type_t type;
|
||||
|
|
@ -956,19 +974,22 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
|
|||
case DNS_RPZ_TYPE_BAD:
|
||||
return;
|
||||
}
|
||||
if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_ERROR_LEVEL, name,
|
||||
type, &tgt_ip, &tgt_prefix))
|
||||
result = name2ipkey(cidr, DNS_RPZ_ERROR_LEVEL, name,
|
||||
type, &tgt_ip, &tgt_prefix);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return;
|
||||
|
||||
if (ISC_R_EXISTS == search(cidr, &tgt_ip, tgt_prefix, type,
|
||||
ISC_TRUE, NULL) &&
|
||||
isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) {
|
||||
result = search(cidr, &tgt_ip, tgt_prefix, type, ISC_TRUE, NULL);
|
||||
if (result == ISC_R_EXISTS &&
|
||||
isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL))
|
||||
{
|
||||
char printname[DNS_NAME_FORMATSIZE];
|
||||
|
||||
dns_name_format(name, printname, sizeof(printname));
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
|
||||
DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
|
||||
"duplicate rpz name \"%s\"", printname);
|
||||
"rpz add failed; \"%s\" is a duplicate name",
|
||||
printname);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -978,6 +999,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
|
|||
*/
|
||||
void
|
||||
dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
|
||||
isc_result_t result;
|
||||
dns_rpz_cidr_key_t tgt_ip;
|
||||
dns_rpz_cidr_bits_t tgt_prefix;
|
||||
dns_rpz_type_t type;
|
||||
|
|
@ -1010,19 +1032,14 @@ dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
|
|||
/*
|
||||
* Do not get excited about the deletion of interior rbt nodes.
|
||||
*/
|
||||
if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_DEBUG_LEVEL3, name,
|
||||
type, &tgt_ip, &tgt_prefix))
|
||||
result = name2ipkey(cidr, DNS_RPZ_DEBUG_QUIET, name,
|
||||
type, &tgt_ip, &tgt_prefix);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return;
|
||||
if (ISC_R_SUCCESS != search(cidr, &tgt_ip, tgt_prefix, type,
|
||||
ISC_FALSE, &tgt)) {
|
||||
if (isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) {
|
||||
char printname[DNS_NAME_FORMATSIZE];
|
||||
|
||||
dns_name_format(name, printname, sizeof(printname));
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
|
||||
DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
|
||||
"missing rpz node \"%s\"", printname);
|
||||
}
|
||||
result = search(cidr, &tgt_ip, tgt_prefix, type, ISC_FALSE, &tgt);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
badname(DNS_RPZ_ERROR_LEVEL, name, "; missing rpz node", "");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1135,7 +1152,9 @@ dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr,
|
|||
* Translate CNAME rdata to a QNAME response policy action.
|
||||
*/
|
||||
dns_rpz_policy_t
|
||||
dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) {
|
||||
dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
|
||||
dns_name_t *selfname)
|
||||
{
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_cname_t cname;
|
||||
isc_result_t result;
|
||||
|
|
@ -1171,7 +1190,13 @@ dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) {
|
|||
}
|
||||
|
||||
/*
|
||||
* 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. means "do not rewrite"
|
||||
* CNAME PASSTHRU.origin means "do not rewrite.
|
||||
*/
|
||||
if (dns_name_equal(&cname.cname, &rpz->passthru))
|
||||
return (DNS_RPZ_POLICY_PASSTHRU);
|
||||
|
||||
/*
|
||||
* 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. is obsolete PASSTHRU
|
||||
*/
|
||||
if (selfname != NULL && dns_name_equal(&cname.cname, selfname))
|
||||
return (DNS_RPZ_POLICY_PASSTHRU);
|
||||
|
|
|
|||
|
|
@ -192,6 +192,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|||
view->v4_aaaa = dns_v4_aaaa_ok;
|
||||
view->v4_aaaa_acl = NULL;
|
||||
ISC_LIST_INIT(view->rpz_zones);
|
||||
view->rpz_recursive_only = ISC_TRUE;
|
||||
view->rpz_break_dnssec = ISC_FALSE;
|
||||
dns_fixedname_init(&view->dlv_fixed);
|
||||
view->managed_keys = NULL;
|
||||
view->redirect = NULL;
|
||||
|
|
|
|||
|
|
@ -1025,66 +1025,60 @@ static cfg_type_t cfg_type_masterformat = {
|
|||
|
||||
|
||||
|
||||
/*
|
||||
/*%
|
||||
* response-policy {
|
||||
* zone <string> [ policy (given|disabled|passthru|
|
||||
* nxdomain|nodata|cname <domain> ) ];
|
||||
* };
|
||||
*
|
||||
* this is a chimera of doc_optional_keyvalue() and cfg_doc_enum()
|
||||
* nxdomain|nodata|cname <domain> ) ]
|
||||
* [ recursive-only yes|no ]
|
||||
* [ max-policy-ttl number ] ;
|
||||
* } [ recursive-only yes|no ] [ break-dnssec yes|no ]
|
||||
* [ max-policy-ttl number ] ;
|
||||
*/
|
||||
|
||||
static void
|
||||
doc_rpz_policies(cfg_printer_t *pctx, const cfg_type_t *type) {
|
||||
const keyword_type_t *kw;
|
||||
doc_rpz_policy(cfg_printer_t *pctx, const cfg_type_t *type) {
|
||||
const char * const *p;
|
||||
|
||||
kw = type->of;
|
||||
cfg_print_chars(pctx, "[ ", 2);
|
||||
cfg_print_cstr(pctx, kw->name);
|
||||
cfg_print_chars(pctx, " ", 1);
|
||||
|
||||
/*
|
||||
* This is cfg_doc_enum() without the trailing " )".
|
||||
*/
|
||||
cfg_print_chars(pctx, "( ", 2);
|
||||
for (p = kw->type->of; *p != NULL; p++) {
|
||||
for (p = type->of; *p != NULL; p++) {
|
||||
cfg_print_cstr(pctx, *p);
|
||||
if (p[1] != NULL)
|
||||
cfg_print_chars(pctx, " | ", 3);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* print_qstring() from parser.c
|
||||
*/
|
||||
static void
|
||||
print_rpz_cname(cfg_printer_t *pctx, const cfg_obj_t *obj)
|
||||
{
|
||||
cfg_print_chars(pctx, "\"", 1);
|
||||
cfg_print_ustring(pctx, obj);
|
||||
cfg_print_chars(pctx, "\"", 1);
|
||||
}
|
||||
|
||||
static void
|
||||
doc_rpz_cname(cfg_printer_t *pctx, const cfg_type_t *type) {
|
||||
cfg_doc_terminal(pctx, type);
|
||||
cfg_print_chars(pctx, " ) ]", 4);
|
||||
cfg_print_chars(pctx, " )", 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse
|
||||
* given|disabled|passthru|nxdomain|nodata|cname <domain>
|
||||
*/
|
||||
static isc_result_t
|
||||
parse_rpz(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
cfg_parse_rpz_policy(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
cfg_obj_t **ret)
|
||||
{
|
||||
isc_result_t result;
|
||||
cfg_obj_t *obj = NULL;
|
||||
const cfg_tuplefielddef_t *fields = type->of;
|
||||
cfg_obj_t *obj;
|
||||
const cfg_tuplefielddef_t *fields;
|
||||
|
||||
CHECK(cfg_create_tuple(pctx, type, &obj));
|
||||
|
||||
fields = type->of;
|
||||
CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
|
||||
CHECK(cfg_parse_obj(pctx, fields[1].type, &obj->value.tuple[1]));
|
||||
/*
|
||||
* parse cname domain only after "policy cname"
|
||||
*/
|
||||
if (cfg_obj_isvoid(obj->value.tuple[1]) ||
|
||||
strcasecmp("cname", cfg_obj_asstring(obj->value.tuple[1]))) {
|
||||
CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[2]));
|
||||
if (strcasecmp("cname", cfg_obj_asstring(obj->value.tuple[0])) != 0) {
|
||||
CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1]));
|
||||
} else {
|
||||
CHECK(cfg_parse_obj(pctx, fields[2].type, &obj->value.tuple[2]));
|
||||
CHECK(cfg_parse_obj(pctx, fields[1].type,
|
||||
&obj->value.tuple[1]));
|
||||
}
|
||||
|
||||
*ret = obj;
|
||||
|
|
@ -1095,48 +1089,158 @@ cleanup:
|
|||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a tuple consisting of any kind of required field followed
|
||||
* by 2 or more optional keyvalues that can be in any order.
|
||||
*/
|
||||
static isc_result_t
|
||||
cfg_parse_kv_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
const cfg_tuplefielddef_t *fields, *f;
|
||||
cfg_obj_t *obj;
|
||||
int fn;
|
||||
isc_result_t result;
|
||||
|
||||
obj = NULL;
|
||||
CHECK(cfg_create_tuple(pctx, type, &obj));
|
||||
|
||||
/*
|
||||
* The zone first field is required and always first.
|
||||
*/
|
||||
fields = type->of;
|
||||
CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
|
||||
|
||||
for (;;) {
|
||||
CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
|
||||
if (pctx->token.type != isc_tokentype_string)
|
||||
break;
|
||||
|
||||
for (fn = 1, f = &fields[1]; ; ++fn, ++f) {
|
||||
if (f->name == NULL) {
|
||||
cfg_parser_error(pctx, 0, "unexpected '%s'",
|
||||
TOKEN_STRING(pctx));
|
||||
result = ISC_R_UNEXPECTEDTOKEN;
|
||||
goto cleanup;
|
||||
}
|
||||
if (obj->value.tuple[fn] == NULL &&
|
||||
strcasecmp(f->name, TOKEN_STRING(pctx)) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
CHECK(cfg_gettoken(pctx, 0));
|
||||
CHECK(cfg_parse_obj(pctx, f->type, &obj->value.tuple[fn]));
|
||||
}
|
||||
|
||||
for (fn = 1, f = &fields[1]; f->name != NULL; ++fn, ++f) {
|
||||
if (obj->value.tuple[fn] == NULL)
|
||||
CHECK(cfg_parse_void(pctx, NULL,
|
||||
&obj->value.tuple[fn]));
|
||||
}
|
||||
|
||||
*ret = obj;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
CLEANUP_OBJ(obj);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
cfg_print_kv_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
||||
unsigned int i;
|
||||
const cfg_tuplefielddef_t *fields, *f;
|
||||
const cfg_obj_t *fieldobj;
|
||||
|
||||
fields = obj->type->of;
|
||||
for (f = fields, i = 0; f->name != NULL; f++, i++) {
|
||||
fieldobj = obj->value.tuple[i];
|
||||
if (fieldobj->type->print == cfg_print_void)
|
||||
continue;
|
||||
if (i != 0) {
|
||||
cfg_print_chars(pctx, " ", 1);
|
||||
cfg_print_cstr(pctx, f->name);
|
||||
cfg_print_chars(pctx, " ", 1);
|
||||
}
|
||||
cfg_print_obj(pctx, fieldobj);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cfg_doc_kv_tuple(cfg_printer_t *pctx, const cfg_type_t *type) {
|
||||
const cfg_tuplefielddef_t *fields, *f;
|
||||
|
||||
fields = type->of;
|
||||
for (f = fields; f->name != NULL; f++) {
|
||||
if (f != fields) {
|
||||
cfg_print_chars(pctx, " [ ", 3);
|
||||
cfg_print_cstr(pctx, f->name);
|
||||
if (f->type->doc != cfg_doc_void)
|
||||
cfg_print_chars(pctx, " ", 1);
|
||||
}
|
||||
cfg_doc_obj(pctx, f->type);
|
||||
if (f != fields)
|
||||
cfg_print_chars(pctx, " ]", 2);
|
||||
}
|
||||
}
|
||||
|
||||
static keyword_type_t zone_kw = {"zone", &cfg_type_qstring};
|
||||
static cfg_type_t cfg_type_rpz_zone = {
|
||||
"zone", parse_keyvalue, print_keyvalue,
|
||||
doc_keyvalue, &cfg_rep_string,
|
||||
&zone_kw
|
||||
};
|
||||
static const char *rpz_policies[] = {
|
||||
"given", "disabled", "passthru", "no-op", "nxdomain", "nodata",
|
||||
"cname", NULL
|
||||
};
|
||||
static cfg_type_t cfg_type_rpz_policylist = {
|
||||
"policies", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
|
||||
&cfg_rep_string, &rpz_policies
|
||||
static cfg_type_t cfg_type_rpz_policy_name = {
|
||||
"policy name", cfg_parse_enum, cfg_print_ustring,
|
||||
doc_rpz_policy, &cfg_rep_string,
|
||||
&rpz_policies
|
||||
};
|
||||
static keyword_type_t rpz_policies_kw = {
|
||||
"policy", &cfg_type_rpz_policylist
|
||||
};
|
||||
static cfg_type_t cfg_type_rpz_policy = {
|
||||
"optional_policy", parse_optional_keyvalue, print_keyvalue,
|
||||
doc_rpz_policies, &cfg_rep_string, &rpz_policies_kw
|
||||
};
|
||||
static cfg_type_t cfg_type_cname = {
|
||||
"domain", cfg_parse_astring, print_rpz_cname, doc_rpz_cname,
|
||||
&cfg_rep_string, NULL
|
||||
};
|
||||
static cfg_tuplefielddef_t rpzone_fields[] = {
|
||||
{ "name", &cfg_type_astring, 0 },
|
||||
{ "policy", &cfg_type_rpz_policy, 0 },
|
||||
{ "cname", &cfg_type_cname, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
static cfg_type_t cfg_type_rpzone = {
|
||||
"rpzone", parse_rpz, cfg_print_tuple, cfg_doc_tuple,
|
||||
&cfg_rep_tuple, rpzone_fields
|
||||
};
|
||||
static cfg_clausedef_t rpz_clauses[] = {
|
||||
{ "zone", &cfg_type_rpzone, CFG_CLAUSEFLAG_MULTI },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
static cfg_clausedef_t *rpz_clausesets[] = {
|
||||
rpz_clauses,
|
||||
static cfg_type_t cfg_type_rpz_cname = {
|
||||
"quoted_string", cfg_parse_astring, NULL,
|
||||
doc_rpz_cname, &cfg_rep_string,
|
||||
NULL
|
||||
};
|
||||
static cfg_type_t cfg_type_rpz = {
|
||||
"rpz", cfg_parse_map, cfg_print_map, cfg_doc_map,
|
||||
&cfg_rep_map, rpz_clausesets
|
||||
static cfg_tuplefielddef_t rpz_policy_fields[] = {
|
||||
{ "policy name", &cfg_type_rpz_policy_name, 0 },
|
||||
{ "cname", &cfg_type_rpz_cname, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
static cfg_type_t cfg_type_rpz_policy = {
|
||||
"policy tuple", cfg_parse_rpz_policy,
|
||||
cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
|
||||
rpz_policy_fields
|
||||
};
|
||||
static cfg_tuplefielddef_t rpz_zone_fields[] = {
|
||||
{ "zone name", &cfg_type_rpz_zone, 0 },
|
||||
{ "policy", &cfg_type_rpz_policy, 0 },
|
||||
{ "recursive-only", &cfg_type_boolean, 0 },
|
||||
{ "max-policy-ttl", &cfg_type_uint32, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
static cfg_type_t cfg_type_rpz_tuple = {
|
||||
"rpz tuple", cfg_parse_kv_tuple,
|
||||
cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple,
|
||||
rpz_zone_fields
|
||||
};
|
||||
static cfg_type_t cfg_type_rpz_list = {
|
||||
"zone list", cfg_parse_bracketed_list, cfg_print_bracketed_list,
|
||||
cfg_doc_bracketed_list, &cfg_rep_list,
|
||||
&cfg_type_rpz_tuple
|
||||
};
|
||||
static cfg_tuplefielddef_t rpz_fields[] = {
|
||||
{ "zone list", &cfg_type_rpz_list, 0 },
|
||||
{ "recursive-only", &cfg_type_boolean, 0 },
|
||||
{ "break-dnssec", &cfg_type_boolean, 0 },
|
||||
{ "max-policy-ttl", &cfg_type_uint32, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
static cfg_type_t cfg_type_rpz = {
|
||||
"rpz", cfg_parse_kv_tuple,
|
||||
cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple,
|
||||
rpz_fields
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*%
|
||||
|
|
|
|||
|
|
@ -1137,6 +1137,7 @@
|
|||
./bin/tests/system/rpz/clean.sh SH 2011,2012
|
||||
./bin/tests/system/rpz/ns1/named.conf CONF-C 2011
|
||||
./bin/tests/system/rpz/ns1/root.db ZONE 2011,2012
|
||||
./bin/tests/system/rpz/ns2/base-tld2s.db ZONE 2012
|
||||
./bin/tests/system/rpz/ns2/hints ZONE 2011
|
||||
./bin/tests/system/rpz/ns2/named.conf CONF-C 2011,2012
|
||||
./bin/tests/system/rpz/ns2/tld2.db ZONE 2011
|
||||
|
|
@ -1145,9 +1146,12 @@
|
|||
./bin/tests/system/rpz/ns3/crash2 X 2011
|
||||
./bin/tests/system/rpz/ns3/hints ZONE 2011
|
||||
./bin/tests/system/rpz/ns3/named.conf CONF-C 2011
|
||||
./bin/tests/system/rpz/ns4/hints X 2011
|
||||
./bin/tests/system/rpz/ns4/hints ZONE 2011
|
||||
./bin/tests/system/rpz/ns4/named.conf CONF-C 2011
|
||||
./bin/tests/system/rpz/ns4/tld4.db ZONE 2011
|
||||
./bin/tests/system/rpz/ns5/hints ZONE 2011
|
||||
./bin/tests/system/rpz/ns5/named.conf CONF-C 2012
|
||||
./bin/tests/system/rpz/qperf.sh SH 2012
|
||||
./bin/tests/system/rpz/rpz.c C 2011
|
||||
./bin/tests/system/rpz/setup.sh SH 2011,2012
|
||||
./bin/tests/system/rpz/test1 X 2011,2012
|
||||
|
|
|
|||
Loading…
Reference in a new issue