mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 06:55:30 +00:00
[master] rndc managed-keys destroy
4750. [func] "rndc managed-keys destroy" shuts down RFC 5011 key maintenance and deletes the managed-keys database. If followed by "rndc reconfig" or a server restart, key maintenance is reinitialized from scratch. This is primarily intended for testing. [RT #32456]
This commit is contained in:
6
CHANGES
6
CHANGES
@@ -1,3 +1,9 @@
|
|||||||
|
4750. [func] "rndc managed-keys destroy" shuts down RFC 5011 key
|
||||||
|
maintenance and deletes the managed-keys database.
|
||||||
|
If followed by "rndc reconfig" or a server restart,
|
||||||
|
key maintenance is reinitialized from scratch.
|
||||||
|
This is primarily intended for testing. [RT #32456]
|
||||||
|
|
||||||
4749. [func] The ISC DLV service has been shut down, and all
|
4749. [func] The ISC DLV service has been shut down, and all
|
||||||
DLV records have been removed from dlv.isc.org.
|
DLV records have been removed from dlv.isc.org.
|
||||||
- Removed references to ISC DLV in documentation
|
- Removed references to ISC DLV in documentation
|
||||||
|
@@ -6042,18 +6042,22 @@ add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx) {
|
|||||||
|
|
||||||
/* See if we can re-use an existing keydata zone. */
|
/* See if we can re-use an existing keydata zone. */
|
||||||
result = dns_viewlist_find(&named_g_server->viewlist,
|
result = dns_viewlist_find(&named_g_server->viewlist,
|
||||||
view->name, view->rdclass,
|
view->name, view->rdclass, &pview);
|
||||||
&pview);
|
if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) {
|
||||||
if (result != ISC_R_NOTFOUND &&
|
|
||||||
result != ISC_R_SUCCESS)
|
|
||||||
return (result);
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pview != NULL) {
|
||||||
|
if (pview->managed_keys != NULL) {
|
||||||
|
dns_zone_synckeyzone(pview->managed_keys);
|
||||||
|
dns_zone_attach(pview->managed_keys,
|
||||||
|
&view->managed_keys);
|
||||||
|
dns_zone_setview(pview->managed_keys, view);
|
||||||
|
dns_view_detach(&pview);
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
if (pview != NULL && pview->managed_keys != NULL) {
|
|
||||||
dns_zone_attach(pview->managed_keys, &view->managed_keys);
|
|
||||||
dns_zone_setview(pview->managed_keys, view);
|
|
||||||
dns_view_detach(&pview);
|
dns_view_detach(&pview);
|
||||||
dns_zone_synckeyzone(view->managed_keys);
|
|
||||||
return (ISC_R_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No existing keydata zone was found; create one */
|
/* No existing keydata zone was found; create one */
|
||||||
@@ -6086,8 +6090,9 @@ add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx) {
|
|||||||
dns_zone_setstats(zone, named_g_server->zonestats);
|
dns_zone_setstats(zone, named_g_server->zonestats);
|
||||||
CHECK(setquerystats(zone, mctx, dns_zonestat_none));
|
CHECK(setquerystats(zone, mctx, dns_zonestat_none));
|
||||||
|
|
||||||
if (view->managed_keys != NULL)
|
if (view->managed_keys != NULL) {
|
||||||
dns_zone_detach(&view->managed_keys);
|
dns_zone_detach(&view->managed_keys);
|
||||||
|
}
|
||||||
dns_zone_attach(zone, &view->managed_keys);
|
dns_zone_attach(zone, &view->managed_keys);
|
||||||
|
|
||||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||||
@@ -6096,10 +6101,12 @@ add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx) {
|
|||||||
view->name, filename);
|
view->name, filename);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (zone != NULL)
|
if (zone != NULL) {
|
||||||
dns_zone_detach(&zone);
|
dns_zone_detach(&zone);
|
||||||
if (none != NULL)
|
}
|
||||||
|
if (none != NULL) {
|
||||||
dns_acl_detach(&none);
|
dns_acl_detach(&none);
|
||||||
|
}
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
@@ -8916,8 +8923,7 @@ run_server(isc_task_t *task, isc_event_t *event) {
|
|||||||
&named_g_addparser),
|
&named_g_addparser),
|
||||||
"creating additional configuration parser");
|
"creating additional configuration parser");
|
||||||
|
|
||||||
CHECKFATAL(load_configuration(named_g_conffile, server,
|
CHECKFATAL(load_configuration(named_g_conffile, server, ISC_TRUE),
|
||||||
ISC_TRUE),
|
|
||||||
"loading configuration");
|
"loading configuration");
|
||||||
|
|
||||||
isc_hash_init();
|
isc_hash_init();
|
||||||
@@ -14067,6 +14073,78 @@ mkey_refresh(dns_view_t *view, isc_buffer_t **text) {
|
|||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
mkey_destroy(named_server_t *server, dns_view_t *view, isc_buffer_t **text) {
|
||||||
|
isc_result_t result;
|
||||||
|
char msg[DNS_NAME_FORMATSIZE + 500] = "";
|
||||||
|
isc_boolean_t exclusive = ISC_FALSE;
|
||||||
|
const char *file = NULL;
|
||||||
|
dns_db_t *dbp = NULL;
|
||||||
|
dns_zone_t *mkzone = NULL;
|
||||||
|
isc_boolean_t removed = ISC_FALSE;
|
||||||
|
|
||||||
|
if (view->managed_keys == NULL) {
|
||||||
|
CHECK(ISC_R_NOTFOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(msg, sizeof(msg),
|
||||||
|
"destroying managed-keys database for '%s'", view->name);
|
||||||
|
CHECK(putstr(text, msg));
|
||||||
|
|
||||||
|
result = isc_task_beginexclusive(server->task);
|
||||||
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||||
|
exclusive = ISC_TRUE;
|
||||||
|
|
||||||
|
/* Remove and clean up managed keys zone from view */
|
||||||
|
mkzone = view->managed_keys;
|
||||||
|
view->managed_keys = NULL;
|
||||||
|
(void)dns_zone_flush(mkzone);
|
||||||
|
|
||||||
|
/* Unload zone database */
|
||||||
|
if (dns_zone_getdb(mkzone, &dbp) == ISC_R_SUCCESS) {
|
||||||
|
dns_db_detach(&dbp);
|
||||||
|
dns_zone_unload(mkzone);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete files */
|
||||||
|
file = dns_zone_getfile(mkzone);
|
||||||
|
result = isc_file_remove(file);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
removed = ISC_TRUE;
|
||||||
|
} else {
|
||||||
|
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||||
|
NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
|
||||||
|
"file %s not removed: %s",
|
||||||
|
file, isc_result_totext(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
file = dns_zone_getjournal(mkzone);
|
||||||
|
result = isc_file_remove(file);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
removed = ISC_TRUE;
|
||||||
|
} else {
|
||||||
|
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||||
|
NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
|
||||||
|
"file %s not removed: %s",
|
||||||
|
file, isc_result_totext(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!removed) {
|
||||||
|
CHECK(putstr(text, "error: no files could be removed"));
|
||||||
|
CHECK(ISC_R_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_zone_detach(&mkzone);
|
||||||
|
result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (exclusive) {
|
||||||
|
isc_task_endexclusive(server->task);
|
||||||
|
}
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
mkey_dumpzone(dns_view_t *view, isc_buffer_t **text) {
|
mkey_dumpzone(dns_view_t *view, isc_buffer_t **text) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
@@ -14220,27 +14298,31 @@ named_server_mkeys(named_server_t *server, isc_lex_t *lex,
|
|||||||
dns_view_t *view = NULL;
|
dns_view_t *view = NULL;
|
||||||
dns_rdataclass_t rdclass;
|
dns_rdataclass_t rdclass;
|
||||||
char msg[DNS_NAME_FORMATSIZE + 500] = "";
|
char msg[DNS_NAME_FORMATSIZE + 500] = "";
|
||||||
enum { NONE, STATUS, REFRESH, SYNC } opt = NONE;
|
enum { NONE, STATUS, REFRESH, SYNC, DESTROY } opt = NONE;
|
||||||
isc_boolean_t found = ISC_FALSE;
|
isc_boolean_t found = ISC_FALSE;
|
||||||
isc_boolean_t first = ISC_TRUE;
|
isc_boolean_t first = ISC_TRUE;
|
||||||
|
|
||||||
/* Skip rndc command name */
|
/* Skip rndc command name */
|
||||||
cmd = next_token(lex, text);
|
cmd = next_token(lex, text);
|
||||||
if (cmd == NULL)
|
if (cmd == NULL) {
|
||||||
return (ISC_R_UNEXPECTEDEND);
|
return (ISC_R_UNEXPECTEDEND);
|
||||||
|
}
|
||||||
|
|
||||||
/* Get managed-keys subcommand */
|
/* Get managed-keys subcommand */
|
||||||
cmd = next_token(lex, text);
|
cmd = next_token(lex, text);
|
||||||
if (cmd == NULL)
|
if (cmd == NULL) {
|
||||||
return (ISC_R_UNEXPECTEDEND);
|
return (ISC_R_UNEXPECTEDEND);
|
||||||
|
}
|
||||||
|
|
||||||
if (strcasecmp(cmd, "status") == 0)
|
if (strcasecmp(cmd, "status") == 0) {
|
||||||
opt = STATUS;
|
opt = STATUS;
|
||||||
else if (strcasecmp(cmd, "refresh") == 0)
|
} else if (strcasecmp(cmd, "refresh") == 0) {
|
||||||
opt = REFRESH;
|
opt = REFRESH;
|
||||||
else if (strcasecmp(cmd, "sync") == 0)
|
} else if (strcasecmp(cmd, "sync") == 0) {
|
||||||
opt = SYNC;
|
opt = SYNC;
|
||||||
else {
|
} else if (strcasecmp(cmd, "destroy") == 0) {
|
||||||
|
opt = DESTROY;
|
||||||
|
} else {
|
||||||
snprintf(msg, sizeof(msg), "unknown command '%s'", cmd);
|
snprintf(msg, sizeof(msg), "unknown command '%s'", cmd);
|
||||||
(void) putstr(text, msg);
|
(void) putstr(text, msg);
|
||||||
result = ISC_R_UNEXPECTED;
|
result = ISC_R_UNEXPECTED;
|
||||||
@@ -14282,7 +14364,9 @@ named_server_mkeys(named_server_t *server, isc_lex_t *lex,
|
|||||||
if (viewtxt != NULL &&
|
if (viewtxt != NULL &&
|
||||||
(rdclass != view->rdclass ||
|
(rdclass != view->rdclass ||
|
||||||
strcmp(view->name, viewtxt) != 0))
|
strcmp(view->name, viewtxt) != 0))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (view->managed_keys == NULL) {
|
if (view->managed_keys == NULL) {
|
||||||
if (viewtxt != NULL) {
|
if (viewtxt != NULL) {
|
||||||
@@ -14290,8 +14374,9 @@ named_server_mkeys(named_server_t *server, isc_lex_t *lex,
|
|||||||
"view '%s': no managed keys", viewtxt);
|
"view '%s': no managed keys", viewtxt);
|
||||||
CHECK(putstr(text, msg));
|
CHECK(putstr(text, msg));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else
|
} else {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
found = ISC_TRUE;
|
found = ISC_TRUE;
|
||||||
@@ -14301,28 +14386,35 @@ named_server_mkeys(named_server_t *server, isc_lex_t *lex,
|
|||||||
CHECK(mkey_refresh(view, text));
|
CHECK(mkey_refresh(view, text));
|
||||||
break;
|
break;
|
||||||
case STATUS:
|
case STATUS:
|
||||||
if (!first)
|
if (!first) {
|
||||||
CHECK(putstr(text, "\n\n"));
|
CHECK(putstr(text, "\n\n"));
|
||||||
|
}
|
||||||
CHECK(mkey_status(view, text));
|
CHECK(mkey_status(view, text));
|
||||||
first = ISC_FALSE;
|
first = ISC_FALSE;
|
||||||
break;
|
break;
|
||||||
case SYNC:
|
case SYNC:
|
||||||
CHECK(dns_zone_flush(view->managed_keys));
|
CHECK(dns_zone_flush(view->managed_keys));
|
||||||
break;
|
break;
|
||||||
|
case DESTROY:
|
||||||
|
CHECK(mkey_destroy(server, view, text));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
INSIST(0);
|
INSIST(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewtxt != NULL)
|
if (viewtxt != NULL) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (!found) {
|
||||||
CHECK(putstr(text, "no views with managed keys"));
|
CHECK(putstr(text, "no views with managed keys"));
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (isc_buffer_usedlength(*text) > 0)
|
if (isc_buffer_usedlength(*text) > 0) {
|
||||||
(void) putnull(text);
|
(void) putnull(text);
|
||||||
|
}
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
@@ -450,18 +450,68 @@
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><userinput>managed-keys <replaceable>(status | refresh | sync)</replaceable> <optional><replaceable>class</replaceable> <optional><replaceable>view</replaceable></optional></optional></userinput></term>
|
<term><userinput>managed-keys <replaceable>(status | refresh | sync | destroy)</replaceable> <optional><replaceable>class</replaceable> <optional><replaceable>view</replaceable></optional></optional></userinput></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
When run with the "status" keyword, print the current
|
Inspect and control the "managed-keys" database which
|
||||||
status of the managed-keys database for the specified
|
handles RFC 5011 DNSSEC trust anchor maintenance. If a view
|
||||||
view, or for all views if none is specified. When run
|
is specified, these commands are applied to that view;
|
||||||
with the "refresh" keyword, force an immediate refresh
|
otherwise they are applied to all views.
|
||||||
of all the managed-keys in the specified view, or all
|
</para>
|
||||||
views. When run with the "sync" keyword, force an
|
<itemizedlist>
|
||||||
immediate dump of the managed-keys database to disk (in
|
<listitem>
|
||||||
the file <filename>managed-keys.bind</filename> or
|
<para>
|
||||||
(<filename><replaceable>viewname</replaceable>.mkeys</filename>).
|
When run with the <literal>status</literal> keyword, prints
|
||||||
|
the current status of the managed-keys database.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
When run with the <literal>refresh</literal> keyword,
|
||||||
|
forces an immediate refresh query to be sent for all
|
||||||
|
the managed keys, updating the managed-keys database
|
||||||
|
if any new keys are found, without waiting the normal
|
||||||
|
refresh interval.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
When run with the <literal>sync</literal> keyword, forces an
|
||||||
|
immediate dump of the managed-keys database to disk
|
||||||
|
(in the file <filename>managed-keys.bind</filename> or
|
||||||
|
(<filename><replaceable>viewname</replaceable>.mkeys</filename>).
|
||||||
|
This synchronizes the database with its journal file, so
|
||||||
|
that the database's current contents can be inspected
|
||||||
|
visually.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
When run with the <literal>destroy</literal> keyword, the
|
||||||
|
managed-keys database is shut down and deleted, and all key
|
||||||
|
maintenance is terminated. This command should be used only
|
||||||
|
with extreme caution.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Existing keys that are already trusted are not deleted
|
||||||
|
from memory; DNSSEC validation can continue after this
|
||||||
|
command is used. However, key maintenance operations will
|
||||||
|
cease until <command>named</command> is restarted or
|
||||||
|
reconfigured, and all existing key maintenance state
|
||||||
|
will be deleted.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Running <command>rndc reconfig>/command> or restarting
|
||||||
|
<command>named</command> immediately after this command
|
||||||
|
will cause key maintenance to be reinitialized from scratch,
|
||||||
|
just as if the server were being started for the first time.
|
||||||
|
This is primarily intended for testing, but it may also be
|
||||||
|
used, for example, to jumpstart the acquisition of new keys
|
||||||
|
in the event of a trust anchor rollover, or as a
|
||||||
|
brute-force repair for key maintenance problems.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@@ -548,5 +548,19 @@ grep "query '_ta-[0-9a-f]*/NULL/IN' approved" ns1/named.run > /dev/null || ret=1
|
|||||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
status=`expr $status + $ret`
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
|
n=`expr $n + 1`
|
||||||
|
echo "I: check 'rndc-managed-keys destroy' ($n)"
|
||||||
|
ret=0
|
||||||
|
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys destroy | sed 's/^/I: ns2 /'
|
||||||
|
sleep 1
|
||||||
|
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys status > rndc.out.$n 2>&1
|
||||||
|
grep "no views with managed keys" rndc.out.$n > /dev/null || ret=1
|
||||||
|
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reconfig | sed 's/^/I: ns2 /'
|
||||||
|
sleep 1
|
||||||
|
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 managed-keys status > rndc.out.$n 2>&1
|
||||||
|
grep "name: \." rndc.out.$n > /dev/null || ret=1
|
||||||
|
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||||
|
status=`expr $status + $ret`
|
||||||
|
|
||||||
echo "I:exit status: $status"
|
echo "I:exit status: $status"
|
||||||
[ $status -eq 0 ] || exit 1
|
[ $status -eq 0 ] || exit 1
|
||||||
|
@@ -395,6 +395,23 @@
|
|||||||
entropy source. [RT #31459] [RT #46047]
|
entropy source. [RT #31459] [RT #46047]
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<command>rndc managed-keys destroy</command> shuts down all
|
||||||
|
RFC 5011 DNSSEC trust anchor maintenance, and deletes any
|
||||||
|
existing managed keys database. If immediately followed by
|
||||||
|
<command>rndc reconfig</command>, this will reinitialize
|
||||||
|
key maintenance just as if the server was being started for
|
||||||
|
the first time.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
This is intended for testing purposes, but can be used -- with
|
||||||
|
extreme caution -- as a brute-force repair for unrecoverable
|
||||||
|
problems with a managed keys database, to jumpstart the key
|
||||||
|
acquisition process if <filename>bind.keys</filename> is updated,
|
||||||
|
etc. [RT #32456]
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user