Merge branch '564-mirror-zone-configuration-tweaks-and-cleanups' into 'master'

Mirror zone configuration tweaks and cleanups

Closes #564, #375, and #342

See merge request isc-projects/bind9!815
This commit is contained in:
Ondřej Surý 2018-10-24 14:51:37 -04:00
commit 7b2eaca5fe
46 changed files with 972 additions and 361 deletions

15
CHANGES
View file

@ -1,3 +1,18 @@
5055. [func] A default list of primary servers for the root zone is
now built into named, allowing the "masters" statement
to be omitted when configuring an IANA root zone
mirror. [GL #564]
5054. [func] Attempts to use mirror zones with recursion disabled
are now considered a configuration error. [GL #564]
5053. [func] The only valid zone-level NOTIFY settings for mirror
zones are now "notify no;" and "notify explicit;".
[GL #564]
5052. [func] Mirror zones are now configured using "type mirror;"
rather than "mirror yes;". [GL #564]
5051. [doc] Documentation incorrectly stated that the
"server-addresses" static-stub zone option accepts
custom port numbers. [GL #582]

View file

@ -301,6 +301,21 @@ view \"_bind\" chaos {\n\
MANAGED_KEYS
"# END MANAGED KEYS\n\
\n\
masters " DEFAULT_IANA_ROOT_ZONE_MASTERS " {\n\
2001:500:84::b; # b.root-servers.net\n\
2001:500:2f::f; # f.root-servers.net\n\
2001:7fd::1; # k.root-servers.net\n\
2620:0:2830:202::132; # xfr.cjr.dns.icann.org\n\
2620:0:2d0:202::132; # xfr.lax.dns.icann.org\n\
192.228.79.201; # b.root-servers.net\n\
192.33.4.12; # c.root-servers.net\n\
192.5.5.241; # f.root-servers.net\n\
192.112.36.4; # g.root-servers.net\n\
193.0.14.129; # k.root-servers.net\n\
192.0.47.132; # xfr.cjr.dns.icann.org\n\
192.0.32.132; # xfr.lax.dns.icann.org\n\
};\n\
";
isc_result_t
@ -432,6 +447,8 @@ named_config_getzonetype(const cfg_obj_t *zonetypeobj) {
strcasecmp(str, "slave") == 0)
{
ztype = dns_zone_slave;
} else if (strcasecmp(str, "mirror") == 0) {
ztype = dns_zone_mirror;
} else if (strcasecmp(str, "stub") == 0) {
ztype = dns_zone_stub;
} else if (strcasecmp(str, "static-stub") == 0) {
@ -553,9 +570,9 @@ named_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
}
}
static isc_result_t
get_masters_def(const cfg_obj_t *cctx, const char *name,
const cfg_obj_t **ret)
isc_result_t
named_config_getmastersdef(const cfg_obj_t *cctx, const char *name,
const cfg_obj_t **ret)
{
isc_result_t result;
const cfg_obj_t *masters = NULL;
@ -697,7 +714,8 @@ named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
break;
if (j < l)
continue;
tresult = get_masters_def(config, listname, &list);
tresult = named_config_getmastersdef(config, listname,
&list);
if (tresult == ISC_R_NOTFOUND) {
cfg_obj_log(addr, named_g_lctx, ISC_LOG_ERROR,
"masters \"%s\" not found", listname);

View file

@ -22,6 +22,8 @@
#include <dns/types.h>
#include <dns/zone.h>
#define DEFAULT_IANA_ROOT_ZONE_MASTERS "_default_iana_root_zone_masters"
isc_result_t
named_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf);
@ -57,6 +59,10 @@ void
named_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp,
isc_dscp_t **dscpsp, uint32_t count);
isc_result_t
named_config_getmastersdef(const cfg_obj_t *cctx, const char *name,
const cfg_obj_t **ret);
isc_result_t
named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
isc_mem_t *mctx, dns_ipkeylist_t *ipkl);

View file

@ -884,7 +884,6 @@ view \fIstring\fR [ \fIclass\fR ] {
max\-zone\-ttl ( unlimited | \fIttlval\fR );
min\-refresh\-time \fIinteger\fR;
min\-retry\-time \fIinteger\fR;
mirror \fIboolean\fR;
multi\-master \fIboolean\fR;
notify ( explicit | master\-only | \fIboolean\fR );
notify\-delay \fIinteger\fR;
@ -910,7 +909,7 @@ view \fIstring\fR [ \fIclass\fR ] {
transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port (
\fIinteger\fR | * ) ] [ dscp \fIinteger\fR ];
try\-tcp\-refresh \fIboolean\fR;
type ( primary | master | secondary | slave |
type ( primary | master | secondary | slave | mirror |
delegation\-only | forward | hint | redirect |
static\-stub | stub );
update\-check\-ksk \fIboolean\fR;
@ -993,7 +992,6 @@ zone \fIstring\fR [ \fIclass\fR ] {
max\-zone\-ttl ( unlimited | \fIttlval\fR );
min\-refresh\-time \fIinteger\fR;
min\-retry\-time \fIinteger\fR;
mirror \fIboolean\fR;
multi\-master \fIboolean\fR;
notify ( explicit | master\-only | \fIboolean\fR );
notify\-delay \fIinteger\fR;
@ -1017,8 +1015,9 @@ zone \fIstring\fR [ \fIclass\fR ] {
transfer\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * )
] [ dscp \fIinteger\fR ];
try\-tcp\-refresh \fIboolean\fR;
type ( primary | master | secondary | slave | delegation\-only |
forward | hint | redirect | static\-stub | stub );
type ( primary | master | secondary | slave | mirror |
delegation\-only | forward | hint | redirect | static\-stub |
stub );
update\-check\-ksk \fIboolean\fR;
update\-policy ( local | { ( deny | grant ) \fIstring\fR ( 6to4\-self |
external | krb5\-self | krb5\-subdomain | ms\-self | ms\-subdomain

View file

@ -341,7 +341,6 @@ options {
min-retry-time <replaceable>integer</replaceable>;
minimal-any <replaceable>boolean</replaceable>;
minimal-responses ( no-auth | no-auth-recursive | <replaceable>boolean</replaceable> );
mirror <replaceable>boolean</replaceable>;
multi-master <replaceable>boolean</replaceable>;
new-zones-directory <replaceable>quoted_string</replaceable>;
no-case-compress { <replaceable>address_match_element</replaceable>; ... };
@ -673,7 +672,6 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
min-retry-time <replaceable>integer</replaceable>;
minimal-any <replaceable>boolean</replaceable>;
minimal-responses ( no-auth | no-auth-recursive | <replaceable>boolean</replaceable> );
mirror <replaceable>boolean</replaceable>;
multi-master <replaceable>boolean</replaceable>;
new-zones-directory <replaceable>quoted_string</replaceable>;
no-case-compress { <replaceable>address_match_element</replaceable>; ... };
@ -864,7 +862,6 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
max-zone-ttl ( unlimited | <replaceable>ttlval</replaceable> );
min-refresh-time <replaceable>integer</replaceable>;
min-retry-time <replaceable>integer</replaceable>;
mirror <replaceable>boolean</replaceable>;
multi-master <replaceable>boolean</replaceable>;
notify ( explicit | master-only | <replaceable>boolean</replaceable> );
notify-delay <replaceable>integer</replaceable>;
@ -890,7 +887,7 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
transfer-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) [ port (
<replaceable>integer</replaceable> | * ) ] [ dscp <replaceable>integer</replaceable> ];
try-tcp-refresh <replaceable>boolean</replaceable>;
type ( primary | master | secondary | slave |
type ( primary | master | secondary | slave | mirror |
delegation-only | forward | hint | redirect |
static-stub | stub );
update-check-ksk <replaceable>boolean</replaceable>;
@ -969,7 +966,6 @@ zone <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
max-zone-ttl ( unlimited | <replaceable>ttlval</replaceable> );
min-refresh-time <replaceable>integer</replaceable>;
min-retry-time <replaceable>integer</replaceable>;
mirror <replaceable>boolean</replaceable>;
multi-master <replaceable>boolean</replaceable>;
notify ( explicit | master-only | <replaceable>boolean</replaceable> );
notify-delay <replaceable>integer</replaceable>;
@ -993,8 +989,9 @@ zone <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
transfer-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * )
] [ dscp <replaceable>integer</replaceable> ];
try-tcp-refresh <replaceable>boolean</replaceable>;
type ( primary | master | secondary | slave | delegation-only |
forward | hint | redirect | static-stub | stub );
type ( primary | master | secondary | slave | mirror |
delegation-only | forward | hint | redirect | static-stub |
stub );
update-check-ksk <replaceable>boolean</replaceable>;
update-policy ( local | { ( deny | grant ) <replaceable>string</replaceable> ( 6to4-self |
external | krb5-self | krb5-selfsub | krb5-subdomain | ms-self

View file

@ -853,7 +853,6 @@ view
max-zone-ttl ( unlimited | <em class="replaceable"><code>ttlval</code></em> );<br>
min-refresh-time <em class="replaceable"><code>integer</code></em>;<br>
min-retry-time <em class="replaceable"><code>integer</code></em>;<br>
mirror <em class="replaceable"><code>boolean</code></em>;<br>
multi-master <em class="replaceable"><code>boolean</code></em>;<br>
notify ( explicit | master-only | <em class="replaceable"><code>boolean</code></em> );<br>
notify-delay <em class="replaceable"><code>integer</code></em>;<br>
@ -879,7 +878,7 @@ view
transfer-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * ) [ port (<br>
    <em class="replaceable"><code>integer</code></em> | * ) ] [ dscp <em class="replaceable"><code>integer</code></em> ];<br>
try-tcp-refresh <em class="replaceable"><code>boolean</code></em>;<br>
type ( primary | master | secondary | slave |<br>
type ( primary | master | secondary | slave | mirror |<br>
    delegation-only | forward | hint | redirect |<br>
    static-stub | stub );<br>
update-check-ksk <em class="replaceable"><code>boolean</code></em>;<br>
@ -959,7 +958,6 @@ zone
max-zone-ttl ( unlimited | <em class="replaceable"><code>ttlval</code></em> );<br>
min-refresh-time <em class="replaceable"><code>integer</code></em>;<br>
min-retry-time <em class="replaceable"><code>integer</code></em>;<br>
mirror <em class="replaceable"><code>boolean</code></em>;<br>
multi-master <em class="replaceable"><code>boolean</code></em>;<br>
notify ( explicit | master-only | <em class="replaceable"><code>boolean</code></em> );<br>
notify-delay <em class="replaceable"><code>integer</code></em>;<br>
@ -983,8 +981,9 @@ zone
transfer-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * ) [ port ( <em class="replaceable"><code>integer</code></em> | * )<br>
    ] [ dscp <em class="replaceable"><code>integer</code></em> ];<br>
try-tcp-refresh <em class="replaceable"><code>boolean</code></em>;<br>
type ( primary | master | secondary | slave | delegation-only |<br>
    forward | hint | redirect | static-stub | stub );<br>
type ( primary | master | secondary | slave | mirror |<br>
    delegation-only | forward | hint | redirect | static-stub |<br>
    stub );<br>
update-check-ksk <em class="replaceable"><code>boolean</code></em>;<br>
update-policy ( local | { ( deny | grant ) <em class="replaceable"><code>string</code></em> ( 6to4-self |<br>
    external | krb5-self | krb5-subdomain | ms-self | ms-subdomain<br>

View file

@ -6978,6 +6978,9 @@ removed(dns_zone_t *zone, void *uap) {
case dns_zone_slave:
type = "slave";
break;
case dns_zone_mirror:
type = "mirror";
break;
case dns_zone_stub:
type = "stub";
break;
@ -10162,7 +10165,8 @@ named_server_retransfercommand(named_server_t *server, isc_lex_t *lex,
dns_zone_detach(&raw);
}
type = dns_zone_gettype(zone);
if (type == dns_zone_slave || type == dns_zone_stub ||
if (type == dns_zone_slave || type == dns_zone_mirror ||
type == dns_zone_stub ||
(type == dns_zone_redirect &&
dns_zone_getredirecttype(zone) == dns_zone_slave))
dns_zone_forcereload(zone);
@ -10194,7 +10198,9 @@ named_server_reloadcommand(named_server_t *server, isc_lex_t *lex,
msg = "server reload successful";
} else {
type = dns_zone_gettype(zone);
if (type == dns_zone_slave || type == dns_zone_stub) {
if (type == dns_zone_slave || type == dns_zone_mirror ||
type == dns_zone_stub)
{
dns_zone_refresh(zone);
dns_zone_detach(&zone);
msg = "zone refresh queued";
@ -10285,7 +10291,7 @@ named_server_refreshcommand(named_server_t *server, isc_lex_t *lex,
isc_result_t result;
dns_zone_t *zone = NULL, *raw = NULL;
const char msg1[] = "zone refresh queued";
const char msg2[] = "not a slave or stub zone";
const char msg2[] = "not a slave, mirror, or stub zone";
dns_zonetype_t type;
result = zone_from_args(server, lex, NULL, &zone, NULL,
@ -10303,7 +10309,9 @@ named_server_refreshcommand(named_server_t *server, isc_lex_t *lex,
}
type = dns_zone_gettype(zone);
if (type == dns_zone_slave || type == dns_zone_stub) {
if (type == dns_zone_slave || type == dns_zone_mirror ||
type == dns_zone_stub)
{
dns_zone_refresh(zone);
dns_zone_detach(&zone);
(void) putstr(text, msg1);
@ -13495,6 +13503,7 @@ named_server_delzone(named_server_t *server, isc_lex_t *lex,
TCHECK(putstr(text, zonename));
TCHECK(putstr(text, "' and associated files will be deleted."));
} else if (dns_zone_gettype(mayberaw) == dns_zone_slave ||
dns_zone_gettype(mayberaw) == dns_zone_mirror ||
dns_zone_gettype(mayberaw) == dns_zone_stub)
{
bool first;
@ -14037,7 +14046,10 @@ named_server_zonestatus(named_server_t *server, isc_lex_t *lex,
type = "master";
break;
case dns_zone_slave:
type = dns_zone_ismirror(zone) ? "mirror" : "slave";
type = "slave";
break;
case dns_zone_mirror:
type = "mirror";
break;
case dns_zone_stub:
type = "stub";
@ -14093,6 +14105,7 @@ named_server_zonestatus(named_server_t *server, isc_lex_t *lex,
/* Refresh/expire times */
if (zonetype == dns_zone_slave ||
zonetype == dns_zone_mirror ||
zonetype == dns_zone_stub ||
zonetype == dns_zone_redirect)
{

View file

@ -94,6 +94,7 @@ user_zonetype( dns_zone_t *zone ) {
{ dns_zone_none, "none" },
{ dns_zone_master, "master" },
{ dns_zone_slave, "slave" },
{ dns_zone_mirror, "mirror" },
{ dns_zone_stub, "stub" },
{ dns_zone_staticstub, "static-stub" },
{ dns_zone_key, "key" },

View file

@ -755,8 +755,13 @@ checknames(dns_zonetype_t ztype, const cfg_obj_t **maps,
isc_result_t result;
switch (ztype) {
case dns_zone_slave: zone = "slave"; break;
case dns_zone_master: zone = "master"; break;
case dns_zone_slave:
case dns_zone_mirror:
zone = "slave";
break;
case dns_zone_master:
zone = "master";
break;
default:
INSIST(0);
}
@ -828,6 +833,37 @@ isself(dns_view_t *myview, dns_tsigkey_t *mykey,
return (view == myview);
}
/*%
* For mirror zones, change "notify yes;" to "notify explicit;", informing the
* user only if "notify" was explicitly configured rather than inherited from
* default configuration.
*/
static dns_notifytype_t
process_notifytype(dns_notifytype_t ntype, dns_zonetype_t ztype,
const char *zname, const cfg_obj_t **maps)
{
const cfg_obj_t *obj = NULL;
/*
* Return the original setting if this is not a mirror zone or if the
* zone is configured with something else than "notify yes;".
*/
if (ztype != dns_zone_mirror || ntype != dns_notifytype_yes) {
return (ntype);
}
/*
* Only log a message if "notify" was set in the configuration
* hierarchy supplied in 'maps'.
*/
if (named_config_get(maps, "notify", &obj) == ISC_R_SUCCESS) {
cfg_obj_log(obj, named_g_lctx, ISC_LOG_INFO,
"'notify explicit;' will be used for mirror zone "
"'%s'", zname);
}
return (dns_notifytype_explicit);
}
isc_result_t
named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
@ -982,7 +1018,7 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
return (ISC_R_FAILURE);
}
if (ztype == dns_zone_slave)
if (ztype == dns_zone_slave || ztype == dns_zone_mirror)
masterformat = dns_masterformat_raw;
else
masterformat = dns_masterformat_text;
@ -1076,7 +1112,7 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
/*
* Notify messages are processed by the raw zone if it exists.
*/
if (ztype == dns_zone_slave)
if (ztype == dns_zone_slave || ztype == dns_zone_mirror)
RETERR(configure_zone_acl(zconfig, vconfig, config,
allow_notify, ac, mayberaw,
dns_zone_setnotifyacl,
@ -1182,6 +1218,8 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
else
INSIST(0);
}
notifytype = process_notifytype(notifytype, ztype, zname,
nodefault);
if (raw != NULL)
dns_zone_setnotifytype(raw, dns_notifytype_no);
dns_zone_setnotifytype(zone, notifytype);
@ -1537,7 +1575,7 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
}
}
if (ztype == dns_zone_slave) {
if (ztype == dns_zone_slave || ztype == dns_zone_mirror) {
RETERR(configure_zone_acl(zconfig, vconfig, config,
allow_update_forwarding, ac,
mayberaw, dns_zone_setforwardacl,
@ -1695,12 +1733,38 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
* Configure slave functionality.
*/
switch (ztype) {
case dns_zone_mirror:
/*
* Disable outgoing zone transfers for mirror zones unless they
* are explicitly enabled by zone configuration.
*/
obj = NULL;
(void)cfg_map_get(zoptions, "allow-transfer", &obj);
if (obj == NULL) {
dns_acl_t *none;
RETERR(dns_acl_none(mctx, &none));
dns_zone_setxfracl(zone, none);
dns_acl_detach(&none);
}
/* FALLTHROUGH */
case dns_zone_slave:
case dns_zone_stub:
case dns_zone_redirect:
count = 0;
obj = NULL;
(void)cfg_map_get(zoptions, "masters", &obj);
/*
* Use the built-in master server list if one was not
* explicitly specified and this is a root zone mirror.
*/
if (obj == NULL && ztype == dns_zone_mirror &&
dns_name_equal(dns_zone_getorigin(zone), dns_rootname))
{
result = named_config_getmastersdef(named_g_config,
DEFAULT_IANA_ROOT_ZONE_MASTERS,
&obj);
RETERR(result);
}
if (obj != NULL) {
dns_ipkeylist_t ipkl;
dns_ipkeylist_init(&ipkl);
@ -1727,35 +1791,6 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
}
dns_zone_setoption(mayberaw, DNS_ZONEOPT_MULTIMASTER, multi);
obj = NULL;
(void)cfg_map_get(zoptions, "mirror", &obj);
if (obj != NULL) {
bool mirror = cfg_obj_asboolean(obj);
dns_zone_setoption(mayberaw, DNS_ZONEOPT_MIRROR,
mirror);
if (mirror) {
/*
* Disable outgoing zone transfers unless they
* are explicitly enabled by zone
* configuration.
*/
obj = NULL;
(void)cfg_map_get(zoptions, "allow-transfer",
&obj);
if (obj == NULL) {
dns_acl_t *none;
RETERR(dns_acl_none(mctx, &none));
dns_zone_setxfracl(zone, none);
dns_acl_detach(&none);
}
/*
* Only allow "also-notify".
*/
notifytype = dns_notifytype_explicit;
dns_zone_setnotifytype(zone, notifytype);
}
}
obj = NULL;
result = named_config_get(maps, "max-transfer-time-in", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
@ -1895,7 +1930,7 @@ named_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) {
const char *cfilename;
const char *zfilename;
dns_zone_t *raw = NULL;
bool has_raw, mirror;
bool has_raw;
dns_zonetype_t ztype;
zoptions = cfg_tuple_get(zconfig, "options");
@ -1935,21 +1970,6 @@ named_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) {
return (false);
}
/*
* Do not reuse a zone whose "mirror" setting was changed.
*/
obj = NULL;
mirror = false;
(void)cfg_map_get(zoptions, "mirror", &obj);
if (obj != NULL) {
mirror = cfg_obj_asboolean(obj);
}
if (dns_zone_ismirror(zone) != mirror) {
dns_zone_log(zone, ISC_LOG_DEBUG(1),
"not reusable: mirror setting changed");
return (false);
}
if (zonetype_fromconfig(zoptions) != ztype) {
dns_zone_log(zone, ISC_LOG_DEBUG(1),
"not reusable: type mismatch");

View file

@ -115,6 +115,8 @@ main(int argc, char **argv) {
strcmp(argv[1], "seconary") == 0)
{
zonetype = CFG_ZONE_SLAVE;
} else if (strcmp(argv[1], "mirror") == 0) {
zonetype = CFG_ZONE_MIRROR;
} else if (strcmp(argv[1], "stub") == 0) {
zonetype = CFG_ZONE_STUB;
} else if (strcmp(argv[1], "static-stub") == 0) {

View file

@ -0,0 +1,20 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
recursion yes;
allow-recursion { none; };
};
zone "." {
type mirror;
masters { 127.0.0.1; };
};

View file

@ -0,0 +1,15 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
zone "." {
type mirror;
notify yes;
};

View file

@ -0,0 +1,14 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
zone "foo." {
type mirror;
};

View file

@ -0,0 +1,18 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
recursion no;
};
zone "." {
type mirror;
};

View file

@ -0,0 +1,18 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
notify yes;
};
zone "." {
type mirror;
};

View file

@ -0,0 +1,14 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
zone "." {
type mirror;
};

View file

@ -0,0 +1,17 @@
Copyright (C) Internet Systems Consortium, Inc. ("ISC")
See COPYRIGHT in the source root or http://isc.org/copyright.html for terms.
This test checks whether zones configured with "type mirror;" behave as
expected.
ns1 is an authoritative-only server. It only serves the root zone, which is
mirrored by ns3.
ns2 is an authoritative-only server. It serves a number of zones, some of which
are delegated to it by ns1 and used in recursive resolution tests aimed at ns3
while others are only served so that ns3 has a primary server to mirror zones
from during various tests of the mirror zone implementation.
ns3 is a recursive resolver. It has a number of mirror zones configured. This
is the only server whose behavior is being examined by this system test.

View file

@ -11,6 +11,7 @@ rm -f */*.conf
rm -f */*.db
rm -f */*.jnl
rm -f */*.mirror
rm -f */*.nzd*
rm -f */*.prev
rm -f */*.signed
rm -f */K*

View file

@ -45,6 +45,11 @@ zone "initially-unavailable" {
allow-transfer { 10.53.0.254; };
};
zone "verify-addzone" {
type master;
file "verify-addzone.db.original.signed";
};
zone "verify-axfr" {
type master;
file "verify-axfr.db.signed";

View file

@ -36,7 +36,7 @@ ORIGINAL_SERIAL=`awk '$2 == "SOA" {print $5}' verify.db.in`
UPDATED_SERIAL_BAD=`expr ${ORIGINAL_SERIAL} + 1`
UPDATED_SERIAL_GOOD=`expr ${ORIGINAL_SERIAL} + 2`
for variant in axfr ixfr load reconfig untrusted; do
for variant in addzone axfr ixfr load reconfig untrusted; do
zone=verify-$variant
infile=verify.db.in
zonefile=verify-$variant.db

View file

@ -29,6 +29,7 @@ options {
recursion yes;
allow-query-cache { 10.53.0.1; };
trust-anchor-telemetry yes;
allow-new-zones yes;
};
zone "." {
@ -37,62 +38,54 @@ zone "." {
};
zone "." {
type slave;
type mirror;
masters { 10.53.0.1; };
mirror yes;
file "root.db.mirror";
};
zone "initially-unavailable" {
type slave;
type mirror;
masters { 10.53.0.2; };
mirror yes;
file "initially-unavailable.db.mirror";
use-alt-transfer-source no;
};
zone "verify-axfr" {
type slave;
type mirror;
masters { 10.53.0.2; };
mirror yes;
file "verify-axfr.db.mirror";
};
zone "verify-ixfr" {
type slave;
type mirror;
masters { 10.53.0.2; };
mirror yes;
file "verify-ixfr.db.mirror";
masterfile-format text;
};
zone "verify-load" {
type slave;
type mirror;
masters { 10.53.0.2; };
mirror yes;
file "verify-load.db.mirror";
masterfile-format text;
};
zone "verify-reconfig" {
type slave;
type mirror;
masters { 10.53.0.2; };
mirror yes;
file "verify-reconfig.db.mirror";
masterfile-format text;
};
zone "verify-unsigned" {
type slave;
type mirror;
masters { 10.53.0.2; };
mirror yes;
file "verify-unsigned.db.mirror";
};
zone "verify-untrusted" {
type slave;
type mirror;
masters { 10.53.0.2; };
mirror yes;
file "verify-untrusted.db.mirror";
};

View file

@ -21,6 +21,4 @@ copy_setports ns3/named.conf.in ns3/named.conf
( cd ns1 && $SHELL -e sign.sh )
cat ns2/verify-axfr.db.bad.signed > ns2/verify-axfr.db.signed
cat ns2/verify-ixfr.db.original.signed > ns2/verify-ixfr.db.signed
cat ns2/verify-load.db.bad.signed > ns3/verify-load.db.mirror
cat ns2/verify-untrusted.db.original.signed > ns2/verify-untrusted.db.signed

View file

@ -380,7 +380,7 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "checking that \"rndc reconfig\" properly handles a yes -> no \"mirror\" setting change ($n)"
echo_i "checking that \"rndc reconfig\" properly handles a mirror -> slave zone type change ($n)"
ret=0
# Sanity check before we start.
$DIG $DIGOPTS @10.53.0.3 +norec verify-reconfig SOA > dig.out.ns3.test$n.1 2>&1 || ret=1
@ -390,13 +390,13 @@ grep "flags:.* ad" dig.out.ns3.test$n.1 > /dev/null || ret=1
# Reconfigure the zone so that it is no longer a mirror zone.
# (NOTE: Keep the embedded newline in the sed function list below.)
sed '/^zone "verify-reconfig" {$/,/^};$/ {
s/mirror yes;/mirror no;/
s/type mirror;/type slave;/
}' ns3/named.conf > ns3/named.conf.modified
mv ns3/named.conf.modified ns3/named.conf
nextpart ns3/named.run > /dev/null
$RNDCCMD 10.53.0.3 reconfig > /dev/null 2>&1
# Zones whose "mirror" setting was changed should not be reusable, which means
# the tested zone should have been reloaded from disk.
# Zones whose type was changed should not be reusable, which means the tested
# zone should have been reloaded from disk.
wait_for_load verify-reconfig ${ORIGINAL_SERIAL} ns3/named.run
# Ensure responses sourced from the reconfigured zone have AA=1 and AD=0.
$DIG $DIGOPTS @10.53.0.3 +norec verify-reconfig SOA > dig.out.ns3.test$n.2 2>&1 || ret=1
@ -407,7 +407,7 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "checking that \"rndc reconfig\" properly handles a no -> yes \"mirror\" setting change ($n)"
echo_i "checking that \"rndc reconfig\" properly handles a slave -> mirror zone type change ($n)"
ret=0
# Put an incorrectly signed version of the zone in the zone file used by ns3.
nextpart ns3/named.run > /dev/null
@ -415,7 +415,7 @@ cat ns2/verify-reconfig.db.bad.signed > ns3/verify-reconfig.db.mirror
# Reconfigure the zone so that it is a mirror zone again.
# (NOTE: Keep the embedded newline in the sed function list below.)
sed '/^zone "verify-reconfig" {$/,/^};$/ {
s/mirror no;/mirror yes;/
s/type slave;/type mirror;/
}' ns3/named.conf > ns3/named.conf.modified
mv ns3/named.conf.modified ns3/named.conf
$RNDCCMD 10.53.0.3 reconfig > /dev/null 2>&1
@ -427,6 +427,39 @@ nextpart ns3/named.run | grep "No correct RSASHA256 signature for verify-reconfi
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "checking that a mirror zone can be added using rndc ($n)"
ret=0
# Sanity check: the zone should not exist in the root zone.
$DIG $DIGOPTS @10.53.0.3 +norec verify-addzone SOA > dig.out.ns3.test$n.1 2>&1 || ret=1
grep "NXDOMAIN" dig.out.ns3.test$n.1 > /dev/null || ret=1
grep "flags:.* aa" dig.out.ns3.test$n.1 > /dev/null && ret=1
grep "flags:.* ad" dig.out.ns3.test$n.1 > /dev/null || ret=1
# Mirror a zone which does not exist in the root zone.
nextpart ns3/named.run > /dev/null
$RNDCCMD 10.53.0.3 addzone verify-addzone '{ type mirror; masters { 10.53.0.2; }; };' > rndc.out.ns3.test$n 2>&1 || ret=1
wait_for_transfer verify-addzone
# Check whether the mirror zone was added and whether it behaves as expected.
$DIG $DIGOPTS @10.53.0.3 +norec verify-addzone SOA > dig.out.ns3.test$n.2 2>&1 || ret=1
grep "NOERROR" dig.out.ns3.test$n.2 > /dev/null || ret=1
grep "flags:.* aa" dig.out.ns3.test$n.2 > /dev/null && ret=1
grep "flags:.* ad" dig.out.ns3.test$n.2 > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "checking that a mirror zone can be deleted using rndc ($n)"
ret=0
# Remove the mirror zone added in the previous test.
$RNDCCMD 10.53.0.3 delzone verify-addzone > rndc.out.ns3.test$n 2>&1 || ret=1
# Check whether the mirror zone was removed.
$DIG $DIGOPTS @10.53.0.3 +norec verify-addzone SOA > dig.out.ns3.test$n 2>&1 || ret=1
grep "NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1
grep "flags:.* aa" dig.out.ns3.test$n > /dev/null && ret=1
grep "flags:.* ad" dig.out.ns3.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "ensuring trust anchor telemetry queries are sent upstream for a mirror zone ($n)"
ret=0

View file

@ -7317,8 +7317,8 @@ options {
</listitem>
</varlistentry>
<varlistentry>
<term><command>allow-transfer</command></term>
<varlistentry xml:id="allow_transfer">
<term xml:id="allow_transfer_term"><command>allow-transfer</command></term>
<listitem>
<para>
Specifies which hosts are allowed to
@ -11410,6 +11410,7 @@ view "external" {
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="master.zoneopt.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="slave.zoneopt.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="mirror.zoneopt.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="hint.zoneopt.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="stub.zoneopt.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="static-stub.zoneopt.xml"/>
@ -11429,6 +11430,7 @@ view "external" {
acceptable values include:
<varname>master</varname> (or <varname>primary</varname>),
<varname>slave</varname> (or <varname>secondary</varname>),
<varname>mirror</varname>,
<varname>delegation-only</varname>,
<varname>forward</varname>,
<varname>hint</varname>,
@ -11565,6 +11567,97 @@ view "external" {
</para>
</entry>
</row>
<row rowsep="0">
<entry colname="1">
<para>
<varname>mirror</varname>
</para>
</entry>
<entry colname="2">
<para>
</para>
<para>
A mirror zone acts like a zone of type
<userinput>secondary</userinput> whose data is
subject to DNSSEC validation before being used
in answers. Validation is performed during the
zone transfer process, and again when the zone
file is loaded from disk when
<command>named</command> is restarted. If
validation fails, a retransfer of the zone is
scheduled; if the mirror zone had not previously
been loaded or if the previous version has
expired, traditional DNS recursion will be used
to look up the answers instead.
</para>
<para>
For validation to succeed, a key-signing key
(KSK) for the zone must be configured as a trust
anchor in <filename>named.conf</filename>: that
is, a key for the zone must either be specified
in <command>managed-keys</command> or
<command>trusted-keys</command>, or in the case
of the root zone,
<command>dnssec-validation</command> must be set
to <userinput>auto</userinput>. Answers coming
from a mirror zone look almost exactly like
answers from a zone of type
<userinput>secondary</userinput>, with the
notable exceptions that the AA bit
("authoritative answer") is not set, and the AD
bit ("authenticated data") is.
</para>
<para>
Since mirror zones are intended to be used by
recursive resolvers, adding one to a view with
recursion disabled is considered to be a
configuration error.
</para>
<para>
When configuring NOTIFY for a mirror zone, only
<userinput>notify no;</userinput> and
<userinput>notify explicit;</userinput> can be
used. Using any other
<userinput>notify</userinput> setting at the
zone level is a configuration error. Using any
other <userinput>notify</userinput> setting at
the <userinput>options</userinput> or
<userinput>view</userinput> level will cause
that setting to be overridden with
<userinput>notify explicit;</userinput> for the
mirror zone in question.
</para>
<para>
Outgoing transfers of mirror zones are disabled
by default but may be enabled using
<xref endterm="allow_transfer_term" linkend="allow_transfer"/>.
</para>
<para>
While any zone may be configured with this type,
it is intended to be used to set up a fast local
copy of the root zone, similar to the one
described in RFC 7706. Note, however, that
mirror zones are not supposed to augment the
example configuration provided by RFC 7706 but
rather to replace it altogether.
</para>
<para>
A default list of primary servers for the root
zone is built into <command>named</command> and
thus IANA root zone mirroring can be enabled
using the following configuration:
</para>
<programlisting>zone "." {
type mirror;
};</programlisting>
<para>
To make mirror zone contents persist between
<command>named</command> restarts, use the
<xref endterm="file_option_term" linkend="file_option"/>
option.
</para>
</entry>
</row>
<row rowsep="0">
<entry colname="1">
<para>
@ -12067,19 +12160,20 @@ view "external" {
</listitem>
</varlistentry>
<varlistentry>
<term><command>file</command></term>
<varlistentry xml:id="file_option">
<term xml:id="file_option_term"><command>file</command></term>
<listitem>
<para>
Set the zone's filename. In <command>master</command>,
<command>hint</command>, and <command>redirect</command>
zones which do not have <command>masters</command>
defined, zone data is loaded from this file. In
<command>slave</command>, <command>stub</command>, and
<command>redirect</command> zones which do have
<command>masters</command> defined, zone data is
retrieved from another server and saved in this file.
This option is not applicable to other zone types.
<command>slave</command>, <command>mirror</command>,
<command>stub</command>, and <command>redirect</command>
zones which do have <command>masters</command>
defined, zone data is retrieved from another server
and saved in this file. This option is not
applicable to other zone types.
</para>
</listitem>
</varlistentry>
@ -12524,68 +12618,6 @@ example.com. NS ns2.example.net.
</listitem>
</varlistentry>
<varlistentry>
<term><command>mirror</command></term>
<listitem>
<para>
If set to <userinput>yes</userinput>, this causes the
zone to become a mirror zone. A mirror zone is a
<userinput>secondary</userinput> zone whose data
is subject to DNSSEC validation before being
used in answers. The default is
<userinput>no</userinput>.
</para>
<para>
A mirror zone's contents are validated during the transfer
process, and again when the zone file is loaded from disk
when <command>named</command> is restarted. If validation
fails, a retransfer of the zone is scheduled; if the mirror
zone had not previously been loaded or if the previous
version has expired, traditional DNS recursion will be used
to look up the answers instead.
</para>
<para>
For validation to succeed, a key-signing key (KSK) for
the zone must be configured as a trust anchor in
<filename>named.conf</filename>:
that is, a key for the zone must either be specified in
<command>managed-keys</command> or
<command>trusted-keys</command>, or in the case of
the root zone, <command>dnssec-validation</command>
must be set to <userinput>auto</userinput>.
Answers coming from a mirror zone look almost exactly like
answers from a normal slave zone, with the notable
exceptions that the AA bit ("authoritative answer") is
not set, and the AD bit ("authenticated data") is.
</para>
<para>
Though this option can be used for other zones, it
is intended to be used to set up a fast local copy of
the root zone, as described in RFC 7706.
This can be done by using the following configuration:
</para>
<programlisting>zone "." {
type slave;
mirror yes;
file "root.mirror";
masters {
192.228.79.201; # b.root-servers.net
192.33.4.12; # c.root-servers.net
192.5.5.241; # f.root-servers.net
192.112.36.4; # g.root-servers.net
193.0.14.129; # k.root-servers.net
192.0.47.132; # xfr.cjr.dns.icann.org
192.0.32.132; # xfr.lax.dns.icann.org
2001:500:84::b; # b.root-servers.net
2001:500:2f::f; # f.root-servers.net
2001:7fd::1; # k.root-servers.net
2620:0:2830:202::132; # xfr.cjr.dns.icann.org
2620:0:2d0:202::132; # xfr.lax.dns.icann.org
};
};</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term><command>multi-master</command></term>
<listitem>

View file

@ -2531,7 +2531,6 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<span class="command"><strong>min-retry-time</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>minimal-any</strong></span> <em class="replaceable"><code>boolean</code></em>;
<span class="command"><strong>minimal-responses</strong></span> ( no-auth | no-auth-recursive | <em class="replaceable"><code>boolean</code></em> );
<span class="command"><strong>mirror</strong></span> <em class="replaceable"><code>boolean</code></em>;
<span class="command"><strong>multi-master</strong></span> <em class="replaceable"><code>boolean</code></em>;
<span class="command"><strong>new-zones-directory</strong></span> <em class="replaceable"><code>quoted_string</code></em>;
<span class="command"><strong>no-case-compress</strong></span> { <em class="replaceable"><code>address_match_element</code></em>; ... };
@ -5369,7 +5368,9 @@ options {
It is now ignored with some warning messages.
</p>
</dd>
<dt><span class="term"><span class="command"><strong>allow-transfer</strong></span></span></dt>
<dt>
<a name="allow_transfer"></a><span class="term"><a name="allow_transfer_term"></a><span class="command"><strong>allow-transfer</strong></span></span>
</dt>
<dd>
<p>
Specifies which hosts are allowed to
@ -9398,7 +9399,6 @@ view "external" {
<span class="command"><strong>max-transfer-time-out</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>min-refresh-time</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>min-retry-time</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>mirror</strong></span> <em class="replaceable"><code>boolean</code></em>;
<span class="command"><strong>multi-master</strong></span> <em class="replaceable"><code>boolean</code></em>;
<span class="command"><strong>notify</strong></span> ( explicit | master-only | <em class="replaceable"><code>boolean</code></em> );
<span class="command"><strong>notify-delay</strong></span> <em class="replaceable"><code>integer</code></em>;
@ -9421,6 +9421,50 @@ view "external" {
};
</pre>
<pre class="programlisting">
<span class="command"><strong>zone</strong></span> <em class="replaceable"><code>string</code></em> [ <em class="replaceable"><code>class</code></em> ] {
<span class="command"><strong>type</strong></span> mirror;
<span class="command"><strong>allow-notify</strong></span> { <em class="replaceable"><code>address_match_element</code></em>; ... };
<span class="command"><strong>allow-query</strong></span> { <em class="replaceable"><code>address_match_element</code></em>; ... };
<span class="command"><strong>allow-query-on</strong></span> { <em class="replaceable"><code>address_match_element</code></em>; ... };
<span class="command"><strong>allow-transfer</strong></span> { <em class="replaceable"><code>address_match_element</code></em>; ... };
<span class="command"><strong>allow-update-forwarding</strong></span> { <em class="replaceable"><code>address_match_element</code></em>; ... };
<span class="command"><strong>also-notify</strong></span> [ port <em class="replaceable"><code>integer</code></em> ] [ dscp <em class="replaceable"><code>integer</code></em> ] { ( <em class="replaceable"><code>masters</code></em> | <em class="replaceable"><code>ipv4_address</code></em> [ port <em class="replaceable"><code>integer</code></em> ] | <em class="replaceable"><code>ipv6_address</code></em> [ port <em class="replaceable"><code>integer</code></em> ] ) [ key <em class="replaceable"><code>string</code></em> ]; ... };
<span class="command"><strong>alt-transfer-source</strong></span> ( <em class="replaceable"><code>ipv4_address</code></em> | * ) [ port ( <em class="replaceable"><code>integer</code></em> | * ) ] [ dscp <em class="replaceable"><code>integer</code></em> ];
<span class="command"><strong>alt-transfer-source-v6</strong></span> ( <em class="replaceable"><code>ipv6_address</code></em> | * ) [ port ( <em class="replaceable"><code>integer</code></em> | * ) ] [ dscp <em class="replaceable"><code>integer</code></em> ];
<span class="command"><strong>check-names</strong></span> ( fail | warn | ignore );
<span class="command"><strong>database</strong></span> <em class="replaceable"><code>string</code></em>;
<span class="command"><strong>file</strong></span> <em class="replaceable"><code>quoted_string</code></em>;
<span class="command"><strong>ixfr-from-differences</strong></span> <em class="replaceable"><code>boolean</code></em>;
<span class="command"><strong>journal</strong></span> <em class="replaceable"><code>quoted_string</code></em>;
<span class="command"><strong>masterfile-format</strong></span> ( map | raw | text );
<span class="command"><strong>masterfile-style</strong></span> ( full | relative );
<span class="command"><strong>masters</strong></span> [ port <em class="replaceable"><code>integer</code></em> ] [ dscp <em class="replaceable"><code>integer</code></em> ] { ( <em class="replaceable"><code>masters</code></em> | <em class="replaceable"><code>ipv4_address</code></em> [ port <em class="replaceable"><code>integer</code></em> ] | <em class="replaceable"><code>ipv6_address</code></em> [ port <em class="replaceable"><code>integer</code></em> ] ) [ key <em class="replaceable"><code>string</code></em> ]; ... };
<span class="command"><strong>max-journal-size</strong></span> ( default | unlimited | <em class="replaceable"><code>sizeval</code></em> );
<span class="command"><strong>max-records</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>max-refresh-time</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>max-retry-time</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>max-transfer-idle-in</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>max-transfer-idle-out</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>max-transfer-time-in</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>max-transfer-time-out</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>min-refresh-time</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>min-retry-time</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>multi-master</strong></span> <em class="replaceable"><code>boolean</code></em>;
<span class="command"><strong>notify</strong></span> ( explicit | master-only | <em class="replaceable"><code>boolean</code></em> );
<span class="command"><strong>notify-delay</strong></span> <em class="replaceable"><code>integer</code></em>;
<span class="command"><strong>notify-source</strong></span> ( <em class="replaceable"><code>ipv4_address</code></em> | * ) [ port ( <em class="replaceable"><code>integer</code></em> | * ) ] [ dscp <em class="replaceable"><code>integer</code></em> ];
<span class="command"><strong>notify-source-v6</strong></span> ( <em class="replaceable"><code>ipv6_address</code></em> | * ) [ port ( <em class="replaceable"><code>integer</code></em> | * ) ] [ dscp <em class="replaceable"><code>integer</code></em> ];
<span class="command"><strong>request-expire</strong></span> <em class="replaceable"><code>boolean</code></em>;
<span class="command"><strong>request-ixfr</strong></span> <em class="replaceable"><code>boolean</code></em>;
<span class="command"><strong>transfer-source</strong></span> ( <em class="replaceable"><code>ipv4_address</code></em> | * ) [ port ( <em class="replaceable"><code>integer</code></em> | * ) ] [ dscp <em class="replaceable"><code>integer</code></em> ];
<span class="command"><strong>transfer-source-v6</strong></span> ( <em class="replaceable"><code>ipv6_address</code></em> | * ) [ port ( <em class="replaceable"><code>integer</code></em> | * ) ] [ dscp <em class="replaceable"><code>integer</code></em> ];
<span class="command"><strong>try-tcp-refresh</strong></span> <em class="replaceable"><code>boolean</code></em>;
<span class="command"><strong>use-alt-transfer-source</strong></span> <em class="replaceable"><code>boolean</code></em>;
<span class="command"><strong>zero-no-soa-ttl</strong></span> <em class="replaceable"><code>boolean</code></em>;
<span class="command"><strong>zone-statistics</strong></span> ( full | terse | none | <em class="replaceable"><code>boolean</code></em> );
};
</pre>
<pre class="programlisting">
<span class="command"><strong>zone</strong></span> <em class="replaceable"><code>string</code></em> [ <em class="replaceable"><code>class</code></em> ] {
<span class="command"><strong>type</strong></span> hint;
<span class="command"><strong>check-names</strong></span> ( fail | warn | ignore );
@ -9519,6 +9563,7 @@ view "external" {
acceptable values include:
<code class="varname">master</code> (or <code class="varname">primary</code>),
<code class="varname">slave</code> (or <code class="varname">secondary</code>),
<code class="varname">mirror</code>,
<code class="varname">delegation-only</code>,
<code class="varname">forward</code>,
<code class="varname">hint</code>,
@ -9656,6 +9701,97 @@ view "external" {
</td>
</tr>
<tr>
<td>
<p>
<code class="varname">mirror</code>
</p>
</td>
<td>
<p>
</p>
<p>
A mirror zone acts like a zone of type
<strong class="userinput"><code>secondary</code></strong> whose data is
subject to DNSSEC validation before being used
in answers. Validation is performed during the
zone transfer process, and again when the zone
file is loaded from disk when
<span class="command"><strong>named</strong></span> is restarted. If
validation fails, a retransfer of the zone is
scheduled; if the mirror zone had not previously
been loaded or if the previous version has
expired, traditional DNS recursion will be used
to look up the answers instead.
</p>
<p>
For validation to succeed, a key-signing key
(KSK) for the zone must be configured as a trust
anchor in <code class="filename">named.conf</code>: that
is, a key for the zone must either be specified
in <span class="command"><strong>managed-keys</strong></span> or
<span class="command"><strong>trusted-keys</strong></span>, or in the case
of the root zone,
<span class="command"><strong>dnssec-validation</strong></span> must be set
to <strong class="userinput"><code>auto</code></strong>. Answers coming
from a mirror zone look almost exactly like
answers from a zone of type
<strong class="userinput"><code>secondary</code></strong>, with the
notable exceptions that the AA bit
("authoritative answer") is not set, and the AD
bit ("authenticated data") is.
</p>
<p>
Since mirror zones are intended to be used by
recursive resolvers, adding one to a view with
recursion disabled is considered to be a
configuration error.
</p>
<p>
When configuring NOTIFY for a mirror zone, only
<strong class="userinput"><code>notify no;</code></strong> and
<strong class="userinput"><code>notify explicit;</code></strong> can be
used. Using any other
<strong class="userinput"><code>notify</code></strong> setting at the
zone level is a configuration error. Using any
other <strong class="userinput"><code>notify</code></strong> setting at
the <strong class="userinput"><code>options</code></strong> or
<strong class="userinput"><code>view</code></strong> level will cause
that setting to be overridden with
<strong class="userinput"><code>notify explicit;</code></strong> for the
mirror zone in question.
</p>
<p>
Outgoing transfers of mirror zones are disabled
by default but may be enabled using
<a class="xref" href="Bv9ARM.ch05.html#allow_transfer"><span class="command"><strong>allow-transfer</strong></span></a>.
</p>
<p>
While any zone may be configured with this type,
it is intended to be used to set up a fast local
copy of the root zone, similar to the one
described in RFC 7706. Note, however, that
mirror zones are not supposed to augment the
example configuration provided by RFC 7706 but
rather to replace it altogether.
</p>
<p>
A default list of primary servers for the root
zone is built into <span class="command"><strong>named</strong></span> and
thus IANA root zone mirroring can be enabled
using the following configuration:
</p>
<pre class="programlisting">zone "." {
type mirror;
};</pre>
<p>
To make mirror zone contents persist between
<span class="command"><strong>named</strong></span> restarts, use the
<a class="xref" href="Bv9ARM.ch05.html#file_option"><span class="command"><strong>file</strong></span></a>
option.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="varname">static-stub</code>
@ -10093,18 +10229,21 @@ view "external" {
See caveats in <a class="xref" href="Bv9ARM.ch05.html#root_delegation_only"><span class="command"><strong>root-delegation-only</strong></span></a>.
</p>
</dd>
<dt><span class="term"><span class="command"><strong>file</strong></span></span></dt>
<dt>
<a name="file_option"></a><span class="term"><a name="file_option_term"></a><span class="command"><strong>file</strong></span></span>
</dt>
<dd>
<p>
Set the zone's filename. In <span class="command"><strong>master</strong></span>,
<span class="command"><strong>hint</strong></span>, and <span class="command"><strong>redirect</strong></span>
zones which do not have <span class="command"><strong>masters</strong></span>
defined, zone data is loaded from this file. In
<span class="command"><strong>slave</strong></span>, <span class="command"><strong>stub</strong></span>, and
<span class="command"><strong>redirect</strong></span> zones which do have
<span class="command"><strong>masters</strong></span> defined, zone data is
retrieved from another server and saved in this file.
This option is not applicable to other zone types.
<span class="command"><strong>slave</strong></span>, <span class="command"><strong>mirror</strong></span>,
<span class="command"><strong>stub</strong></span>, and <span class="command"><strong>redirect</strong></span>
zones which do have <span class="command"><strong>masters</strong></span>
defined, zone data is retrieved from another server
and saved in this file. This option is not
applicable to other zone types.
</p>
</dd>
<dt><span class="term"><span class="command"><strong>forward</strong></span></span></dt>
@ -10444,65 +10583,6 @@ example.com. NS ns2.example.net.
behavior is disabled by default.
</p>
</dd>
<dt><span class="term"><span class="command"><strong>mirror</strong></span></span></dt>
<dd>
<p>
If set to <strong class="userinput"><code>yes</code></strong>, this causes the
zone to become a mirror zone. A mirror zone is a
<strong class="userinput"><code>secondary</code></strong> zone whose data
is subject to DNSSEC validation before being
used in answers. The default is
<strong class="userinput"><code>no</code></strong>.
</p>
<p>
A mirror zone's contents are validated during the transfer
process, and again when the zone file is loaded from disk
when <span class="command"><strong>named</strong></span> is restarted. If validation
fails, a retransfer of the zone is scheduled; if the mirror
zone had not previously been loaded or if the previous
version has expired, traditional DNS recursion will be used
to look up the answers instead.
</p>
<p>
For validation to succeed, a key-signing key (KSK) for
the zone must be configured as a trust anchor in
<code class="filename">named.conf</code>:
that is, a key for the zone must either be specified in
<span class="command"><strong>managed-keys</strong></span> or
<span class="command"><strong>trusted-keys</strong></span>, or in the case of
the root zone, <span class="command"><strong>dnssec-validation</strong></span>
must be set to <strong class="userinput"><code>auto</code></strong>.
Answers coming from a mirror zone look almost exactly like
answers from a normal slave zone, with the notable
exceptions that the AA bit ("authoritative answer") is
not set, and the AD bit ("authenticated data") is.
</p>
<p>
Though this option can be used for other zones, it
is intended to be used to set up a fast local copy of
the root zone, as described in RFC 7706.
This can be done by using the following configuration:
</p>
<pre class="programlisting">zone "." {
type slave;
mirror yes;
file "root.mirror";
masters {
192.228.79.201; # b.root-servers.net
192.33.4.12; # c.root-servers.net
192.5.5.241; # f.root-servers.net
192.112.36.4; # g.root-servers.net
193.0.14.129; # k.root-servers.net
192.0.47.132; # xfr.cjr.dns.icann.org
192.0.32.132; # xfr.lax.dns.icann.org
2001:500:84::b; # b.root-servers.net
2001:500:2f::f; # f.root-servers.net
2001:7fd::1; # k.root-servers.net
2620:0:2830:202::132; # xfr.cjr.dns.icann.org
2620:0:2d0:202::132; # xfr.lax.dns.icann.org
};
};</pre>
</dd>
<dt><span class="term"><span class="command"><strong>multi-master</strong></span></span></dt>
<dd>
<p>

View file

@ -871,7 +871,6 @@ view
max-zone-ttl ( unlimited | <em class="replaceable"><code>ttlval</code></em> );<br>
min-refresh-time <em class="replaceable"><code>integer</code></em>;<br>
min-retry-time <em class="replaceable"><code>integer</code></em>;<br>
mirror <em class="replaceable"><code>boolean</code></em>;<br>
multi-master <em class="replaceable"><code>boolean</code></em>;<br>
notify ( explicit | master-only | <em class="replaceable"><code>boolean</code></em> );<br>
notify-delay <em class="replaceable"><code>integer</code></em>;<br>
@ -897,7 +896,7 @@ view
transfer-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * ) [ port (<br>
    <em class="replaceable"><code>integer</code></em> | * ) ] [ dscp <em class="replaceable"><code>integer</code></em> ];<br>
try-tcp-refresh <em class="replaceable"><code>boolean</code></em>;<br>
type ( primary | master | secondary | slave |<br>
type ( primary | master | secondary | slave | mirror |<br>
    delegation-only | forward | hint | redirect |<br>
    static-stub | stub );<br>
update-check-ksk <em class="replaceable"><code>boolean</code></em>;<br>
@ -977,7 +976,6 @@ zone
max-zone-ttl ( unlimited | <em class="replaceable"><code>ttlval</code></em> );<br>
min-refresh-time <em class="replaceable"><code>integer</code></em>;<br>
min-retry-time <em class="replaceable"><code>integer</code></em>;<br>
mirror <em class="replaceable"><code>boolean</code></em>;<br>
multi-master <em class="replaceable"><code>boolean</code></em>;<br>
notify ( explicit | master-only | <em class="replaceable"><code>boolean</code></em> );<br>
notify-delay <em class="replaceable"><code>integer</code></em>;<br>
@ -1001,8 +999,9 @@ zone
transfer-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * ) [ port ( <em class="replaceable"><code>integer</code></em> | * )<br>
    ] [ dscp <em class="replaceable"><code>integer</code></em> ];<br>
try-tcp-refresh <em class="replaceable"><code>boolean</code></em>;<br>
type ( primary | master | secondary | slave | delegation-only |<br>
    forward | hint | redirect | static-stub | stub );<br>
type ( primary | master | secondary | slave | mirror |<br>
    delegation-only | forward | hint | redirect | static-stub |<br>
    stub );<br>
update-check-ksk <em class="replaceable"><code>boolean</code></em>;<br>
update-policy ( local | { ( deny | grant ) <em class="replaceable"><code>string</code></em> ( 6to4-self |<br>
    external | krb5-self | krb5-subdomain | ms-self | ms-subdomain<br>

View file

@ -0,0 +1,56 @@
<!--
- Copyright (C) Internet Systems Consortium, Inc. ("ISC")
-
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
- See the COPYRIGHT file distributed with this work for additional
- information regarding copyright ownership.
-->
<!-- Generated by doc/misc/docbook-zoneopt.pl -->
<programlisting>
<command>zone</command> <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
<command>type</command> mirror;
<command>allow-notify</command> { <replaceable>address_match_element</replaceable>; ... };
<command>allow-query</command> { <replaceable>address_match_element</replaceable>; ... };
<command>allow-query-on</command> { <replaceable>address_match_element</replaceable>; ... };
<command>allow-transfer</command> { <replaceable>address_match_element</replaceable>; ... };
<command>allow-update-forwarding</command> { <replaceable>address_match_element</replaceable>; ... };
<command>also-notify</command> [ port <replaceable>integer</replaceable> ] [ dscp <replaceable>integer</replaceable> ] { ( <replaceable>masters</replaceable> | <replaceable>ipv4_address</replaceable> [ port <replaceable>integer</replaceable> ] | <replaceable>ipv6_address</replaceable> [ port <replaceable>integer</replaceable> ] ) [ key <replaceable>string</replaceable> ]; ... };
<command>alt-transfer-source</command> ( <replaceable>ipv4_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ] [ dscp <replaceable>integer</replaceable> ];
<command>alt-transfer-source-v6</command> ( <replaceable>ipv6_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ] [ dscp <replaceable>integer</replaceable> ];
<command>check-names</command> ( fail | warn | ignore );
<command>database</command> <replaceable>string</replaceable>;
<command>file</command> <replaceable>quoted_string</replaceable>;
<command>ixfr-from-differences</command> <replaceable>boolean</replaceable>;
<command>journal</command> <replaceable>quoted_string</replaceable>;
<command>masterfile-format</command> ( map | raw | text );
<command>masterfile-style</command> ( full | relative );
<command>masters</command> [ port <replaceable>integer</replaceable> ] [ dscp <replaceable>integer</replaceable> ] { ( <replaceable>masters</replaceable> | <replaceable>ipv4_address</replaceable> [ port <replaceable>integer</replaceable> ] | <replaceable>ipv6_address</replaceable> [ port <replaceable>integer</replaceable> ] ) [ key <replaceable>string</replaceable> ]; ... };
<command>max-journal-size</command> ( default | unlimited | <replaceable>sizeval</replaceable> );
<command>max-records</command> <replaceable>integer</replaceable>;
<command>max-refresh-time</command> <replaceable>integer</replaceable>;
<command>max-retry-time</command> <replaceable>integer</replaceable>;
<command>max-transfer-idle-in</command> <replaceable>integer</replaceable>;
<command>max-transfer-idle-out</command> <replaceable>integer</replaceable>;
<command>max-transfer-time-in</command> <replaceable>integer</replaceable>;
<command>max-transfer-time-out</command> <replaceable>integer</replaceable>;
<command>min-refresh-time</command> <replaceable>integer</replaceable>;
<command>min-retry-time</command> <replaceable>integer</replaceable>;
<command>multi-master</command> <replaceable>boolean</replaceable>;
<command>notify</command> ( explicit | master-only | <replaceable>boolean</replaceable> );
<command>notify-delay</command> <replaceable>integer</replaceable>;
<command>notify-source</command> ( <replaceable>ipv4_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ] [ dscp <replaceable>integer</replaceable> ];
<command>notify-source-v6</command> ( <replaceable>ipv6_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ] [ dscp <replaceable>integer</replaceable> ];
<command>request-expire</command> <replaceable>boolean</replaceable>;
<command>request-ixfr</command> <replaceable>boolean</replaceable>;
<command>transfer-source</command> ( <replaceable>ipv4_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ] [ dscp <replaceable>integer</replaceable> ];
<command>transfer-source-v6</command> ( <replaceable>ipv6_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ] [ dscp <replaceable>integer</replaceable> ];
<command>try-tcp-refresh</command> <replaceable>boolean</replaceable>;
<command>use-alt-transfer-source</command> <replaceable>boolean</replaceable>;
<command>zero-no-soa-ttl</command> <replaceable>boolean</replaceable>;
<command>zone-statistics</command> ( full | terse | none | <replaceable>boolean</replaceable> );
};
</programlisting>

View file

@ -180,7 +180,6 @@
<command>min-retry-time</command> <replaceable>integer</replaceable>;
<command>minimal-any</command> <replaceable>boolean</replaceable>;
<command>minimal-responses</command> ( no-auth | no-auth-recursive | <replaceable>boolean</replaceable> );
<command>mirror</command> <replaceable>boolean</replaceable>;
<command>multi-master</command> <replaceable>boolean</replaceable>;
<command>new-zones-directory</command> <replaceable>quoted_string</replaceable>;
<command>no-case-compress</command> { <replaceable>address_match_element</replaceable>; ... };

View file

@ -50,7 +50,6 @@
<command>max-transfer-time-out</command> <replaceable>integer</replaceable>;
<command>min-refresh-time</command> <replaceable>integer</replaceable>;
<command>min-retry-time</command> <replaceable>integer</replaceable>;
<command>mirror</command> <replaceable>boolean</replaceable>;
<command>multi-master</command> <replaceable>boolean</replaceable>;
<command>notify</command> ( explicit | master-only | <replaceable>boolean</replaceable> );
<command>notify-delay</command> <replaceable>integer</replaceable>;

View file

@ -111,6 +111,7 @@ Types:
dns_zone_none = 0,
dns_zone_master,
dns_zone_slave,
dns_zone_mirror,
dns_zone_stub,
dns_zone_hint,
dns_zone_cache,

View file

@ -35,6 +35,7 @@ options: FORCE
${CFG_TEST} --named --grammar > $@.raw ; \
${CFG_TEST} --zonegrammar master > master.zoneopt ; \
${CFG_TEST} --zonegrammar slave > slave.zoneopt ; \
${CFG_TEST} --zonegrammar mirror > mirror.zoneopt ; \
${CFG_TEST} --zonegrammar forward > forward.zoneopt ; \
${CFG_TEST} --zonegrammar hint > hint.zoneopt ; \
${CFG_TEST} --zonegrammar stub > stub.zoneopt ; \
@ -54,6 +55,7 @@ docbook: options
${PERL} docbook-options.pl options > ${top_srcdir}/bin/named/named.conf.docbook
${PERL} docbook-zoneopt.pl master.zoneopt > ${top_srcdir}/doc/arm/master.zoneopt.xml
${PERL} docbook-zoneopt.pl slave.zoneopt > ${top_srcdir}/doc/arm/slave.zoneopt.xml
${PERL} docbook-zoneopt.pl mirror.zoneopt > ${top_srcdir}/doc/arm/mirror.zoneopt.xml
${PERL} docbook-zoneopt.pl forward.zoneopt > ${top_srcdir}/doc/arm/forward.zoneopt.xml
${PERL} docbook-zoneopt.pl hint.zoneopt > ${top_srcdir}/doc/arm/hint.zoneopt.xml
${PERL} docbook-zoneopt.pl stub.zoneopt > ${top_srcdir}/doc/arm/stub.zoneopt.xml

42
doc/misc/mirror.zoneopt Normal file
View file

@ -0,0 +1,42 @@
zone <string> [ <class> ] {
type mirror;
allow-notify { <address_match_element>; ... };
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
allow-transfer { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ dscp <integer> ] { ( <masters> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
check-names ( fail | warn | ignore );
database <string>;
file <quoted_string>;
ixfr-from-differences <boolean>;
journal <quoted_string>;
masterfile-format ( map | raw | text );
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <masters> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
min-refresh-time <integer>;
min-retry-time <integer>;
multi-master <boolean>;
notify ( explicit | master-only | <boolean> );
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
notify-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
request-expire <boolean>;
request-ixfr <boolean>;
transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
try-tcp-refresh <boolean>;
use-alt-transfer-source <boolean>;
zero-no-soa-ttl <boolean>;
zone-statistics ( full | terse | none | <boolean> );
};

View file

@ -239,7 +239,6 @@ options {
min-roots <integer>; // not implemented
minimal-any <boolean>;
minimal-responses ( no-auth | no-auth-recursive | <boolean> );
mirror <boolean>;
multi-master <boolean>;
multiple-cnames <boolean>; // obsolete
named-xfer <quoted_string>; // obsolete
@ -580,7 +579,6 @@ view <string> [ <class> ] {
min-roots <integer>; // not implemented
minimal-any <boolean>;
minimal-responses ( no-auth | no-auth-recursive | <boolean> );
mirror <boolean>;
multi-master <boolean>;
new-zones-directory <quoted_string>;
no-case-compress { <address_match_element>; ... };
@ -786,7 +784,6 @@ view <string> [ <class> ] {
max-zone-ttl ( unlimited | <ttlval> );
min-refresh-time <integer>;
min-retry-time <integer>;
mirror <boolean>;
multi-master <boolean>;
notify ( explicit | master-only | <boolean> );
notify-delay <integer>;
@ -814,7 +811,7 @@ view <string> [ <class> ] {
transfer-source-v6 ( <ipv6_address> | * ) [ port (
<integer> | * ) ] [ dscp <integer> ];
try-tcp-refresh <boolean>;
type ( primary | master | secondary | slave |
type ( primary | master | secondary | slave | mirror |
delegation-only | forward | hint | redirect |
static-stub | stub );
update-check-ksk <boolean>;
@ -892,7 +889,6 @@ zone <string> [ <class> ] {
max-zone-ttl ( unlimited | <ttlval> );
min-refresh-time <integer>;
min-retry-time <integer>;
mirror <boolean>;
multi-master <boolean>;
notify ( explicit | master-only | <boolean> );
notify-delay <integer>;
@ -918,8 +914,9 @@ zone <string> [ <class> ] {
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * )
] [ dscp <integer> ];
try-tcp-refresh <boolean>;
type ( primary | master | secondary | slave | delegation-only |
forward | hint | redirect | static-stub | stub );
type ( primary | master | secondary | slave | mirror |
delegation-only | forward | hint | redirect | static-stub |
stub );
update-check-ksk <boolean>;
update-policy ( local | { ( deny | grant ) <string> ( 6to4-self |
external | krb5-self | krb5-selfsub | krb5-subdomain | ms-self

View file

@ -37,7 +37,6 @@ zone <string> [ <class> ] {
max-transfer-time-out <integer>;
min-refresh-time <integer>;
min-retry-time <integer>;
mirror <boolean>;
multi-master <boolean>;
notify ( explicit | master-only | <boolean> );
notify-delay <integer>;

View file

@ -1915,6 +1915,114 @@ check_nonzero(const cfg_obj_t *options, isc_log_t *logctx) {
return (result);
}
/*%
* Check whether NOTIFY configuration at the zone level is acceptable for a
* mirror zone. Return true if it is; return false otherwise.
*/
static bool
check_mirror_zone_notify(const cfg_obj_t *zoptions, const char *znamestr,
isc_log_t *logctx)
{
bool notify_configuration_ok = true;
const cfg_obj_t *obj = NULL;
(void)cfg_map_get(zoptions, "notify", &obj);
if (obj == NULL) {
/*
* "notify" not set at zone level. This is fine.
*/
return (true);
}
if (cfg_obj_isboolean(obj)) {
if (cfg_obj_asboolean(obj)) {
/*
* "notify yes;" set at zone level. This is an error.
*/
notify_configuration_ok = false;
}
} else {
const char *notifystr = cfg_obj_asstring(obj);
if (strcasecmp(notifystr, "explicit") != 0) {
/*
* Something else than "notify explicit;" set at zone
* level. This is an error.
*/
notify_configuration_ok = false;
}
}
if (!notify_configuration_ok) {
cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR,
"zone '%s': mirror zones can only be used with "
"'notify no;' or 'notify explicit;'", znamestr);
}
return (notify_configuration_ok);
}
/*%
* Try to determine whether recursion is available in a view without resorting
* to extraordinary measures: just check the "recursion" and "allow-recursion"
* settings. The point is to prevent accidental mirror zone misuse rather than
* to enforce some sort of policy. Recursion is assumed to be allowed by
* default if it is not explicitly disabled.
*/
static bool
check_recursion(const cfg_obj_t *config, const cfg_obj_t *voptions,
const cfg_obj_t *goptions, isc_log_t *logctx,
cfg_aclconfctx_t *actx, isc_mem_t *mctx)
{
dns_acl_t *acl = NULL;
const cfg_obj_t *obj;
isc_result_t result;
bool retval = true;
/*
* Check the "recursion" option first.
*/
obj = NULL;
result = ISC_R_NOTFOUND;
if (voptions != NULL) {
result = cfg_map_get(voptions, "recursion", &obj);
}
if (result != ISC_R_SUCCESS && goptions != NULL) {
result = cfg_map_get(goptions, "recursion", &obj);
}
if (result == ISC_R_SUCCESS && !cfg_obj_asboolean(obj)) {
retval = false;
goto cleanup;
}
/*
* If recursion is not disabled by the "recursion" option, check
* whether it is disabled by the "allow-recursion" ACL.
*/
obj = NULL;
result = ISC_R_NOTFOUND;
if (voptions != NULL) {
result = cfg_map_get(voptions, "allow-recursion", &obj);
}
if (result != ISC_R_SUCCESS && goptions != NULL) {
result = cfg_map_get(goptions, "allow-recursion", &obj);
}
if (result == ISC_R_SUCCESS) {
result = cfg_acl_fromconfig(obj, config, logctx, actx, mctx, 0,
&acl);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
retval = !dns_acl_isnone(acl);
}
cleanup:
if (acl != NULL) {
dns_acl_detach(&acl);
}
return (retval);
}
static isc_result_t
check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
const cfg_obj_t *config, isc_symtab_t *symtab,
@ -1989,6 +2097,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
strcasecmp(typestr, "secondary") == 0)
{
ztype = CFG_ZONE_SLAVE;
} else if (strcasecmp(typestr, "mirror") == 0) {
ztype = CFG_ZONE_MIRROR;
} else if (strcasecmp(typestr, "stub") == 0) {
ztype = CFG_ZONE_STUB;
} else if (strcasecmp(typestr, "static-stub") == 0) {
@ -2100,6 +2210,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
case CFG_ZONE_MASTER:
case CFG_ZONE_SLAVE:
case CFG_ZONE_MIRROR:
case CFG_ZONE_HINT:
case CFG_ZONE_STUB:
case CFG_ZONE_STATICSTUB:
@ -2184,10 +2295,22 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
}
/*
* Master & slave zones may have an "also-notify" field, but
* Only a limited subset of all possible "notify" settings can be used
* at the zone level for mirror zones.
*/
if (ztype == CFG_ZONE_MIRROR &&
!check_mirror_zone_notify(zoptions, znamestr, logctx))
{
result = ISC_R_FAILURE;
}
/*
* Master, slave, and mirror zones may have an "also-notify" field, but
* shouldn't if notify is disabled.
*/
if (ztype == CFG_ZONE_MASTER || ztype == CFG_ZONE_SLAVE) {
if (ztype == CFG_ZONE_MASTER || ztype == CFG_ZONE_SLAVE ||
ztype == CFG_ZONE_MIRROR)
{
bool donotify = true;
obj = NULL;
@ -2228,9 +2351,13 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
}
/*
* Slave & stub zones must have a "masters" field.
* Slave, mirror, and stub zones must have a "masters" field, with one
* exception: when mirroring the root zone, a default, built-in master
* server list is used in the absence of one explicitly specified.
*/
if (ztype == CFG_ZONE_SLAVE || ztype == CFG_ZONE_STUB) {
if (ztype == CFG_ZONE_SLAVE || ztype == CFG_ZONE_STUB ||
(ztype == CFG_ZONE_MIRROR && !dns_name_equal(zname, dns_rootname)))
{
obj = NULL;
if (cfg_map_get(zoptions, "masters", &obj) != ISC_R_SUCCESS) {
cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR,
@ -2252,6 +2379,19 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
}
}
/*
* Configuring a mirror zone and disabling recursion at the same time
* contradicts the purpose of the former.
*/
if (ztype == CFG_ZONE_MIRROR &&
!check_recursion(config, voptions, goptions, logctx, actx, mctx))
{
cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR,
"zone '%s': mirror zones cannot be used if "
"recursion is disabled", znamestr);
result = ISC_R_FAILURE;
}
/*
* Master zones can't have both "allow-update" and "update-policy".
*/
@ -2621,7 +2761,9 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
znamestr);
result = tresult;
} else if (tresult == ISC_R_SUCCESS &&
(ztype == CFG_ZONE_SLAVE || ddns)) {
(ztype == CFG_ZONE_SLAVE ||
ztype == CFG_ZONE_MIRROR || ddns))
{
tresult = fileexist(fileobj, files, true, logctx);
if (tresult != ISC_R_SUCCESS)
result = tresult;

View file

@ -38,6 +38,7 @@ typedef enum {
dns_zone_none,
dns_zone_master,
dns_zone_slave,
dns_zone_mirror,
dns_zone_stub,
dns_zone_staticstub,
dns_zone_key,
@ -82,7 +83,6 @@ typedef enum {
DNS_ZONEOPT_CHECKSPF = 1<<27, /*%< check SPF records */
DNS_ZONEOPT_CHECKTTL = 1<<28, /*%< check max-zone-ttl */
DNS_ZONEOPT_AUTOEMPTY = 1<<29, /*%< automatic empty zone */
DNS_ZONEOPT_MIRROR = 1<<30, /*%< mirror zone */
} dns_zoneopt_t;
/*
@ -2485,12 +2485,6 @@ dns_zone_isloaded(const dns_zone_t *zone);
* false otherwise.
*/
bool
dns_zone_ismirror(const dns_zone_t *zone);
/*%<
* Return true if 'zone' is a mirror zone, return false otherwise.
*/
isc_result_t
dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver);
/*%<

View file

@ -1201,7 +1201,6 @@ dns_zone_idetach
dns_zone_isdynamic
dns_zone_isforced
dns_zone_isloaded
dns_zone_ismirror
dns_zone_keydone
dns_zone_link
dns_zone_load

View file

@ -1709,16 +1709,17 @@ dns_zone_getjournal(dns_zone_t *zone) {
* master file (if any) is written by the server, rather than being
* updated manually and read by the server.
*
* This is true for slave zones, stub zones, key zones, and zones that
* allow dynamic updates either by having an update policy ("ssutable")
* or an "allow-update" ACL with a value other than exactly "{ none; }".
* This is true for slave zones, mirror zones, stub zones, key zones,
* and zones that allow dynamic updates either by having an update
* policy ("ssutable") or an "allow-update" ACL with a value other than
* exactly "{ none; }".
*/
bool
dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze) {
REQUIRE(DNS_ZONE_VALID(zone));
if (zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
zone->type == dns_zone_key ||
if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
zone->type == dns_zone_stub || zone->type == dns_zone_key ||
(zone->type == dns_zone_redirect && zone->masters != NULL))
return (true);
@ -2072,7 +2073,8 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
goto cleanup;
}
if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub ||
if ((zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
zone->type == dns_zone_stub ||
(zone->type == dns_zone_redirect && zone->masters != NULL)) &&
rbt) {
if (zone->masterfile == NULL ||
@ -2108,7 +2110,9 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
}
dns_db_settask(db, zone->task);
if (zone->type == dns_zone_master || zone->type == dns_zone_slave) {
if (zone->type == dns_zone_master || zone->type == dns_zone_slave ||
zone->type == dns_zone_mirror)
{
result = dns_db_setgluecachestats(db, zone->gluecachestats);
if (result == ISC_R_NOTIMPLEMENTED) {
result = ISC_R_SUCCESS;
@ -2280,27 +2284,39 @@ get_master_options(dns_zone_t *zone) {
unsigned int options;
options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN;
if (zone->type == dns_zone_slave ||
if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
(zone->type == dns_zone_redirect && zone->masters == NULL))
{
options |= DNS_MASTER_SLAVE;
if (zone->type == dns_zone_key)
}
if (zone->type == dns_zone_key) {
options |= DNS_MASTER_KEY;
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
}
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) {
options |= DNS_MASTER_CHECKNS;
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
}
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) {
options |= DNS_MASTER_FATALNS;
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
}
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) {
options |= DNS_MASTER_CHECKNAMES;
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
}
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
options |= DNS_MASTER_CHECKNAMESFAIL;
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
}
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) {
options |= DNS_MASTER_CHECKMX;
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
}
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) {
options |= DNS_MASTER_CHECKMXFAIL;
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
}
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) {
options |= DNS_MASTER_CHECKWILDCARD;
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL))
}
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL)) {
options |= DNS_MASTER_CHECKTTL;
}
return (options);
}
@ -4433,6 +4449,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
*/
if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
if (zone->type == dns_zone_slave ||
zone->type == dns_zone_mirror ||
zone->type == dns_zone_stub ||
(zone->type == dns_zone_redirect &&
zone->masters == NULL)) {
@ -4592,14 +4609,15 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
"loaded; checking validity");
/*
* Master / Slave / Stub zones require both NS and SOA records at
* the top of the zone.
* Master / Slave / Mirror / Stub zones require both NS and SOA records
* at the top of the zone.
*/
switch (zone->type) {
case dns_zone_dlz:
case dns_zone_master:
case dns_zone_slave:
case dns_zone_mirror:
case dns_zone_stub:
case dns_zone_redirect:
if (soacount != 1) {
@ -4723,6 +4741,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
if (zone->type == dns_zone_slave ||
zone->type == dns_zone_mirror ||
zone->type == dns_zone_stub ||
(zone->type == dns_zone_redirect &&
zone->masters != NULL)) {
@ -4909,6 +4928,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
isc_mem_put(zone->mctx, inc, sizeof(*inc));
}
if (zone->type == dns_zone_slave ||
zone->type == dns_zone_mirror ||
zone->type == dns_zone_stub ||
zone->type == dns_zone_key ||
(zone->type == dns_zone_redirect && zone->masters != NULL)) {
@ -5063,7 +5083,9 @@ zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
while (result == ISC_R_SUCCESS) {
if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
(zone->type == dns_zone_master ||
zone->type == dns_zone_slave)) {
zone->type == dns_zone_slave ||
zone->type == dns_zone_mirror))
{
dns_rdata_init(&rdata);
dns_rdataset_current(&rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &ns, NULL);
@ -10043,6 +10065,7 @@ zone_maintenance(dns_zone_t *zone) {
break;
/* FALLTHROUGH */
case dns_zone_slave:
case dns_zone_mirror:
case dns_zone_stub:
LOCK_ZONE(zone);
if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
@ -10065,6 +10088,7 @@ zone_maintenance(dns_zone_t *zone) {
break;
/* FALLTHROUGH */
case dns_zone_slave:
case dns_zone_mirror:
case dns_zone_stub:
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
isc_time_compare(&now, &zone->refreshtime) >= 0)
@ -10077,7 +10101,7 @@ zone_maintenance(dns_zone_t *zone) {
/*
* Slaves send notifies before backing up to disk, masters after.
*/
if (zone->type == dns_zone_slave &&
if ((zone->type == dns_zone_slave || zone->type == dns_zone_mirror) &&
(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
isc_time_compare(&now, &zone->notifytime) >= 0)
@ -10089,6 +10113,7 @@ zone_maintenance(dns_zone_t *zone) {
switch (zone->type) {
case dns_zone_master:
case dns_zone_slave:
case dns_zone_mirror:
case dns_zone_key:
case dns_zone_redirect:
case dns_zone_stub:
@ -11950,8 +11975,10 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
master, source);
/* Try with slave with TCP. */
if ((zone->type == dns_zone_slave ||
zone->type == dns_zone_mirror ||
zone->type == dns_zone_redirect) &&
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH))
{
if (!dns_zonemgr_unreachable(zone->zmgr,
&zone->masteraddr,
&zone->sourceaddr,
@ -12026,8 +12053,11 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
*/
if (msg->rcode == dns_rcode_refused &&
(zone->type == dns_zone_slave ||
zone->type == dns_zone_mirror ||
zone->type == dns_zone_redirect))
{
goto tcp_transfer;
}
goto next_master;
}
@ -12036,7 +12066,9 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
*/
if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
if (zone->type == dns_zone_slave ||
zone->type == dns_zone_redirect) {
zone->type == dns_zone_mirror ||
zone->type == dns_zone_redirect)
{
dns_zone_log(zone, ISC_LOG_INFO,
"refresh: truncated UDP answer, "
"initiating TCP zone xfer "
@ -12164,6 +12196,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
"refresh: skipping %s as master %s "
"(source %s) is unreachable (cached)",
(zone->type == dns_zone_slave ||
zone->type == dns_zone_mirror ||
zone->type == dns_zone_redirect) ?
"zone transfer" : "NS query",
master, source);
@ -12173,7 +12206,9 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
dns_request_destroy(&zone->request);
if (zone->type == dns_zone_slave ||
zone->type == dns_zone_redirect) {
zone->type == dns_zone_mirror ||
zone->type == dns_zone_redirect)
{
do_queue_xfrin = true;
} else {
INSIST(zone->type == dns_zone_stub);
@ -13028,6 +13063,7 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) {
break;
case dns_zone_slave:
case dns_zone_mirror:
treat_as_slave:
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
@ -19410,13 +19446,6 @@ dns_zone_isloaded(const dns_zone_t *zone) {
return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED));
}
bool
dns_zone_ismirror(const dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
return (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MIRROR));
}
isc_result_t
dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) {
dns_dbversion_t *version = NULL;
@ -19430,7 +19459,7 @@ dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(db != NULL);
if (!dns_zone_ismirror(zone)) {
if (dns_zone_gettype(zone) != dns_zone_mirror) {
return (ISC_R_SUCCESS);
}

View file

@ -181,7 +181,8 @@ dns_zt_find(dns_zt_t *zt, const dns_name_t *name, unsigned int options,
* instead of returning a SERVFAIL.
*/
if ((options & DNS_ZTFIND_MIRROR) != 0 &&
dns_zone_ismirror(dummy) && !dns_zone_isloaded(dummy))
dns_zone_gettype(dummy) == dns_zone_mirror &&
!dns_zone_isloaded(dummy))
{
result = ISC_R_NOTFOUND;
} else {

View file

@ -72,6 +72,7 @@
#define CFG_ZONE_REDIRECT 0x02000000
#define CFG_ZONE_DELEGATION 0x01000000
#define CFG_ZONE_INVIEW 0x00800000
#define CFG_ZONE_MIRROR 0x00400000
typedef struct cfg_clausedef cfg_clausedef_t;
typedef struct cfg_tuplefielddef cfg_tuplefielddef_t;

View file

@ -668,7 +668,7 @@ static cfg_type_t cfg_type_forwardtype = {
};
static const char *zonetype_enums[] = {
"primary", "master", "secondary", "slave",
"primary", "master", "secondary", "slave", "mirror",
"delegation-only", "forward", "hint", "redirect",
"static-stub", "stub", NULL
};
@ -2020,33 +2020,33 @@ static cfg_type_t cfg_type_validityinterval = {
static cfg_clausedef_t
zone_clauses[] = {
{ "allow-notify", &cfg_type_bracketed_aml,
CFG_ZONE_SLAVE
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "allow-query", &cfg_type_bracketed_aml,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_STUB |
CFG_ZONE_REDIRECT | CFG_ZONE_STATICSTUB
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR |
CFG_ZONE_STUB | CFG_ZONE_REDIRECT | CFG_ZONE_STATICSTUB
},
{ "allow-query-on", &cfg_type_bracketed_aml,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_STUB |
CFG_ZONE_REDIRECT | CFG_ZONE_STATICSTUB
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR |
CFG_ZONE_STUB | CFG_ZONE_REDIRECT | CFG_ZONE_STATICSTUB
},
{ "allow-transfer", &cfg_type_bracketed_aml,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "allow-update", &cfg_type_bracketed_aml,
CFG_ZONE_MASTER
},
{ "allow-update-forwarding", &cfg_type_bracketed_aml,
CFG_ZONE_SLAVE
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "also-notify", &cfg_type_namesockaddrkeylist,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "alt-transfer-source", &cfg_type_sockaddr4wild,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "alt-transfer-source-v6", &cfg_type_sockaddr6wild,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "auto-dnssec", &cfg_type_autodnssec,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
@ -2108,67 +2108,64 @@ zone_clauses[] = {
CFG_CLAUSEFLAG_OBSOLETE
},
{ "masterfile-format", &cfg_type_masterformat,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE |
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR |
CFG_ZONE_STUB | CFG_ZONE_REDIRECT
},
{ "masterfile-style", &cfg_type_masterstyle,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE |
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR |
CFG_ZONE_STUB | CFG_ZONE_REDIRECT
},
{ "max-ixfr-log-size", &cfg_type_size,
CFG_CLAUSEFLAG_OBSOLETE
},
{ "max-journal-size", &cfg_type_size,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "max-records", &cfg_type_uint32,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_STUB |
CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR |
CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT
},
{ "max-refresh-time", &cfg_type_uint32,
CFG_ZONE_SLAVE | CFG_ZONE_STUB
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR | CFG_ZONE_STUB
},
{ "max-retry-time", &cfg_type_uint32,
CFG_ZONE_SLAVE | CFG_ZONE_STUB
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR | CFG_ZONE_STUB
},
{ "max-transfer-idle-in", &cfg_type_uint32,
CFG_ZONE_SLAVE | CFG_ZONE_STUB
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR | CFG_ZONE_STUB
},
{ "max-transfer-idle-out", &cfg_type_uint32,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_MIRROR | CFG_ZONE_SLAVE
},
{ "max-transfer-time-in", &cfg_type_uint32,
CFG_ZONE_SLAVE | CFG_ZONE_STUB
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR | CFG_ZONE_STUB
},
{ "max-transfer-time-out", &cfg_type_uint32,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_MIRROR | CFG_ZONE_SLAVE
},
{ "max-zone-ttl", &cfg_type_maxttl,
CFG_ZONE_MASTER | CFG_ZONE_REDIRECT
},
{ "min-refresh-time", &cfg_type_uint32,
CFG_ZONE_SLAVE | CFG_ZONE_STUB
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR | CFG_ZONE_STUB
},
{ "min-retry-time", &cfg_type_uint32,
CFG_ZONE_SLAVE | CFG_ZONE_STUB
},
{ "mirror", &cfg_type_boolean,
CFG_ZONE_SLAVE
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR | CFG_ZONE_STUB
},
{ "multi-master", &cfg_type_boolean,
CFG_ZONE_SLAVE | CFG_ZONE_STUB
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR | CFG_ZONE_STUB
},
{ "notify", &cfg_type_notifytype,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "notify-delay", &cfg_type_uint32,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "notify-source", &cfg_type_sockaddr4wild,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "notify-source-v6", &cfg_type_sockaddr6wild,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "notify-to-soa", &cfg_type_boolean,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
@ -2178,10 +2175,10 @@ zone_clauses[] = {
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
},
{ "request-expire", &cfg_type_boolean,
CFG_ZONE_SLAVE
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "request-ixfr", &cfg_type_boolean,
CFG_ZONE_SLAVE
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "serial-update-method", &cfg_type_updatemethod,
CFG_ZONE_MASTER
@ -2202,26 +2199,26 @@ zone_clauses[] = {
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
},
{ "transfer-source", &cfg_type_sockaddr4wild,
CFG_ZONE_SLAVE | CFG_ZONE_STUB
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR | CFG_ZONE_STUB
},
{ "transfer-source-v6", &cfg_type_sockaddr6wild,
CFG_ZONE_SLAVE | CFG_ZONE_STUB
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR | CFG_ZONE_STUB
},
{ "try-tcp-refresh", &cfg_type_boolean,
CFG_ZONE_SLAVE
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "update-check-ksk", &cfg_type_boolean,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
},
{ "use-alt-transfer-source", &cfg_type_boolean,
CFG_ZONE_SLAVE | CFG_ZONE_STUB
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR | CFG_ZONE_STUB
},
{ "zero-no-soa-ttl", &cfg_type_boolean,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "zone-statistics", &cfg_type_zonestat,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_STUB |
CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR |
CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT
},
{ NULL, NULL, 0 }
};
@ -2239,16 +2236,17 @@ zone_only_clauses[] = {
* the zone options and the global/view options. Ugh.
*/
{ "type", &cfg_type_zonetype,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_STUB |
CFG_ZONE_STATICSTUB | CFG_ZONE_DELEGATION | CFG_ZONE_HINT |
CFG_ZONE_REDIRECT | CFG_ZONE_FORWARD
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR |
CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_DELEGATION |
CFG_ZONE_HINT | CFG_ZONE_REDIRECT | CFG_ZONE_FORWARD
},
{ "check-names", &cfg_type_checkmode,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE |
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR |
CFG_ZONE_HINT | CFG_ZONE_STUB
},
{ "database", &cfg_type_astring,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_STUB
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR |
CFG_ZONE_STUB
},
{ "delegation-only", &cfg_type_boolean,
CFG_ZONE_HINT | CFG_ZONE_STUB | CFG_ZONE_FORWARD
@ -2257,8 +2255,8 @@ zone_only_clauses[] = {
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_REDIRECT
},
{ "file", &cfg_type_qstring,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_STUB |
CFG_ZONE_HINT | CFG_ZONE_REDIRECT
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR |
CFG_ZONE_STUB | CFG_ZONE_HINT | CFG_ZONE_REDIRECT
},
{ "in-view", &cfg_type_astring,
CFG_ZONE_INVIEW
@ -2267,16 +2265,17 @@ zone_only_clauses[] = {
CFG_CLAUSEFLAG_OBSOLETE
},
{ "ixfr-from-differences", &cfg_type_boolean,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "ixfr-tmp-file", &cfg_type_qstring,
CFG_CLAUSEFLAG_OBSOLETE
},
{ "journal", &cfg_type_qstring,
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR
},
{ "masters", &cfg_type_namesockaddrkeylist,
CFG_ZONE_SLAVE | CFG_ZONE_STUB | CFG_ZONE_REDIRECT
CFG_ZONE_SLAVE | CFG_ZONE_MIRROR | CFG_ZONE_STUB |
CFG_ZONE_REDIRECT
},
{ "pubkey", &cfg_type_pubkey,
CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_OBSOLETE
@ -4121,6 +4120,10 @@ cfg_print_zonegrammar(const unsigned int zonetype,
cfg_print_indent(&pctx);
cfg_print_cstr(&pctx, "type ( slave | secondary );\n");
break;
case CFG_ZONE_MIRROR:
cfg_print_indent(&pctx);
cfg_print_cstr(&pctx, "type mirror;\n");
break;
case CFG_ZONE_STUB:
cfg_print_indent(&pctx);
cfg_print_cstr(&pctx, "type stub;\n");

View file

@ -141,6 +141,7 @@ ns_notify_start(ns_client_t *client) {
if ((zonetype == dns_zone_master) ||
(zonetype == dns_zone_slave) ||
(zonetype == dns_zone_mirror) ||
(zonetype == dns_zone_stub))
{
isc_sockaddr_t *from = ns_client_getsockaddr(client);

View file

@ -1095,7 +1095,7 @@ query_validatezonedb(ns_client_t *client, const dns_name_t *name,
/*
* Mirror zone data is treated as cache data.
*/
if (dns_zone_ismirror(zone)) {
if (dns_zone_gettype(zone) == dns_zone_mirror) {
return (query_checkcacheaccess(client, name, qtype, options));
}
@ -5382,7 +5382,7 @@ ns__query_start(query_ctx_t *qctx) {
if (qctx->is_zone) {
qctx->authoritative = true;
if (qctx->zone != NULL) {
if (dns_zone_ismirror(qctx->zone)) {
if (dns_zone_gettype(qctx->zone) == dns_zone_mirror) {
qctx->authoritative = false;
}
if (dns_zone_gettype(qctx->zone) ==
@ -7099,8 +7099,8 @@ query_respond_any(query_ctx_t *qctx) {
}
/*
* Set the expire time, if requested, when answering from a
* slave or master zone.
* Set the expire time, if requested, when answering from a slave, mirror, or
* master zone.
*/
static void
query_getexpire(query_ctx_t *qctx) {
@ -7117,7 +7117,9 @@ query_getexpire(query_ctx_t *qctx) {
dns_zone_getraw(qctx->zone, &raw);
mayberaw = (raw != NULL) ? raw : qctx->zone;
if (dns_zone_gettype(mayberaw) == dns_zone_slave) {
if (dns_zone_gettype(mayberaw) == dns_zone_slave ||
dns_zone_gettype(mayberaw) == dns_zone_mirror)
{
isc_time_t expiretime;
uint32_t secs;
dns_zone_getexpiretime(qctx->zone, &expiretime);
@ -7918,7 +7920,8 @@ query_zone_delegation(query_ctx_t *qctx) {
if (USECACHE(qctx->client) &&
(RECURSIONOK(qctx->client) ||
(qctx->zone != NULL && dns_zone_ismirror(qctx->zone))))
(qctx->zone != NULL &&
dns_zone_gettype(qctx->zone) == dns_zone_mirror)))
{
/*
* We might have a better answer or delegation in the

View file

@ -1637,6 +1637,7 @@ ns_update_start(ns_client_t *client, isc_result_t sigresult) {
CHECK(send_update_event(client, zone));
break;
case dns_zone_slave:
case dns_zone_mirror:
CHECK(checkupdateacl(client, dns_zone_getforwardacl(zone),
"update forwarding", zonename, true,
false));
@ -1649,7 +1650,8 @@ ns_update_start(ns_client_t *client, isc_result_t sigresult) {
failure:
if (result == DNS_R_REFUSED) {
INSIST(dns_zone_gettype(zone) == dns_zone_slave);
INSIST(dns_zone_gettype(zone) == dns_zone_slave ||
dns_zone_gettype(zone) == dns_zone_mirror);
inc_stats(client, zone, ns_statscounter_updaterej);
}
/*

View file

@ -848,9 +848,12 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
} else {
/* zone table has a match */
switch(dns_zone_gettype(zone)) {
/* Master and slave zones are OK for transfer. */
/*
* Master, slave, and mirror zones are OK for transfer.
*/
case dns_zone_master:
case dns_zone_slave:
case dns_zone_mirror:
case dns_zone_dlz:
break;
default:
@ -1087,7 +1090,9 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
dns_zone_getraw(zone, &raw);
mayberaw = (raw != NULL) ? raw : zone;
if ((client->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0 &&
dns_zone_gettype(mayberaw) == dns_zone_slave) {
(dns_zone_gettype(mayberaw) == dns_zone_slave ||
dns_zone_gettype(mayberaw) == dns_zone_mirror))
{
isc_time_t expiretime;
uint32_t secs;
dns_zone_getexpiretime(zone, &expiretime);

View file

@ -597,6 +597,10 @@
./bin/tests/system/checkconf/bad-maxcachettl.conf CONF-C 2018
./bin/tests/system/checkconf/bad-maxncachettl.conf CONF-C 2018
./bin/tests/system/checkconf/bad-maxttlmap.conf CONF-C 2014,2016,2018
./bin/tests/system/checkconf/bad-mirror-allow-recursion-none.conf CONF-C 2018
./bin/tests/system/checkconf/bad-mirror-explicit-notify-yes.conf CONF-C 2018
./bin/tests/system/checkconf/bad-mirror-non-root-zone-without-masters.conf CONF-C 2018
./bin/tests/system/checkconf/bad-mirror-recursion-no.conf CONF-C 2018
./bin/tests/system/checkconf/bad-noddns.conf CONF-C 2014,2016,2018
./bin/tests/system/checkconf/bad-options-also-notify.conf CONF-C 2016,2018
./bin/tests/system/checkconf/bad-printtime.conf CONF-C 2016,2018
@ -668,6 +672,8 @@
./bin/tests/system/checkconf/good-lmdb-mapsize-smallest.conf CONF-C 2017,2018
./bin/tests/system/checkconf/good-maxcachettl.conf CONF-C 2018
./bin/tests/system/checkconf/good-maxncachettl.conf CONF-C 2018
./bin/tests/system/checkconf/good-mirror-inherited-notify-yes.conf CONF-C 2018
./bin/tests/system/checkconf/good-mirror-root-zone-without-masters.conf CONF-C 2018
./bin/tests/system/checkconf/good-nested.conf CONF-C 2015,2016,2018
./bin/tests/system/checkconf/good-options-also-notify.conf CONF-C 2016,2018
./bin/tests/system/checkconf/good-printtime.conf CONF-C 2016,2018
@ -1537,6 +1543,7 @@
./bin/tests/system/metadata/parent.db ZONE 2009,2016,2018
./bin/tests/system/metadata/setup.sh SH 2009,2011,2012,2014,2016,2017,2018
./bin/tests/system/metadata/tests.sh SH 2009,2011,2012,2013,2014,2016,2017,2018
./bin/tests/system/mirror/README TXT.BRIEF 2018
./bin/tests/system/mirror/clean.sh SH 2018
./bin/tests/system/mirror/ns1/named.conf.in CONF-C 2018
./bin/tests/system/mirror/ns1/root.db.in ZONE 2018
@ -2675,6 +2682,7 @@
./doc/arm/managed-keys.xml SGML 2010,2014,2015,2016,2017,2018
./doc/arm/master.zoneopt.xml SGML 2018
./doc/arm/masters.grammar.xml SGML 2018
./doc/arm/mirror.zoneopt.xml SGML 2018
./doc/arm/notes-wrapper.xml SGML 2014,2015,2016,2018
./doc/arm/notes.conf X 2015,2018
./doc/arm/notes.html X 2014,2015,2016,2017,2018
@ -2741,6 +2749,7 @@
./doc/misc/master.zoneopt X 2018
./doc/misc/migration TXT.BRIEF 2000,2001,2003,2004,2007,2008,2016,2018
./doc/misc/migration-4to9 TXT.BRIEF 2001,2004,2016,2018
./doc/misc/mirror.zoneopt X 2018
./doc/misc/options X 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018
./doc/misc/redirect.zoneopt X 2018
./doc/misc/rfc-compliance TXT.BRIEF 2001,2004,2015,2016,2018