From c82b3781158672e8308b53a8b6289e432ceb48d0 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 23 Apr 2015 16:57:15 +1000 Subject: [PATCH] 4108. [func] A additional nxdomain redirect (nxdomain-redirect) method is now supported. [RT #37989] --- CHANGES | 3 + bin/named/client.c | 1 + bin/named/include/named/query.h | 14 + bin/named/query.c | 296 +++++++++++++++++++- bin/named/server.c | 14 + bin/tests/system/redirect/clean.sh | 20 +- bin/tests/system/redirect/ns3/example.db | 55 ++++ bin/tests/system/redirect/ns3/named.conf | 60 ++++ bin/tests/system/redirect/ns3/redirect.db | 21 ++ bin/tests/system/redirect/ns3/root.db | 25 ++ bin/tests/system/redirect/ns3/sign.sh | 42 +++ bin/tests/system/redirect/ns4/example.db.in | 19 ++ bin/tests/system/redirect/ns4/named.conf | 53 ++++ bin/tests/system/redirect/ns4/root.hint | 19 ++ bin/tests/system/redirect/setup.sh | 5 +- bin/tests/system/redirect/tests.sh | 185 ++++++++++-- doc/arm/Bv9ARM-book.xml | 36 +++ doc/arm/notes.xml | 8 + lib/dns/include/dns/view.h | 3 + lib/dns/view.c | 2 + lib/isccfg/namedconf.c | 1 + 21 files changed, 837 insertions(+), 45 deletions(-) create mode 100644 bin/tests/system/redirect/ns3/example.db create mode 100644 bin/tests/system/redirect/ns3/named.conf create mode 100644 bin/tests/system/redirect/ns3/redirect.db create mode 100644 bin/tests/system/redirect/ns3/root.db create mode 100644 bin/tests/system/redirect/ns3/sign.sh create mode 100644 bin/tests/system/redirect/ns4/example.db.in create mode 100644 bin/tests/system/redirect/ns4/named.conf create mode 100644 bin/tests/system/redirect/ns4/root.hint diff --git a/CHANGES b/CHANGES index 4d9fb19374..c4b4db394e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4108. [func] A additional nxdomain redirect (nxdomain-redirect) + is now supported. [RT #37989] + 4107. [bug] Address potential deadlock when updating zone content. [RT #39269] diff --git a/bin/named/client.c b/bin/named/client.c index 21afbbd3fc..0e79d7cc1d 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -3599,6 +3599,7 @@ ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) { &client->query.qname); } client->query.qname = name; + client->query.attributes &= ~NS_QUERYATTR_REDIRECT; UNLOCK(&client->query.fetchlock); } diff --git a/bin/named/include/named/query.h b/bin/named/include/named/query.h index e4179f1f93..3e6c03a775 100644 --- a/bin/named/include/named/query.h +++ b/bin/named/include/named/query.h @@ -67,6 +67,19 @@ struct ns_query { unsigned int dns64_aaaaoklen; unsigned int dns64_options; unsigned int dns64_ttl; + struct { + dns_db_t * db; + dns_zone_t * zone; + dns_dbnode_t * node; + dns_rdatatype_t qtype; + dns_name_t * fname; + dns_fixedname_t fixed; + isc_result_t result; + dns_rdataset_t * rdataset; + dns_rdataset_t * sigrdataset; + isc_boolean_t authoritative; + } redirect; + }; #define NS_QUERYATTR_RECURSIONOK 0x0001 @@ -86,6 +99,7 @@ struct ns_query { #define NS_QUERYATTR_DNS64 0x4000 #define NS_QUERYATTR_DNS64EXCLUDE 0x8000 #define NS_QUERYATTR_RRL_CHECKED 0x10000 +#define NS_QUERYATTR_REDIRECT 0x20000 isc_result_t ns_query_init(ns_client_t *client); diff --git a/bin/named/query.c b/bin/named/query.c index 68cd9d2163..7aa95ce49b 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -122,6 +122,9 @@ #define DNS64EXCLUDE(c) (((c)->query.attributes & \ NS_QUERYATTR_DNS64EXCLUDE) != 0) +#define REDIRECT(c) (((c)->query.attributes & \ + NS_QUERYATTR_REDIRECT) != 0) + /*% No QNAME Proof? */ #define NOQNAME(r) (((r)->attributes & \ DNS_RDATASETATTR_NOQNAME) != 0) @@ -381,6 +384,17 @@ query_reset(ns_client_t *client, isc_boolean_t everything) { client->query.dns64_aaaaoklen = 0; } + query_putrdataset(client, &client->query.redirect.rdataset); + query_putrdataset(client, &client->query.redirect.sigrdataset); + if (client->query.redirect.db != NULL) { + if (client->query.redirect.node != NULL) + dns_db_detachnode(client->query.redirect.db, + &client->query.redirect.node); + dns_db_detach(&client->query.redirect.db); + } + if (client->query.redirect.zone != NULL) + dns_zone_detach(&client->query.redirect.zone); + query_freefreeversions(client, everything); for (dbuf = ISC_LIST_HEAD(client->query.namebufs); @@ -655,6 +669,16 @@ ns_query_init(ns_client_t *client) { client->query.dns64_sigaaaa = NULL; client->query.dns64_aaaaok = NULL; client->query.dns64_aaaaoklen = 0; + client->query.redirect.db = NULL; + client->query.redirect.node = NULL; + client->query.redirect.zone = NULL; + client->query.redirect.qtype = dns_rdatatype_none; + client->query.redirect.result = ISC_R_SUCCESS; + client->query.redirect.rdataset = NULL; + client->query.redirect.sigrdataset = NULL; + dns_fixedname_init(&client->query.redirect.fixed); + client->query.redirect.fname = + dns_fixedname_name(&client->query.redirect.fixed); query_reset(client, ISC_FALSE); result = query_newdbversion(client, 3); if (result != ISC_R_SUCCESS) { @@ -6140,6 +6164,168 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, return (result); } +static isc_result_t +redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, + dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp, + dns_rdatatype_t qtype) +{ + dns_db_t *db = NULL; + dns_dbnode_t *node = NULL; + dns_fixedname_t fixed; + dns_fixedname_t fixedredirect; + dns_name_t *found, *redirectname; + dns_rdataset_t trdataset; + isc_result_t result; + dns_rdatatype_t type; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; + dns_dbversion_t *version = NULL; + dns_zone_t *zone = NULL; + unsigned int options; + isc_boolean_t is_zonep = ISC_FALSE; + + CTRACE(ISC_LOG_DEBUG(3), "redirect2"); + + if (client->view->redirectzone == NULL) + return (ISC_R_NOTFOUND); + + if (dns_name_issubdomain(name, client->view->redirectzone)) + return (ISC_R_NOTFOUND); + + dns_fixedname_init(&fixed); + found = dns_fixedname_name(&fixed); + dns_rdataset_init(&trdataset); + + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client, NULL); + + if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp)) + return (ISC_R_NOTFOUND); + + if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) { + if (rdataset->trust == dns_trust_secure) + return (ISC_R_NOTFOUND); + if (rdataset->trust == dns_trust_ultimate && + (rdataset->type == dns_rdatatype_nsec || + rdataset->type == dns_rdatatype_nsec3)) + return (ISC_R_NOTFOUND); + if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) { + 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_R_NOTFOUND); + } + } + } + + dns_fixedname_init(&fixedredirect); + redirectname = dns_fixedname_name(&fixedredirect); + if (dns_name_countlabels(name) > 1U) { + dns_name_t prefix; + unsigned int labels = dns_name_countlabels(name) - 1; + + dns_name_init(&prefix, NULL); + dns_name_getlabelsequence(name, 0, labels, &prefix); + result = dns_name_concatenate(&prefix, + client->view->redirectzone, + redirectname, NULL); + if (result != ISC_R_SUCCESS) + return (ISC_R_NOTFOUND); + } else + dns_name_copy(redirectname, client->view->redirectzone, NULL); + + options = 0; + result = query_getdb(client, redirectname, qtype, options, &zone, + &db, &version, &is_zonep); + if (result != ISC_R_SUCCESS) + return (ISC_R_NOTFOUND); + + /* + * Lookup the requested data in the redirect zone. + */ + result = dns_db_findext(db, redirectname, version, + qtype, 0, client->now, + &node, found, &cm, &ci, &trdataset, NULL); + if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) { + if (dns_rdataset_isassociated(rdataset)) + dns_rdataset_disassociate(rdataset); + if (dns_rdataset_isassociated(&trdataset)) + dns_rdataset_disassociate(&trdataset); + goto nxrrset; + } else if (result == ISC_R_NOTFOUND || result == DNS_R_DELEGATION) { + /* + * Cleanup. + */ + if (dns_rdataset_isassociated(&trdataset)) + dns_rdataset_disassociate(&trdataset); + if (node != NULL) + dns_db_detachnode(db, &node); + dns_db_detach(&db); + /* + * Don't loop forever if the lookup failed last time. + */ + if (!REDIRECT(client)) { + result = query_recurse(client, qtype, redirectname, + NULL, NULL, ISC_TRUE); + if (result == ISC_R_SUCCESS) { + client->query.attributes |= + NS_QUERYATTR_RECURSING; + client->query.attributes |= + NS_QUERYATTR_REDIRECT; + return (DNS_R_CONTINUE); + } + } + return (ISC_R_NOTFOUND); + } else if (result != ISC_R_SUCCESS) { + if (dns_rdataset_isassociated(&trdataset)) + dns_rdataset_disassociate(&trdataset); + if (node != NULL) + dns_db_detachnode(db, &node); + dns_db_detach(&db); + return (ISC_R_NOTFOUND); + } + + CTRACE(ISC_LOG_DEBUG(3), "redirect2: found data: done"); + /* + * Adjust the found name to not include the redirectzone suffix. + */ + dns_name_split(found, dns_name_countlabels(client->view->redirectzone), + found, NULL); + /* + * Make the name absolute. + */ + result = dns_name_concatenate(found, dns_rootname, found, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + dns_name_copy(found, name, NULL); + if (dns_rdataset_isassociated(rdataset)) + dns_rdataset_disassociate(rdataset); + if (dns_rdataset_isassociated(&trdataset)) { + dns_rdataset_clone(&trdataset, rdataset); + dns_rdataset_disassociate(&trdataset); + } + nxrrset: + if (*nodep != NULL) + dns_db_detachnode(*dbp, nodep); + dns_db_detach(dbp); + dns_db_attachnode(db, node, nodep); + dns_db_attach(db, dbp); + dns_db_detachnode(db, &node); + dns_db_detach(&db); + *versionp = version; + + client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | + NS_QUERYATTR_NOADDITIONAL); + + return (result); +} + /* * Do the bulk of query processing for the current query of 'client'. * If 'event' is non-NULL, we are returning from recursion and 'qtype' @@ -6253,6 +6439,33 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) rpz_st->r.r_type = event->qtype; rpz_st->r.r_rdataset = event->rdataset; query_putrdataset(client, &event->sigrdataset); + } else if (REDIRECT(client)) { + + /* + * Restore saved state. + */ + qtype = client->query.redirect.qtype; + rdataset = client->query.redirect.rdataset; + client->query.redirect.rdataset = NULL; + sigrdataset = client->query.redirect.sigrdataset; + client->query.redirect.sigrdataset = NULL; + db = client->query.redirect.db; + client->query.redirect.db = NULL; + node = client->query.redirect.node; + client->query.redirect.node = NULL; + zone = client->query.redirect.zone; + client->query.redirect.zone = NULL; + authoritative = client->query.redirect.authoritative; + + /* + * Free resources used while recursing. + */ + query_putrdataset(client, &event->rdataset); + query_putrdataset(client, &event->sigrdataset); + if (event->node != NULL) + dns_db_detachnode(event->db, &event->node); + if (event->db != NULL) + dns_db_detach(&event->db); } else { authoritative = ISC_FALSE; @@ -6297,6 +6510,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) != 0) { tname = rpz_st->fname; + } else if (REDIRECT(client)) { + tname = client->query.redirect.fname; } else { tname = dns_fixedname_name(&event->foundname); } @@ -6312,6 +6527,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) rpz_st->r.r_result = event->result; result = rpz_st->q.result; isc_event_free(ISC_EVENT_PTR(&event)); + } else if (REDIRECT(client)) { + result = client->query.redirect.result; } else { result = event->result; } @@ -7350,6 +7567,40 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) is_zone = ISC_FALSE; goto ncache_nxrrset; } + tresult = redirect2(client, fname, rdataset, &node, + &db, &version, type); + if (tresult == DNS_R_CONTINUE) { + client->query.redirect.qtype = qtype; + client->query.redirect.rdataset = rdataset; + client->query.redirect.sigrdataset = + sigrdataset; + client->query.redirect.db = db; + client->query.redirect.node = node; + client->query.redirect.zone = zone; + client->query.redirect.result = DNS_R_NXDOMAIN; + dns_name_copy(fname, + client->query.redirect.fname, + NULL); + client->query.redirect.authoritative = + authoritative; + db = NULL; + node = NULL; + zone = NULL; + rdataset = NULL; + sigrdataset = NULL; + goto cleanup; + } + if (tresult == ISC_R_SUCCESS) + break; + if (tresult == DNS_R_NXRRSET) { + redirected = ISC_TRUE; + goto iszone_nxrrset; + } + if (tresult == DNS_R_NCACHENXRRSET) { + redirected = ISC_TRUE; + is_zone = ISC_FALSE; + goto ncache_nxrrset; + } } if (dns_rdataset_isassociated(rdataset)) { /* @@ -7427,6 +7678,37 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) result = tresult; goto ncache_nxrrset; } + tresult = redirect2(client, fname, rdataset, &node, + &db, &version, type); + if (tresult == DNS_R_CONTINUE) { + client->query.redirect.db = db; + client->query.redirect.node = node; + client->query.redirect.zone = zone; + client->query.redirect.qtype = qtype; + client->query.redirect.rdataset = rdataset; + client->query.redirect.sigrdataset = sigrdataset; + client->query.redirect.result = DNS_R_NCACHENXDOMAIN; + dns_name_copy(fname, client->query.redirect.fname, + NULL); + client->query.redirect.authoritative = authoritative; + db = NULL; + node = NULL; + rdataset = NULL; + sigrdataset = NULL; + goto cleanup; + } + if (tresult == ISC_R_SUCCESS) + break; + if (tresult == DNS_R_NXRRSET) { + redirected = ISC_TRUE; + is_zone = ISC_TRUE; + goto iszone_nxrrset; + } + if (tresult == DNS_R_NCACHENXRRSET) { + redirected = ISC_TRUE; + result = tresult; + goto ncache_nxrrset; + } /* FALLTHROUGH */ case DNS_R_NCACHENXRRSET: @@ -7533,12 +7815,14 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) * We don't call query_addrrset() because we don't need any * of its extra features (and things would probably break!). */ - query_keepname(client, fname, dbuf); - dns_message_addname(client->message, fname, - DNS_SECTION_AUTHORITY); - ISC_LIST_APPEND(fname->list, rdataset, link); - fname = NULL; - rdataset = NULL; + if (dns_rdataset_isassociated(rdataset)) { + query_keepname(client, fname, dbuf); + dns_message_addname(client->message, fname, + DNS_SECTION_AUTHORITY); + ISC_LIST_APPEND(fname->list, rdataset, link); + fname = NULL; + rdataset = NULL; + } goto cleanup; case DNS_R_CNAME: diff --git a/bin/named/server.c b/bin/named/server.c index bb7e087804..8067a602b4 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -3816,6 +3816,20 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, fail_ttl = 300; dns_view_setfailttl(view, fail_ttl); + /* + * Name space to look up redirect information in. + */ + obj = NULL; + result = ns_config_get(maps, "nxdomain-redirect", &obj); + if (result == ISC_R_SUCCESS) { + dns_name_t *name = dns_fixedname_name(&view->redirectfixed); + CHECK(dns_name_fromstring(name, cfg_obj_asstring(obj), 0, + NULL)); + view->redirectzone = name; + } else + view->redirectzone = NULL; + + result = ISC_R_SUCCESS; cleanup: diff --git a/bin/tests/system/redirect/clean.sh b/bin/tests/system/redirect/clean.sh index 431c1f29d2..83568a8f86 100644 --- a/bin/tests/system/redirect/clean.sh +++ b/bin/tests/system/redirect/clean.sh @@ -14,14 +14,20 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -rm -f ns1/K* -rm -f ns1/signed.db* -rm -f ns1/nsec3.db* -rm -f ns1/dsset-signed. -rm -f ns1/dsset-nsec3. rm -f */named.memstats rm -f */named.run rm -f dig.out.* -rm -f ns2/*.db -rm -f rndc.out rm -f ns*/named.lock +rm -f ns1/K* +rm -f ns1/dsset-nsec3. +rm -f ns1/dsset-signed. +rm -f ns1/nsec3.db* +rm -f ns1/signed.db* +rm -f ns2/*.db +rm -f ns3/K* +rm -f ns3/dsset-nsec3. +rm -f ns3/dsset-signed. +rm -f ns3/nsec3.db* +rm -f ns3/signed.db* +rm -f ns4/*.db +rm -f rndc.out diff --git a/bin/tests/system/redirect/ns3/example.db b/bin/tests/system/redirect/ns3/example.db new file mode 100644 index 0000000000..2877e9d878 --- /dev/null +++ b/bin/tests/system/redirect/ns3/example.db @@ -0,0 +1,55 @@ +; 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: example.db,v 1.3 2011/03/01 23:48:06 tbox Exp $ + +$TTL 3600 +@ SOA ns3 marka.isc.org. 0 0 0 0 1200 +@ NS ns3 +ns3 A 10.53.0.3 +excluded-good-a AAAA 2001:eeee::1 + A 1.2.3.4 +excluded-bad-a AAAA 2001:eeee::2 + A 10.0.0.1 +excluded-only AAAA 2001:eeee::3 +partially-excluded-good-a AAAA 2001:eeee::1 + AAAA 2001::1 + A 1.2.3.4 +partially-excluded-bad-a AAAA 2001:eeee::2 + AAAA 2001::2 + A 10.0.0.1 +partially-excluded-only AAAA 2001:eeee::3 + AAAA 2001::3 +a-only A 1.2.3.5 +a-and-aaaa AAAA 2001::1 + A 1.2.3.6 +aaaa-only AAAA 2001::2 +a-not-mapped A 10.0.0.2 +mx-only MX 10 ns.example. +cname-excluded-good-a CNAME excluded-good-a +cname-excluded-bad-a CNAME excluded-bad-a +cname-excluded-only CNAME excluded-only +cname-partial-excluded-good-a CNAME partial-excluded-good-a +cname-partial-excluded-bad-a CNAME partial-excluded-bad-a +cname-partial-excluded-only CNAME partial-excluded-only +cname-a-only CNAME a-only +cname-a-and-aaaa CNAME a-and-aaaa +cname-aaaa-only CNAME aaaa-only +cname-a-not-mapped CNAME a-not-mapped +cname-mx-only CNAME mx-only +cname-non-existent CNAME non-existent +ttl-less-than-600 500 A 5.6.7.8 +ttl-more-than-600 700 A 5.6.7.8 +ttl-less-than-minimum 1100 A 5.6.7.8 +ttl-more-than-minimum 1300 A 5.6.7.8 diff --git a/bin/tests/system/redirect/ns3/named.conf b/bin/tests/system/redirect/ns3/named.conf new file mode 100644 index 0000000000..d8e14054cd --- /dev/null +++ b/bin/tests/system/redirect/ns3/named.conf @@ -0,0 +1,60 @@ +/* + * 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. + */ + +controls { /* empty */ }; + +acl rfc1918 { 10/8; 192.168/16; 172.16/12; }; + +options { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + allow-recursion { 10.53.0.3; }; + notify yes; + dnssec-enable yes; + dnssec-validation yes; +}; + +zone "." { + type master; + file "root.db"; +}; + +zone "example" { + type master; + file "example.db"; +}; + +zone "signed" { + type master; + file "signed.db.signed"; +}; + +zone "nsec3" { + type master; + file "nsec3.db.signed"; +}; + +zone "redirect" { + type master; + file "redirect.db"; +}; + +// include "trusted.conf"; diff --git a/bin/tests/system/redirect/ns3/redirect.db b/bin/tests/system/redirect/ns3/redirect.db new file mode 100644 index 0000000000..3b4efd716b --- /dev/null +++ b/bin/tests/system/redirect/ns3/redirect.db @@ -0,0 +1,21 @@ +; 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: redirect.db,v 1.3 2011/03/01 23:48:06 tbox Exp $ + +$TTL 300 +@ IN SOA a.root-servers.nil. hostmaster.example.net. 0 0 0 0 0 +@ IN NS a.root-servers.nil. +* IN A 100.100.100.1 +* IN AAAA 2001:ffff:ffff::100.100.100.1 diff --git a/bin/tests/system/redirect/ns3/root.db b/bin/tests/system/redirect/ns3/root.db new file mode 100644 index 0000000000..3273989a1d --- /dev/null +++ b/bin/tests/system/redirect/ns3/root.db @@ -0,0 +1,25 @@ +; 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: root.db,v 1.3 2011/03/01 23:48:06 tbox Exp $ + +$TTL 3600 +@ SOA a.root-servers.nil. marka.isc.org. 0 0 0 0 0 +@ NS a.root-servers.nil. +a.root-servers.nil. A 10.53.0.3 +example NS ns1.example. +ns1.example. A 10.53.0.3 +signed NS ns1.example. +ns1.signed. A 10.53.0.3 +redirect NS a.root-servers.nil diff --git a/bin/tests/system/redirect/ns3/sign.sh b/bin/tests/system/redirect/ns3/sign.sh new file mode 100644 index 0000000000..fe5d562e82 --- /dev/null +++ b/bin/tests/system/redirect/ns3/sign.sh @@ -0,0 +1,42 @@ +#!/bin/sh -e +# +# Copyright (C) 2011, 2012, 2014 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: sign.sh,v 1.3 2011/03/01 23:48:06 tbox Exp $ + +SYSTEMTESTTOP=../.. +. $SYSTEMTESTTOP/conf.sh + +zone=signed +infile=example.db +zonefile=signed.db + +key1=`$KEYGEN -q -r $RANDFILE $zone` +key2=`$KEYGEN -q -r $RANDFILE -fk $zone` + +cat $infile $key1.key $key2.key > $zonefile + +$SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null + +zone=nsec3 +infile=example.db +zonefile=nsec3.db + +key1=`$KEYGEN -q -r $RANDFILE -3 $zone` +key2=`$KEYGEN -q -r $RANDFILE -3 -fk $zone` + +cat $infile $key1.key $key2.key > $zonefile + +$SIGNER -P -3 - -g -r $RANDFILE -o $zone $zonefile > /dev/null diff --git a/bin/tests/system/redirect/ns4/example.db.in b/bin/tests/system/redirect/ns4/example.db.in new file mode 100644 index 0000000000..cf08a09a6b --- /dev/null +++ b/bin/tests/system/redirect/ns4/example.db.in @@ -0,0 +1,19 @@ +; Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +$TTL 300 ; 5 minutes +@ IN SOA ns.example.net hostmaster.example.net 0 0 0 0 0 +@ NS ns4 +ns2 A 10.53.0.4 +a A 10.53.0.2 diff --git a/bin/tests/system/redirect/ns4/named.conf b/bin/tests/system/redirect/ns4/named.conf new file mode 100644 index 0000000000..2d077aa3dc --- /dev/null +++ b/bin/tests/system/redirect/ns4/named.conf @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011, 2013 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: named.conf,v 1.3 2011/03/01 23:48:07 tbox Exp $ */ + +// NS2 + +controls { /* empty */ }; + +acl rfc1918 { 10/8; 192.168/16; 172.16/12; }; + +options { + query-source address 10.53.0.2; /* note this is not 10.53.0.3 */ + notify-source 10.53.0.4; + transfer-source 10.53.0.4; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.4; }; + listen-on-v6 { none; }; + recursion yes; + notify yes; + dnssec-enable yes; + dnssec-validation yes; + nxdomain-redirect "redirect"; + +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.4 port 9953 allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "root.hint"; +}; diff --git a/bin/tests/system/redirect/ns4/root.hint b/bin/tests/system/redirect/ns4/root.hint new file mode 100644 index 0000000000..2dc780cfd9 --- /dev/null +++ b/bin/tests/system/redirect/ns4/root.hint @@ -0,0 +1,19 @@ +; Copyright (C) 2015 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: root.hint,v 1.5 2007/06/19 23:47:01 tbox Exp $ + +$TTL 999999 +. IN NS a.root-servers.nil. +a.root-servers.nil. IN A 10.53.0.3 diff --git a/bin/tests/system/redirect/setup.sh b/bin/tests/system/redirect/setup.sh index 9fecc9ad81..388999838a 100644 --- a/bin/tests/system/redirect/setup.sh +++ b/bin/tests/system/redirect/setup.sh @@ -23,4 +23,7 @@ test -r $RANDFILE || $GENRANDOM 400 $RANDFILE cp ns2/redirect.db.in ns2/redirect.db cp ns2/example.db.in ns2/example.db -cd ns1 && $SHELL sign.sh +( cd ns1 && $SHELL sign.sh ) + +cp ns4/example.db.in ns4/example.db +( cd ns3 && $SHELL sign.sh ) diff --git a/bin/tests/system/redirect/tests.sh b/bin/tests/system/redirect/tests.sh index dd8dadc850..f2894334c8 100644 --- a/bin/tests/system/redirect/tests.sh +++ b/bin/tests/system/redirect/tests.sh @@ -46,7 +46,7 @@ do status=`expr $status + $ret` done -echo "I:checking A redirect works for nonexist ($n)" +echo "I:checking A zone redirect works for nonexist ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.2 a > dig.out.ns2.test$n || ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 @@ -55,7 +55,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking AAAA redirect works for nonexist ($n)" +echo "I:checking AAAA zone redirect works for nonexist ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 @@ -64,7 +64,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking ANY redirect works for nonexist ($n)" +echo "I:checking ANY zone redirect works for nonexist ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.2 any > dig.out.ns2.test$n || ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 @@ -74,7 +74,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking A redirect doesn't work for acl miss ($n)" +echo "I:checking A zone redirect doesn't work for acl miss ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.4 a > dig.out.ns2.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 @@ -83,7 +83,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking AAAA redirect doesn't work for acl miss ($n)" +echo "I:checking AAAA zone redirect doesn't work for acl miss ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.4 aaaa > dig.out.ns2.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 @@ -92,7 +92,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking ANY redirect doesn't work for acl miss ($n)" +echo "I:checking ANY zone redirect doesn't work for acl miss ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.4 any > dig.out.ns2.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 @@ -102,7 +102,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking A redirect works for signed nonexist, DO=0 ($n)" +echo "I:checking A zone redirect works for signed nonexist, DO=0 ($n)" ret=0 $DIG $DIGOPTS nonexist.signed. @10.53.0.2 -b 10.53.0.2 a > dig.out.ns2.test$n || ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 @@ -111,7 +111,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking AAAA redirect works for signed nonexist, DO=0 ($n)" +echo "I:checking AAAA zone redirect works for signed nonexist, DO=0 ($n)" ret=0 $DIG $DIGOPTS nonexist.signed. @10.53.0.2 -b 10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 @@ -120,7 +120,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking ANY redirect works for signed nonexist, DO=0 ($n)" +echo "I:checking ANY zone redirect works for signed nonexist, DO=0 ($n)" ret=0 $DIG $DIGOPTS nonexist.signed. @10.53.0.2 -b 10.53.0.2 any > dig.out.ns2.test$n || ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 @@ -130,7 +130,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking A redirect fails for signed nonexist, DO=1 ($n)" +echo "I:checking A zone redirect fails for signed nonexist, DO=1 ($n)" ret=0 $DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.2 -b 10.53.0.2 a > dig.out.ns2.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 @@ -139,7 +139,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking AAAA redirect fails for signed nonexist, DO=1 ($n)" +echo "I:checking AAAA zone redirect fails for signed nonexist, DO=1 ($n)" ret=0 $DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.2 -b 10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 @@ -148,7 +148,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking ANY redirect fails for signed nonexist, DO=1 ($n)" +echo "I:checking ANY zone redirect fails for signed nonexist, DO=1 ($n)" ret=0 $DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.2 -b 10.53.0.2 any > dig.out.ns2.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 @@ -158,7 +158,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking A redirect fails for nsec3 signed nonexist, DO=1 ($n)" +echo "I:checking A zone redirect fails for nsec3 signed nonexist, DO=1 ($n)" ret=0 $DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.2 -b 10.53.0.2 a > dig.out.ns2.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 @@ -168,7 +168,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking AAAA redirect fails for nsec3 signed nonexist, DO=1 ($n)" +echo "I:checking AAAA zone redirect fails for nsec3 signed nonexist, DO=1 ($n)" ret=0 $DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.2 -b 10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 @@ -178,7 +178,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking ANY redirect fails for nsec3 signed nonexist, DO=1 ($n)" +echo "I:checking ANY zone redirect fails for nsec3 signed nonexist, DO=1 ($n)" ret=0 $DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.2 -b 10.53.0.2 any > dig.out.ns2.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 @@ -189,7 +189,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking A redirect works for nonexist authoritative ($n)" +echo "I:checking A zone redirect works for nonexist authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.1 a > dig.out.ns1.test$n || ret=1 grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 @@ -198,7 +198,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking AAAA redirect works for nonexist authoritative ($n)" +echo "I:checking AAAA zone redirect works for nonexist authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.1 aaaa > dig.out.ns1.test$n || ret=1 grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 @@ -207,7 +207,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking ANY redirect works for nonexist authoritative ($n)" +echo "I:checking ANY zone redirect works for nonexist authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.1 any > dig.out.ns1.test$n || ret=1 grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 @@ -217,7 +217,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking A redirect doesn't work for acl miss authoritative ($n)" +echo "I:checking A zone redirect doesn't work for acl miss authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.4 a > dig.out.ns1.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 @@ -226,7 +226,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking AAAA redirect doesn't work for acl miss authoritative ($n)" +echo "I:checking AAAA zone redirect doesn't work for acl miss authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.4 aaaa > dig.out.ns1.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 @@ -235,7 +235,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking ANY redirect doesn't work for acl miss authoritative ($n)" +echo "I:checking ANY zone redirect doesn't work for acl miss authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.1 -b 10.53.0.4 any > dig.out.ns1.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 @@ -245,7 +245,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking A redirect works for signed nonexist, DO=0 authoritative ($n)" +echo "I:checking A zone redirect works for signed nonexist, DO=0 authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist.signed. @10.53.0.1 -b 10.53.0.1 a > dig.out.ns1.test$n || ret=1 grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 @@ -254,7 +254,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking AAAA redirect works for signed nonexist, DO=0 authoritative ($n)" +echo "I:checking AAAA zone redirect works for signed nonexist, DO=0 authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist.signed. @10.53.0.1 -b 10.53.0.1 aaaa > dig.out.ns1.test$n || ret=1 grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 @@ -263,7 +263,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking ANY redirect works for signed nonexist, DO=0 authoritative ($n)" +echo "I:checking ANY zone redirect works for signed nonexist, DO=0 authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist.signed. @10.53.0.1 -b 10.53.0.1 any > dig.out.ns1.test$n || ret=1 grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 @@ -273,7 +273,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking A redirect fails for signed nonexist, DO=1 authoritative ($n)" +echo "I:checking A zone redirect fails for signed nonexist, DO=1 authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.1 -b 10.53.0.1 a > dig.out.ns1.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 @@ -282,7 +282,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking AAAA redirect fails for signed nonexist, DO=1 authoritative ($n)" +echo "I:checking AAAA zone redirect fails for signed nonexist, DO=1 authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.1 -b 10.53.0.1 aaaa > dig.out.ns1.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 @@ -291,7 +291,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking ANY redirect fails for signed nonexist, DO=1 authoritative ($n)" +echo "I:checking ANY zone redirect fails for signed nonexist, DO=1 authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.1 -b 10.53.0.1 any > dig.out.ns1.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 @@ -301,7 +301,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking A redirect fails for nsec3 signed nonexist, DO=1 authoritative ($n)" +echo "I:checking A zone redirect fails for nsec3 signed nonexist, DO=1 authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.1 -b 10.53.0.1 a > dig.out.ns1.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 @@ -311,7 +311,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking AAAA redirect fails for nsec3 signed nonexist, DO=1 authoritative ($n)" +echo "I:checking AAAA zone redirect fails for nsec3 signed nonexist, DO=1 authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.1 -b 10.53.0.1 aaaa > dig.out.ns1.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 @@ -321,7 +321,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking ANY redirect fails for nsec3 signed nonexist, DO=1 authoritative ($n)" +echo "I:checking ANY zone redirect fails for nsec3 signed nonexist, DO=1 authoritative ($n)" ret=0 $DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.1 -b 10.53.0.1 any > dig.out.ns1.test$n || ret=1 grep "status: NXDOMAIN" dig.out.ns1.test$n > /dev/null || ret=1 @@ -332,7 +332,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:checking redirect works (with noerror) when qtype is not found ($n)" +echo "I:checking zone redirect works (with noerror) when qtype is not found ($n)" ret=0 $DIG $DIGOPTS nonexist. @10.53.0.2 -b 10.53.0.2 txt > dig.out.ns2.test$n || ret=1 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 @@ -363,5 +363,128 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:checking A nxdomain-redirect works for nonexist ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.4 -b 10.53.0.2 a > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +grep "nonexist. .*100.100.100.1" dig.out.ns4.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA nxdomain-redirect works for nonexist ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.4 -b 10.53.0.2 aaaa > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +grep "nonexist. .*2001:ffff:ffff::6464:6401" dig.out.ns4.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY nxdomain-redirect works for nonexist ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.4 -b 10.53.0.2 any > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns4.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns4.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking A nxdomain-redirect works for signed nonexist, DO=0 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. @10.53.0.4 -b 10.53.0.2 a > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns4.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA nxdomain-redirect works for signed nonexist, DO=0 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. @10.53.0.4 -b 10.53.0.2 aaaa > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns4.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY nxdomain-redirect works for signed nonexist, DO=0 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. @10.53.0.4 -b 10.53.0.2 any > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns4.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns4.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking A nxdomain-redirect fails for signed nonexist, DO=1 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.4 -b 10.53.0.2 a > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns4.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA nxdomain-redirect fails for signed nonexist, DO=1 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.4 -b 10.53.0.2 aaaa > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns4.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY nxdomain-redirect fails for signed nonexist, DO=1 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.signed. +dnssec @10.53.0.4 -b 10.53.0.2 any > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns4.test$n > /dev/null && ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns4.test$n > /dev/null && ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking A nxdomain-redirect fails for nsec3 signed nonexist, DO=1 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.4 -b 10.53.0.2 a > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns4.test$n > /dev/null && ret=1 +grep "IN.NSEC3" dig.out.ns4.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking AAAA nxdomain-redirect fails for nsec3 signed nonexist, DO=1 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.4 -b 10.53.0.2 aaaa > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns4.test$n > /dev/null && ret=1 +grep "IN.NSEC3" dig.out.ns4.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking ANY nxdomain-redirect fails for nsec3 signed nonexist, DO=1 ($n)" +ret=0 +$DIG $DIGOPTS nonexist.nsec3. +dnssec @10.53.0.4 -b 10.53.0.2 any > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +grep "100.100.100.1" dig.out.ns4.test$n > /dev/null && ret=1 +grep "2001:ffff:ffff::6464:6401" dig.out.ns4.test$n > /dev/null && ret=1 +grep "IN.NSEC3" dig.out.ns4.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking nxdomain-redirect works (with noerror) when qtype is not found ($n)" +ret=0 +$DIG $DIGOPTS nonexist. @10.53.0.4 -b 10.53.0.2 txt > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:exit status: $status" exit $status diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index b85123e796..528e2df95d 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -10521,6 +10521,42 @@ example.com CNAME rpz-tcp-only. RateSlipped and RespTruncated. + + + + Named supports NXDOMAIN redirection via two methods: + + Redirect zone + Redirect namespace + + + + With both methods when named gets a NXDOMAIN response + it examines a seperate namespace to see if the NXDOMAIN + response should be replaced with a alternative response. + + + With a redirect zone (zone "." { type redirect; };), the + data used to replace the NXDOMAIN is held in a single + zone which is not part of the normal namespace. All the + redirect information is contained in the zone; there are + no delegations. + + + With a redirect namespace (option { nxdomain-redirect + <suffix> };) the data used to replace the + NXDOMAIN is part of the normal namespace and is looked up by + appending the specified suffix to the original query name. + This roughly doubles the cache required to process NXDOMAIN + responses as you have the original NXDOMAIN response and + the replacement data or a NXDOMAIN indicating that there + is no replacement. + + + If both a redirect zone and a redirect namespace are configured, + the redirect zone is tried first. + + diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 9b272c4968..cbde1d9c52 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -467,6 +467,14 @@ in the prior response. [RT #39047] + + + A alternative NXDOMAIN redirect method (nxdomain-redirect) + which allows the redirect information to be looked up from + a namespace on the Internet rather than requiring a zone + to be configured on the server is now available. + + diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 9136267466..e5d2396f06 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -199,6 +199,9 @@ struct dns_view { dns_zone_t * managed_keys; dns_zone_t * redirect; + dns_name_t * redirectzone; /* points to redirectfixed + when valid */ + dns_fixedname_t redirectfixed; /* * File and configuration data for zones added at runtime diff --git a/lib/dns/view.c b/lib/dns/view.c index 84c00640f7..fb6368615a 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -230,6 +230,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_fixedname_init(&view->dlv_fixed); view->managed_keys = NULL; view->redirect = NULL; + view->redirectzone = NULL; + dns_fixedname_init(&view->redirectfixed); view->requestnsid = ISC_FALSE; view->requestsit = ISC_TRUE; view->new_zone_file = NULL; diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 2f91e543a9..48108a739b 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1530,6 +1530,7 @@ view_clauses[] = { { "minimal-responses", &cfg_type_boolean, 0 }, { "nta-recheck", &cfg_type_ttlval, 0 }, { "nta-lifetime", &cfg_type_ttlval, 0 }, + { "nxdomain-redirect", &cfg_type_astring, 0 }, { "prefetch", &cfg_type_prefetch, 0 }, { "preferred-glue", &cfg_type_astring, 0 }, { "no-case-compress", &cfg_type_bracketed_aml, 0 },