mirror of
https://github.com/isc-projects/bind9.git
synced 2026-03-14 22:53:34 -04:00
Merge branch '1134-dnssec-made-easy' into 'master'
DNSSEC Made Easy Closes #1134 See merge request isc-projects/bind9!2458
This commit is contained in:
commit
e7a9f52f50
96 changed files with 12292 additions and 1303 deletions
|
|
@ -421,7 +421,7 @@ configure_zone(const char *vclass, const char *view,
|
|||
|
||||
obj = NULL;
|
||||
if (get_maps(maps, "max-zone-ttl", &obj)) {
|
||||
maxttl = cfg_obj_asuint32(obj);
|
||||
maxttl = cfg_obj_asduration(obj);
|
||||
zone_options |= DNS_ZONEOPT_CHECKTTL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,24 +15,26 @@ VERSION=@BIND9_VERSION@
|
|||
|
||||
@BIND9_MAKE_INCLUDES@
|
||||
|
||||
CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} \
|
||||
CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES} \
|
||||
${OPENSSL_CFLAGS}
|
||||
|
||||
CDEFINES = -DVERSION=\"${VERSION}\"
|
||||
CDEFINES = -DVERSION=\"${VERSION}\" -DNAMED_CONFFILE=\"${sysconfdir}/named.conf\"
|
||||
CWARNINGS =
|
||||
|
||||
DNSLIBS = ../../lib/dns/libdns.@A@ ${MAXMINDDB_LIBS} @DNS_CRYPTO_LIBS@
|
||||
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
|
||||
ISCLIBS = ../../lib/isc/libisc.@A@ ${OPENSSL_LIBS} ${JSON_C_LIBS} ${LIBXML2_LIBS}
|
||||
ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@ ${OPENSSL_LIBS} ${JSON_C_LIBS} ${LIBXML2_LIBS}
|
||||
|
||||
DNSDEPLIBS = ../../lib/dns/libdns.@A@
|
||||
ISCDEPLIBS = ../../lib/isc/libisc.@A@
|
||||
ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
|
||||
|
||||
DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS}
|
||||
DEPLIBS = ${DNSDEPLIBS} ${ISCCFGDEPLIBS} ${ISCDEPLIBS}
|
||||
|
||||
LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@
|
||||
LIBS = ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@
|
||||
|
||||
NOSYMLIBS = ${DNSLIBS} ${ISCNOSYMLIBS} @LIBS@
|
||||
NOSYMLIBS = ${DNSLIBS} ${ISCCFGLIBS} ${ISCNOSYMLIBS} @LIBS@
|
||||
|
||||
# Alphabetically
|
||||
TARGETS = dnssec-cds@EXEEXT@ dnssec-dsfromkey@EXEEXT@ \
|
||||
|
|
@ -48,7 +50,7 @@ SRCS = dnssec-cds.c dnssec-dsfromkey.c dnssec-importkey.c \
|
|||
dnssec-settime.c dnssec-signzone.c dnssec-verify.c \
|
||||
dnssectool.c
|
||||
|
||||
MANPAGES = dnssec-cds.8 dnssec-dsfromkey.8 dnssec-importkey.8 \
|
||||
MANPAGES = dnssec-cds.8 dnssec-dsfromkey.8 dnssec-importkey.8 \
|
||||
dnssec-keyfromlabel.8 dnssec-keygen.8 dnssec-revoke.8 \
|
||||
dnssec-settime.8 dnssec-signzone.8 dnssec-verify.8
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -66,6 +66,7 @@
|
|||
<arg choice="opt" rep="norepeat"><option>-c <replaceable class="parameter">class</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-D sync <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-d <replaceable class="parameter">bits</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-f <replaceable class="parameter">flag</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-G</option></arg>
|
||||
|
|
@ -74,8 +75,9 @@
|
|||
<arg choice="opt" rep="norepeat"><option>-I <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-i <replaceable class="parameter">interval</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-k</option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-k <replaceable class="parameter">policy</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-L <replaceable class="parameter">ttl</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-l <replaceable class="parameter">file</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-n <replaceable class="parameter">nametype</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-P sync <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||
|
|
@ -84,6 +86,7 @@
|
|||
<arg choice="opt" rep="norepeat"><option>-R <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-S <replaceable class="parameter">key</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-s <replaceable class="parameter">strength</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-T <replaceable class="parameter">rrtype</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-t <replaceable class="parameter">type</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-V</option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-v <replaceable class="parameter">level</replaceable></option></arg>
|
||||
|
|
@ -207,6 +210,18 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-d <replaceable class="parameter">bits</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Key size in bits. For the algorithms RSASHA1, NSEC3RSASA1,
|
||||
RSASHA256 and RSASHA512 the key size must be in range 1024-4096.
|
||||
DH size is between 128 and 4096. This option is ignored for
|
||||
algorithms ECDSAP256SHA256, ECDSAP384SHA384, ED25519 and ED448.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-E <replaceable class="parameter">engine</replaceable></term>
|
||||
<listitem>
|
||||
|
|
@ -275,6 +290,24 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-k <replaceable class="parameter">policy</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Create keys for a specific dnssec-policy. If a policy uses
|
||||
multiple keys, <command>dnssec-keygen</command> will generate
|
||||
multiple keys. This will also create a ".state" file to keep
|
||||
track of the key state.
|
||||
</para>
|
||||
<para>
|
||||
This option creates keys according to the dnssec-policy
|
||||
configuration, hence it cannot be used together with many of
|
||||
the other options that <command>dnssec-keygen</command>
|
||||
provides.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-L <replaceable class="parameter">ttl</replaceable></term>
|
||||
<listitem>
|
||||
|
|
@ -291,6 +324,16 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-l <replaceable class="parameter">file</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Provide a configuration file that contains a dnssec-policy
|
||||
statement (matching the policy set with <command>-k</command>).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-n <replaceable class="parameter">nametype</replaceable></term>
|
||||
<listitem>
|
||||
|
|
|
|||
|
|
@ -88,6 +88,15 @@ usage(void) {
|
|||
fprintf(stderr, " -i <interval>: prepublication interval for "
|
||||
"successor key "
|
||||
"(default: 30 days)\n");
|
||||
fprintf(stderr, "Key state options:\n");
|
||||
fprintf(stderr, " -s: update key state file (default no)\n");
|
||||
fprintf(stderr, " -g state: set the goal state for this key\n");
|
||||
fprintf(stderr, " -d state date/[+-]offset: set the DS state\n");
|
||||
fprintf(stderr, " -k state date/[+-]offset: set the DNSKEY state\n");
|
||||
fprintf(stderr, " -r state date/[+-]offset: set the RRSIG (KSK) "
|
||||
"state\n");
|
||||
fprintf(stderr, " -z state date/[+-]offset: set the RRSIG (ZSK) "
|
||||
"state\n");
|
||||
fprintf(stderr, "Printing options:\n");
|
||||
fprintf(stderr, " -p C/P/Psync/A/R/I/D/Dsync/all: print a "
|
||||
"particular time value or values\n");
|
||||
|
|
@ -123,29 +132,87 @@ printtime(dst_key_t *key, int type, const char *tag, bool epoch,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
writekey(dst_key_t *key, const char *directory, bool write_state)
|
||||
{
|
||||
char newname[1024];
|
||||
char keystr[DST_KEY_FORMATSIZE];
|
||||
isc_buffer_t buf;
|
||||
isc_result_t result;
|
||||
int options = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE;
|
||||
|
||||
if (write_state) {
|
||||
options |= DST_TYPE_STATE;
|
||||
}
|
||||
|
||||
isc_buffer_init(&buf, newname, sizeof(newname));
|
||||
result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, &buf);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fatal("Failed to build public key filename: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
|
||||
result = dst_key_tofile(key, options, directory);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dst_key_format(key, keystr, sizeof(keystr));
|
||||
fatal("Failed to write key %s: %s", keystr,
|
||||
isc_result_totext(result));
|
||||
}
|
||||
printf("%s\n", newname);
|
||||
|
||||
isc_buffer_clear(&buf);
|
||||
result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &buf);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fatal("Failed to build private key filename: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
printf("%s\n", newname);
|
||||
|
||||
if (write_state) {
|
||||
isc_buffer_clear(&buf);
|
||||
result = dst_key_buildfilename(key, DST_TYPE_STATE, directory,
|
||||
&buf);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fatal("Failed to build key state filename: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
printf("%s\n", newname);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
isc_result_t result;
|
||||
const char *engine = NULL;
|
||||
const char *filename = NULL;
|
||||
char *directory = NULL;
|
||||
char newname[1024];
|
||||
char keystr[DST_KEY_FORMATSIZE];
|
||||
char *endp, *p;
|
||||
int ch;
|
||||
const char *predecessor = NULL;
|
||||
dst_key_t *prevkey = NULL;
|
||||
dst_key_t *key = NULL;
|
||||
isc_buffer_t buf;
|
||||
dns_name_t *name = NULL;
|
||||
dns_secalg_t alg = 0;
|
||||
unsigned int size = 0;
|
||||
uint16_t flags = 0;
|
||||
int prepub = -1;
|
||||
int options;
|
||||
dns_ttl_t ttl = 0;
|
||||
isc_stdtime_t now;
|
||||
isc_stdtime_t dstime = 0, dnskeytime = 0;
|
||||
isc_stdtime_t krrsigtime = 0, zrrsigtime = 0;
|
||||
isc_stdtime_t pub = 0, act = 0, rev = 0, inact = 0, del = 0;
|
||||
isc_stdtime_t prevact = 0, previnact = 0, prevdel = 0;
|
||||
dst_key_state_t goal = DST_KEY_STATE_NA;
|
||||
dst_key_state_t ds = DST_KEY_STATE_NA;
|
||||
dst_key_state_t dnskey = DST_KEY_STATE_NA;
|
||||
dst_key_state_t krrsig = DST_KEY_STATE_NA;
|
||||
dst_key_state_t zrrsig = DST_KEY_STATE_NA;
|
||||
bool setgoal = false, setds = false, setdnskey = false;
|
||||
bool setkrrsig = false, setzrrsig = false;
|
||||
bool setdstime = false, setdnskeytime = false;
|
||||
bool setkrrsigtime = false, setzrrsigtime = false;
|
||||
bool setpub = false, setact = false;
|
||||
bool setrev = false, setinact = false;
|
||||
bool setdel = false, setttl = false;
|
||||
|
|
@ -156,14 +223,17 @@ main(int argc, char **argv) {
|
|||
bool printact = false, printrev = false;
|
||||
bool printinact = false, printdel = false;
|
||||
bool force = false;
|
||||
bool epoch = false;
|
||||
bool changed = false;
|
||||
bool epoch = false;
|
||||
bool changed = false;
|
||||
bool write_state = false;
|
||||
isc_log_t *log = NULL;
|
||||
isc_stdtime_t syncadd = 0, syncdel = 0;
|
||||
bool unsetsyncadd = false, setsyncadd = false;
|
||||
bool unsetsyncdel = false, setsyncdel = false;
|
||||
bool printsyncadd = false, printsyncdel = false;
|
||||
|
||||
options = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_STATE;
|
||||
|
||||
if (argc == 1)
|
||||
usage();
|
||||
|
||||
|
|
@ -180,7 +250,7 @@ main(int argc, char **argv) {
|
|||
|
||||
isc_stdtime_get(&now);
|
||||
|
||||
#define CMDLINE_FLAGS "A:D:E:fhI:i:K:L:P:p:R:S:uv:V"
|
||||
#define CMDLINE_FLAGS "A:D:d:E:fg:hI:i:K:k:L:P:p:R:r:S:suv:Vz:"
|
||||
while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
|
||||
switch (ch) {
|
||||
case 'E':
|
||||
|
|
@ -339,6 +409,70 @@ main(int argc, char **argv) {
|
|||
case 'i':
|
||||
prepub = strtottl(isc_commandline_argument);
|
||||
break;
|
||||
case 's':
|
||||
write_state = true;
|
||||
break;
|
||||
case 'g':
|
||||
if (setgoal) {
|
||||
fatal("-g specified more than once");
|
||||
}
|
||||
|
||||
goal = strtokeystate(isc_commandline_argument);
|
||||
if (goal != DST_KEY_STATE_NA &&
|
||||
goal != DST_KEY_STATE_HIDDEN &&
|
||||
goal != DST_KEY_STATE_OMNIPRESENT) {
|
||||
fatal("-g must be either none, hidden, or "
|
||||
"omnipresent");
|
||||
}
|
||||
setgoal = true;
|
||||
break;
|
||||
case 'd':
|
||||
if (setds) {
|
||||
fatal("-d specified more than once");
|
||||
}
|
||||
|
||||
ds = strtokeystate(isc_commandline_argument);
|
||||
setds = true;
|
||||
/* time */
|
||||
(void)isoptarg(isc_commandline_argument, argv, usage);
|
||||
dstime = strtotime(isc_commandline_argument,
|
||||
now, now, &setdstime);
|
||||
break;
|
||||
case 'k':
|
||||
if (setdnskey) {
|
||||
fatal("-k specified more than once");
|
||||
}
|
||||
|
||||
dnskey = strtokeystate(isc_commandline_argument);
|
||||
setdnskey = true;
|
||||
/* time */
|
||||
(void)isoptarg(isc_commandline_argument, argv, usage);
|
||||
dnskeytime = strtotime(isc_commandline_argument,
|
||||
now, now, &setdnskeytime);
|
||||
break;
|
||||
case 'r':
|
||||
if (setkrrsig) {
|
||||
fatal("-r specified more than once");
|
||||
}
|
||||
|
||||
krrsig = strtokeystate(isc_commandline_argument);
|
||||
setkrrsig = true;
|
||||
/* time */
|
||||
(void)isoptarg(isc_commandline_argument, argv, usage);
|
||||
krrsigtime = strtotime(isc_commandline_argument,
|
||||
now, now, &setkrrsigtime);
|
||||
break;
|
||||
case 'z':
|
||||
if (setzrrsig) {
|
||||
fatal("-z specified more than once");
|
||||
}
|
||||
|
||||
zrrsig = strtokeystate(isc_commandline_argument);
|
||||
setzrrsig = true;
|
||||
(void)isoptarg(isc_commandline_argument, argv, usage);
|
||||
zrrsigtime = strtotime(isc_commandline_argument,
|
||||
now, now, &setzrrsigtime);
|
||||
break;
|
||||
case '?':
|
||||
if (isc_commandline_option != '?')
|
||||
fprintf(stderr, "%s: invalid argument -%c\n",
|
||||
|
|
@ -365,6 +499,12 @@ main(int argc, char **argv) {
|
|||
if (argc > isc_commandline_index + 1)
|
||||
fatal("Extraneous arguments");
|
||||
|
||||
if ((setgoal || setds || setdnskey || setkrrsig || setzrrsig) &&
|
||||
!write_state)
|
||||
{
|
||||
fatal("Options -g, -d, -k, -r and -z require -s to be set");
|
||||
}
|
||||
|
||||
result = dst_lib_init(mctx, engine);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fatal("Could not initialize dst: %s",
|
||||
|
|
@ -381,9 +521,7 @@ main(int argc, char **argv) {
|
|||
if (setact || unsetact)
|
||||
fatal("-S and -A cannot be used together");
|
||||
|
||||
result = dst_key_fromnamedfile(predecessor, directory,
|
||||
DST_TYPE_PUBLIC |
|
||||
DST_TYPE_PRIVATE,
|
||||
result = dst_key_fromnamedfile(predecessor, directory, options,
|
||||
mctx, &prevkey);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fatal("Invalid keyfile %s: %s",
|
||||
|
|
@ -475,9 +613,8 @@ main(int argc, char **argv) {
|
|||
isc_result_totext(result));
|
||||
}
|
||||
|
||||
result = dst_key_fromnamedfile(filename, directory,
|
||||
DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
|
||||
mctx, &key);
|
||||
result = dst_key_fromnamedfile(filename, directory, options, mctx,
|
||||
&key);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fatal("Invalid keyfile %s: %s",
|
||||
filename, isc_result_totext(result));
|
||||
|
|
@ -578,6 +715,11 @@ main(int argc, char **argv) {
|
|||
if (setttl)
|
||||
dst_key_setttl(key, ttl);
|
||||
|
||||
if (predecessor != NULL && prevkey != NULL) {
|
||||
dst_key_setnum(prevkey, DST_NUM_SUCCESSOR, dst_key_id(key));
|
||||
dst_key_setnum(key, DST_NUM_PREDECESSOR, dst_key_id(prevkey));
|
||||
}
|
||||
|
||||
/*
|
||||
* No metadata changes were made but we're forcing an upgrade
|
||||
* to the new format anyway: use "-P now -A now" as the default
|
||||
|
|
@ -588,6 +730,63 @@ main(int argc, char **argv) {
|
|||
changed = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the key state goals are written.
|
||||
*/
|
||||
if (write_state) {
|
||||
if (setgoal) {
|
||||
if (goal == DST_KEY_STATE_NA) {
|
||||
dst_key_unsetstate(key, DST_KEY_GOAL);
|
||||
} else {
|
||||
dst_key_setstate(key, DST_KEY_GOAL, goal);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
if (setds) {
|
||||
if (ds == DST_KEY_STATE_NA) {
|
||||
dst_key_unsetstate(key, DST_KEY_DS);
|
||||
dst_key_unsettime(key, DST_TIME_DS);
|
||||
} else {
|
||||
dst_key_setstate(key, DST_KEY_DS, ds);
|
||||
dst_key_settime(key, DST_TIME_DS, dstime);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
if (setdnskey) {
|
||||
if (dnskey == DST_KEY_STATE_NA) {
|
||||
dst_key_unsetstate(key, DST_KEY_DNSKEY);
|
||||
dst_key_unsettime(key, DST_TIME_DNSKEY);
|
||||
} else {
|
||||
dst_key_setstate(key, DST_KEY_DNSKEY, dnskey);
|
||||
dst_key_settime(key, DST_TIME_DNSKEY,
|
||||
dnskeytime);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
if (setkrrsig) {
|
||||
if (krrsig == DST_KEY_STATE_NA) {
|
||||
dst_key_unsetstate(key, DST_KEY_KRRSIG);
|
||||
dst_key_unsettime(key, DST_TIME_KRRSIG);
|
||||
} else {
|
||||
dst_key_setstate(key, DST_KEY_KRRSIG, krrsig);
|
||||
dst_key_settime(key, DST_TIME_KRRSIG,
|
||||
krrsigtime);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
if (setzrrsig) {
|
||||
if (zrrsig == DST_KEY_STATE_NA) {
|
||||
dst_key_unsetstate(key, DST_KEY_ZRRSIG);
|
||||
dst_key_unsettime(key, DST_TIME_ZRRSIG);
|
||||
} else {
|
||||
dst_key_setstate(key, DST_KEY_ZRRSIG, zrrsig);
|
||||
dst_key_settime(key, DST_TIME_ZRRSIG,
|
||||
zrrsigtime);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed && setttl)
|
||||
changed = true;
|
||||
|
||||
|
|
@ -621,32 +820,10 @@ main(int argc, char **argv) {
|
|||
epoch, stdout);
|
||||
|
||||
if (changed) {
|
||||
isc_buffer_init(&buf, newname, sizeof(newname));
|
||||
result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory,
|
||||
&buf);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fatal("Failed to build public key filename: %s",
|
||||
isc_result_totext(result));
|
||||
writekey(key, directory, write_state);
|
||||
if (predecessor != NULL && prevkey != NULL) {
|
||||
writekey(prevkey, directory, write_state);
|
||||
}
|
||||
|
||||
result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
|
||||
directory);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dst_key_format(key, keystr, sizeof(keystr));
|
||||
fatal("Failed to write key %s: %s", keystr,
|
||||
isc_result_totext(result));
|
||||
}
|
||||
|
||||
printf("%s\n", newname);
|
||||
|
||||
isc_buffer_clear(&buf);
|
||||
result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory,
|
||||
&buf);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fatal("Failed to build private key filename: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
printf("%s\n", newname);
|
||||
}
|
||||
|
||||
if (prevkey != NULL)
|
||||
|
|
|
|||
|
|
@ -64,6 +64,12 @@
|
|||
<arg choice="opt" rep="norepeat"><option>-V</option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-v <replaceable class="parameter">level</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-E <replaceable class="parameter">engine</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-s</option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-g <replaceable class="parameter">state</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-d <replaceable class="parameter">state</replaceable> <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-k <replaceable class="parameter">state</replaceable> <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-r <replaceable class="parameter">state</replaceable> <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||
<arg choice="opt" rep="norepeat"><option>-z <replaceable class="parameter">state</replaceable> <replaceable class="parameter">date/offset</replaceable></option></arg>
|
||||
<arg choice="req" rep="norepeat">keyfile</arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
|
@ -88,11 +94,30 @@
|
|||
When key metadata fields are changed, both files of a key
|
||||
pair (<filename>Knnnn.+aaa+iiiii.key</filename> and
|
||||
<filename>Knnnn.+aaa+iiiii.private</filename>) are regenerated.
|
||||
</para>
|
||||
<para>
|
||||
Metadata fields are stored in the private file. A human-readable
|
||||
description of the metadata is also placed in comments in the key
|
||||
file. The private file's permissions are always set to be
|
||||
inaccessible to anyone other than the owner (mode 0600).
|
||||
</para>
|
||||
<para>
|
||||
When working with state files, it is possible to update the timing
|
||||
metadata in those files as well with <option>-s</option>. If this
|
||||
option is used you can also update key states with <option>-d</option>
|
||||
(DS), <option>-k</option> (DNSKEY), <option>-r</option> (RRSIG of KSK),
|
||||
or <option>-z</option> (RRSIG of ZSK). Allowed states are HIDDEN,
|
||||
RUMOURED, OMNIPRESENT, and UNRETENTIVE.
|
||||
</para>
|
||||
<para>
|
||||
You can also set the goal state of the key with <option>-g</option>.
|
||||
This should be either HIDDEN or OMNIPRESENT (representing whether the
|
||||
key should be removed from the zone, or published).
|
||||
</para>
|
||||
<para>
|
||||
It is NOT RECOMMENDED to manipulate state files manually except for
|
||||
testing purposes.
|
||||
</para>
|
||||
</refsection>
|
||||
|
||||
<refsection><info><title>OPTIONS</title></info>
|
||||
|
|
@ -319,6 +344,74 @@
|
|||
</variablelist>
|
||||
</refsection>
|
||||
|
||||
<refsection><info><title>KEY STATE OPTIONS</title></info>
|
||||
|
||||
<para>
|
||||
Known key states are HIDDEN, RUMOURED, OMNIPRESENT and UNRETENTIVE.
|
||||
These should not be set manually except for testing purposes.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term>-s</term>
|
||||
<listitem>
|
||||
<para>
|
||||
When setting key timing data, also update the state file.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-g</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the goal state for this key. Must be HIDDEN or OMNIPRESENT.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-d</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the DS state for this key, and when it was last changed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-k</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the DNSKEY state for this key, and when it was last changed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-r</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the RRSIG (KSK) state for this key, and when it was last
|
||||
changed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-z</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the RRSIG (ZSK) state for this key, and when it was last
|
||||
changed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsection>
|
||||
|
||||
<refsection><info><title>PRINTING OPTIONS</title></info>
|
||||
|
||||
<para>
|
||||
|
|
|
|||
|
|
@ -2717,7 +2717,7 @@ build_final_keylist(void) {
|
|||
* Update keylist with information from from the key repository.
|
||||
*/
|
||||
dns_dnssec_updatekeys(&keylist, &matchkeys, NULL, gorigin, keyttl,
|
||||
&diff, ignore_kskflag, mctx, report);
|
||||
&diff, mctx, report);
|
||||
|
||||
/*
|
||||
* Update keylist with sync records.
|
||||
|
|
|
|||
|
|
@ -57,6 +57,11 @@
|
|||
|
||||
#include "dnssectool.h"
|
||||
|
||||
#define KEYSTATES_NVALUES 4
|
||||
static const char *keystates[KEYSTATES_NVALUES] = {
|
||||
"hidden", "rumoured", "omnipresent", "unretentive",
|
||||
};
|
||||
|
||||
int verbose = 0;
|
||||
bool quiet = false;
|
||||
uint8_t dtype[8];
|
||||
|
|
@ -244,6 +249,21 @@ strtottl(const char *str) {
|
|||
return (ttl);
|
||||
}
|
||||
|
||||
dst_key_state_t
|
||||
strtokeystate(const char *str) {
|
||||
if (isnone(str)) {
|
||||
return (DST_KEY_STATE_NA);
|
||||
}
|
||||
|
||||
for (int i = 0; i < KEYSTATES_NVALUES; i++) {
|
||||
if (keystates[i] != NULL &&
|
||||
strcasecmp(str, keystates[i]) == 0) {
|
||||
return (dst_key_state_t) i;
|
||||
}
|
||||
}
|
||||
fatal("unknown key state");
|
||||
}
|
||||
|
||||
isc_stdtime_t
|
||||
strtotime(const char *str, int64_t now, int64_t base,
|
||||
bool *setp)
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ cleanup_logging(isc_log_t **logp);
|
|||
|
||||
dns_ttl_t strtottl(const char *str);
|
||||
|
||||
dst_key_state_t strtokeystate(const char *str);
|
||||
|
||||
isc_stdtime_t
|
||||
strtotime(const char *str, int64_t now, int64_t base,
|
||||
bool *setp);
|
||||
|
|
|
|||
|
|
@ -66,15 +66,15 @@
|
|||
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\isccfg\win32;..\..\..\lib\isccfg\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<OutputFile>..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalDependencies>@OPENSSL_LIB@dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>@OPENSSL_LIB@dnssectool.lib;libisc.lib;libisccfg.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|@PLATFORM@'">
|
||||
|
|
@ -94,7 +94,7 @@
|
|||
<ObjectFileName>.\$(Configuration)\</ObjectFileName>
|
||||
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles>
|
||||
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>.\;..\..\..\;@LIBXML2_INC@@OPENSSL_INC@..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\isccfg\win32;..\..\..\lib\isccfg\include;..\..\..\lib\dns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
|
@ -104,8 +104,8 @@
|
|||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<OutputFile>..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt)</OutputFile>
|
||||
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||
<AdditionalDependencies>@OPENSSL_LIB@dnssectool.lib;libisc.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>@OPENSSL_LIB@dnssectool.lib;libisc.lib;libisccfg.lib;libdns.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(Configuration);..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ options {\n\
|
|||
"\
|
||||
# deallocate-on-exit <obsolete>;\n\
|
||||
# directory <none>\n\
|
||||
dnssec-policy \"none\";\n\
|
||||
dump-file \"named_dump.db\";\n\
|
||||
edns-udp-size 4096;\n\
|
||||
# fake-iquery <obsolete>;\n"
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ struct named_server {
|
|||
dns_loadmgr_t * loadmgr;
|
||||
dns_zonemgr_t * zonemgr;
|
||||
dns_viewlist_t viewlist;
|
||||
dns_kasplist_t kasplist;
|
||||
ns_interfacemgr_t * interfacemgr;
|
||||
dns_db_t * in_roothints;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,19 +27,18 @@ ISC_LANG_BEGINDECLS
|
|||
isc_result_t
|
||||
named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac,
|
||||
dns_zone_t *zone, dns_zone_t *raw);
|
||||
dns_kasplist_t* kasplist, dns_zone_t *zone,
|
||||
dns_zone_t *raw);
|
||||
/*%<
|
||||
* Configure or reconfigure a zone according to the named.conf
|
||||
* data in 'cctx' and 'czone'.
|
||||
* data.
|
||||
*
|
||||
* The zone origin is not configured, it is assumed to have been set
|
||||
* at zone creation time.
|
||||
*
|
||||
* Require:
|
||||
* \li 'lctx' to be initialized or NULL.
|
||||
* \li 'cctx' to be initialized or NULL.
|
||||
* \li 'ac' to point to an initialized cfg_aclconfctx_t.
|
||||
* \li 'czone' to be initialized.
|
||||
* \li 'kasplist' to be initialized.
|
||||
* \li 'zone' to be initialized.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ options {
|
|||
[ 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> ]; ... } ] [ zone-directory <replaceable>quoted_string</replaceable> ] [
|
||||
in-memory <replaceable>boolean</replaceable> ] [ min-update-interval <replaceable>ttlval</replaceable> ]; ... };
|
||||
in-memory <replaceable>boolean</replaceable> ] [ min-update-interval <replaceable>duration</replaceable> ]; ... };
|
||||
check-dup-records ( fail | warn | ignore );
|
||||
check-integrity <replaceable>boolean</replaceable>;
|
||||
check-mx ( fail | warn | ignore );
|
||||
|
|
@ -290,18 +290,18 @@ options {
|
|||
fstrm-set-output-notify-threshold <replaceable>integer</replaceable>;
|
||||
fstrm-set-output-queue-model ( mpsc | spsc );
|
||||
fstrm-set-output-queue-size <replaceable>integer</replaceable>;
|
||||
fstrm-set-reopen-interval <replaceable>ttlval</replaceable>;
|
||||
fstrm-set-reopen-interval <replaceable>duration</replaceable>;
|
||||
geoip-directory ( <replaceable>quoted_string</replaceable> | none );
|
||||
glue-cache <replaceable>boolean</replaceable>;
|
||||
heartbeat-interval <replaceable>integer</replaceable>;
|
||||
hostname ( <replaceable>quoted_string</replaceable> | none );
|
||||
inline-signing <replaceable>boolean</replaceable>;
|
||||
interface-interval <replaceable>ttlval</replaceable>;
|
||||
interface-interval <replaceable>duration</replaceable>;
|
||||
ixfr-from-differences ( primary | master | secondary | slave |
|
||||
<replaceable>boolean</replaceable> );
|
||||
keep-response-order { <replaceable>address_match_element</replaceable>; ... };
|
||||
key-directory <replaceable>quoted_string</replaceable>;
|
||||
lame-ttl <replaceable>ttlval</replaceable>;
|
||||
lame-ttl <replaceable>duration</replaceable>;
|
||||
listen-on [ port <replaceable>integer</replaceable> ] [ dscp
|
||||
<replaceable>integer</replaceable> ] {
|
||||
<replaceable>address_match_element</replaceable>; ... };
|
||||
|
|
@ -315,28 +315,28 @@ options {
|
|||
masterfile-style ( full | relative );
|
||||
match-mapped-addresses <replaceable>boolean</replaceable>;
|
||||
max-cache-size ( default | unlimited | <replaceable>sizeval</replaceable> | <replaceable>percentage</replaceable> );
|
||||
max-cache-ttl <replaceable>ttlval</replaceable>;
|
||||
max-cache-ttl <replaceable>duration</replaceable>;
|
||||
max-clients-per-query <replaceable>integer</replaceable>;
|
||||
max-journal-size ( default | unlimited | <replaceable>sizeval</replaceable> );
|
||||
max-ncache-ttl <replaceable>ttlval</replaceable>;
|
||||
max-ncache-ttl <replaceable>duration</replaceable>;
|
||||
max-records <replaceable>integer</replaceable>;
|
||||
max-recursion-depth <replaceable>integer</replaceable>;
|
||||
max-recursion-queries <replaceable>integer</replaceable>;
|
||||
max-refresh-time <replaceable>integer</replaceable>;
|
||||
max-retry-time <replaceable>integer</replaceable>;
|
||||
max-rsa-exponent-size <replaceable>integer</replaceable>;
|
||||
max-stale-ttl <replaceable>ttlval</replaceable>;
|
||||
max-stale-ttl <replaceable>duration</replaceable>;
|
||||
max-transfer-idle-in <replaceable>integer</replaceable>;
|
||||
max-transfer-idle-out <replaceable>integer</replaceable>;
|
||||
max-transfer-time-in <replaceable>integer</replaceable>;
|
||||
max-transfer-time-out <replaceable>integer</replaceable>;
|
||||
max-udp-size <replaceable>integer</replaceable>;
|
||||
max-zone-ttl ( unlimited | <replaceable>ttlval</replaceable> );
|
||||
max-zone-ttl ( unlimited | <replaceable>duration</replaceable> );
|
||||
memstatistics <replaceable>boolean</replaceable>;
|
||||
memstatistics-file <replaceable>quoted_string</replaceable>;
|
||||
message-compression <replaceable>boolean</replaceable>;
|
||||
min-cache-ttl <replaceable>ttlval</replaceable>;
|
||||
min-ncache-ttl <replaceable>ttlval</replaceable>;
|
||||
min-cache-ttl <replaceable>duration</replaceable>;
|
||||
min-ncache-ttl <replaceable>duration</replaceable>;
|
||||
min-refresh-time <replaceable>integer</replaceable>;
|
||||
min-retry-time <replaceable>integer</replaceable>;
|
||||
minimal-any <replaceable>boolean</replaceable>;
|
||||
|
|
@ -353,8 +353,8 @@ options {
|
|||
notify-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ]
|
||||
[ dscp <replaceable>integer</replaceable> ];
|
||||
notify-to-soa <replaceable>boolean</replaceable>;
|
||||
nta-lifetime <replaceable>ttlval</replaceable>;
|
||||
nta-recheck <replaceable>ttlval</replaceable>;
|
||||
nta-lifetime <replaceable>duration</replaceable>;
|
||||
nta-recheck <replaceable>duration</replaceable>;
|
||||
nxdomain-redirect <replaceable>string</replaceable>;
|
||||
pid-file ( <replaceable>quoted_string</replaceable> | none );
|
||||
port <replaceable>integer</replaceable>;
|
||||
|
|
@ -401,13 +401,13 @@ options {
|
|||
response-padding { <replaceable>address_match_element</replaceable>; ... } block-size
|
||||
<replaceable>integer</replaceable>;
|
||||
response-policy { zone <replaceable>string</replaceable> [ add-soa <replaceable>boolean</replaceable> ] [ log
|
||||
<replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>ttlval</replaceable> ] [ min-update-interval
|
||||
<replaceable>ttlval</replaceable> ] [ policy ( cname | disabled | drop | given | no-op |
|
||||
<replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>duration</replaceable> ] [ min-update-interval
|
||||
<replaceable>duration</replaceable> ] [ policy ( cname | disabled | drop | given | no-op |
|
||||
nodata | nxdomain | passthru | tcp-only <replaceable>quoted_string</replaceable> ) ] [
|
||||
recursive-only <replaceable>boolean</replaceable> ] [ nsip-enable <replaceable>boolean</replaceable> ] [
|
||||
nsdname-enable <replaceable>boolean</replaceable> ]; ... } [ add-soa <replaceable>boolean</replaceable> ] [
|
||||
break-dnssec <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>ttlval</replaceable> ] [
|
||||
min-update-interval <replaceable>ttlval</replaceable> ] [ min-ns-dots <replaceable>integer</replaceable> ] [
|
||||
break-dnssec <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>duration</replaceable> ] [
|
||||
min-update-interval <replaceable>duration</replaceable> ] [ min-ns-dots <replaceable>integer</replaceable> ] [
|
||||
nsip-wait-recurse <replaceable>boolean</replaceable> ] [ qname-wait-recurse <replaceable>boolean</replaceable> ]
|
||||
[ recursive-only <replaceable>boolean</replaceable> ] [ nsip-enable <replaceable>boolean</replaceable> ] [
|
||||
nsdname-enable <replaceable>boolean</replaceable> ] [ dnsrps-enable <replaceable>boolean</replaceable> ] [
|
||||
|
|
@ -421,7 +421,7 @@ options {
|
|||
serial-query-rate <replaceable>integer</replaceable>;
|
||||
serial-update-method ( date | increment | unixtime );
|
||||
server-id ( <replaceable>quoted_string</replaceable> | none | hostname );
|
||||
servfail-ttl <replaceable>ttlval</replaceable>;
|
||||
servfail-ttl <replaceable>duration</replaceable>;
|
||||
session-keyalg <replaceable>string</replaceable>;
|
||||
session-keyfile ( <replaceable>quoted_string</replaceable> | none );
|
||||
session-keyname <replaceable>string</replaceable>;
|
||||
|
|
@ -432,7 +432,7 @@ options {
|
|||
sortlist { <replaceable>address_match_element</replaceable>; ... };
|
||||
stacksize ( default | unlimited | <replaceable>sizeval</replaceable> );
|
||||
stale-answer-enable <replaceable>boolean</replaceable>;
|
||||
stale-answer-ttl <replaceable>ttlval</replaceable>;
|
||||
stale-answer-ttl <replaceable>duration</replaceable>;
|
||||
startup-notify-rate <replaceable>integer</replaceable>;
|
||||
statistics-file <replaceable>quoted_string</replaceable>;
|
||||
synth-from-dnssec <replaceable>boolean</replaceable>;
|
||||
|
|
@ -564,7 +564,7 @@ view <replaceable>string</replaceable> [ <replaceable>class</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> ]; ... } ] [ zone-directory <replaceable>quoted_string</replaceable> ] [
|
||||
in-memory <replaceable>boolean</replaceable> ] [ min-update-interval <replaceable>ttlval</replaceable> ]; ... };
|
||||
in-memory <replaceable>boolean</replaceable> ] [ min-update-interval <replaceable>duration</replaceable> ]; ... };
|
||||
check-dup-records ( fail | warn | ignore );
|
||||
check-integrity <replaceable>boolean</replaceable>;
|
||||
check-mx ( fail | warn | ignore );
|
||||
|
|
@ -642,7 +642,7 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
|
|||
secret <replaceable>string</replaceable>;
|
||||
};
|
||||
key-directory <replaceable>quoted_string</replaceable>;
|
||||
lame-ttl <replaceable>ttlval</replaceable>;
|
||||
lame-ttl <replaceable>duration</replaceable>;
|
||||
lmdb-mapsize <replaceable>sizeval</replaceable>;
|
||||
managed-keys { <replaceable>string</replaceable> (
|
||||
static-key | initial-key
|
||||
|
|
@ -655,25 +655,25 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
|
|||
match-destinations { <replaceable>address_match_element</replaceable>; ... };
|
||||
match-recursive-only <replaceable>boolean</replaceable>;
|
||||
max-cache-size ( default | unlimited | <replaceable>sizeval</replaceable> | <replaceable>percentage</replaceable> );
|
||||
max-cache-ttl <replaceable>ttlval</replaceable>;
|
||||
max-cache-ttl <replaceable>duration</replaceable>;
|
||||
max-clients-per-query <replaceable>integer</replaceable>;
|
||||
max-journal-size ( default | unlimited | <replaceable>sizeval</replaceable> );
|
||||
max-ncache-ttl <replaceable>ttlval</replaceable>;
|
||||
max-ncache-ttl <replaceable>duration</replaceable>;
|
||||
max-records <replaceable>integer</replaceable>;
|
||||
max-recursion-depth <replaceable>integer</replaceable>;
|
||||
max-recursion-queries <replaceable>integer</replaceable>;
|
||||
max-refresh-time <replaceable>integer</replaceable>;
|
||||
max-retry-time <replaceable>integer</replaceable>;
|
||||
max-stale-ttl <replaceable>ttlval</replaceable>;
|
||||
max-stale-ttl <replaceable>duration</replaceable>;
|
||||
max-transfer-idle-in <replaceable>integer</replaceable>;
|
||||
max-transfer-idle-out <replaceable>integer</replaceable>;
|
||||
max-transfer-time-in <replaceable>integer</replaceable>;
|
||||
max-transfer-time-out <replaceable>integer</replaceable>;
|
||||
max-udp-size <replaceable>integer</replaceable>;
|
||||
max-zone-ttl ( unlimited | <replaceable>ttlval</replaceable> );
|
||||
max-zone-ttl ( unlimited | <replaceable>duration</replaceable> );
|
||||
message-compression <replaceable>boolean</replaceable>;
|
||||
min-cache-ttl <replaceable>ttlval</replaceable>;
|
||||
min-ncache-ttl <replaceable>ttlval</replaceable>;
|
||||
min-cache-ttl <replaceable>duration</replaceable>;
|
||||
min-ncache-ttl <replaceable>duration</replaceable>;
|
||||
min-refresh-time <replaceable>integer</replaceable>;
|
||||
min-retry-time <replaceable>integer</replaceable>;
|
||||
minimal-any <replaceable>boolean</replaceable>;
|
||||
|
|
@ -689,8 +689,8 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
|
|||
notify-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ]
|
||||
[ dscp <replaceable>integer</replaceable> ];
|
||||
notify-to-soa <replaceable>boolean</replaceable>;
|
||||
nta-lifetime <replaceable>ttlval</replaceable>;
|
||||
nta-recheck <replaceable>ttlval</replaceable>;
|
||||
nta-lifetime <replaceable>duration</replaceable>;
|
||||
nta-recheck <replaceable>duration</replaceable>;
|
||||
nxdomain-redirect <replaceable>string</replaceable>;
|
||||
plugin ( query ) <replaceable>string</replaceable> [ {
|
||||
<replaceable>unspecified-text</replaceable> } ];
|
||||
|
|
@ -732,13 +732,13 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
|
|||
response-padding { <replaceable>address_match_element</replaceable>; ... } block-size
|
||||
<replaceable>integer</replaceable>;
|
||||
response-policy { zone <replaceable>string</replaceable> [ add-soa <replaceable>boolean</replaceable> ] [ log
|
||||
<replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>ttlval</replaceable> ] [ min-update-interval
|
||||
<replaceable>ttlval</replaceable> ] [ policy ( cname | disabled | drop | given | no-op |
|
||||
<replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>duration</replaceable> ] [ min-update-interval
|
||||
<replaceable>duration</replaceable> ] [ policy ( cname | disabled | drop | given | no-op |
|
||||
nodata | nxdomain | passthru | tcp-only <replaceable>quoted_string</replaceable> ) ] [
|
||||
recursive-only <replaceable>boolean</replaceable> ] [ nsip-enable <replaceable>boolean</replaceable> ] [
|
||||
nsdname-enable <replaceable>boolean</replaceable> ]; ... } [ add-soa <replaceable>boolean</replaceable> ] [
|
||||
break-dnssec <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>ttlval</replaceable> ] [
|
||||
min-update-interval <replaceable>ttlval</replaceable> ] [ min-ns-dots <replaceable>integer</replaceable> ] [
|
||||
break-dnssec <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>duration</replaceable> ] [
|
||||
min-update-interval <replaceable>duration</replaceable> ] [ min-ns-dots <replaceable>integer</replaceable> ] [
|
||||
nsip-wait-recurse <replaceable>boolean</replaceable> ] [ qname-wait-recurse <replaceable>boolean</replaceable> ]
|
||||
[ recursive-only <replaceable>boolean</replaceable> ] [ nsip-enable <replaceable>boolean</replaceable> ] [
|
||||
nsdname-enable <replaceable>boolean</replaceable> ] [ dnsrps-enable <replaceable>boolean</replaceable> ] [
|
||||
|
|
@ -783,14 +783,14 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
|
|||
<replaceable>integer</replaceable> | * ) ] [ dscp <replaceable>integer</replaceable> ];
|
||||
transfers <replaceable>integer</replaceable>;
|
||||
};
|
||||
servfail-ttl <replaceable>ttlval</replaceable>;
|
||||
servfail-ttl <replaceable>duration</replaceable>;
|
||||
sig-signing-nodes <replaceable>integer</replaceable>;
|
||||
sig-signing-signatures <replaceable>integer</replaceable>;
|
||||
sig-signing-type <replaceable>integer</replaceable>;
|
||||
sig-validity-interval <replaceable>integer</replaceable> [ <replaceable>integer</replaceable> ];
|
||||
sortlist { <replaceable>address_match_element</replaceable>; ... };
|
||||
stale-answer-enable <replaceable>boolean</replaceable>;
|
||||
stale-answer-ttl <replaceable>ttlval</replaceable>;
|
||||
stale-answer-ttl <replaceable>duration</replaceable>;
|
||||
synth-from-dnssec <replaceable>boolean</replaceable>;
|
||||
transfer-format ( many-answers | one-answer );
|
||||
transfer-source ( <replaceable>ipv4_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ] [
|
||||
|
|
@ -842,6 +842,7 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
|
|||
dnskey-sig-validity <replaceable>integer</replaceable>;
|
||||
dnssec-dnskey-kskonly <replaceable>boolean</replaceable>;
|
||||
dnssec-loadkeys-interval <replaceable>integer</replaceable>;
|
||||
dnssec-policy <replaceable>string</replaceable>;
|
||||
dnssec-secure-to-insecure <replaceable>boolean</replaceable>;
|
||||
dnssec-update-mode ( maintain | no-resign );
|
||||
file <replaceable>quoted_string</replaceable>;
|
||||
|
|
@ -867,7 +868,7 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
|
|||
max-transfer-idle-out <replaceable>integer</replaceable>;
|
||||
max-transfer-time-in <replaceable>integer</replaceable>;
|
||||
max-transfer-time-out <replaceable>integer</replaceable>;
|
||||
max-zone-ttl ( unlimited | <replaceable>ttlval</replaceable> );
|
||||
max-zone-ttl ( unlimited | <replaceable>duration</replaceable> );
|
||||
min-refresh-time <replaceable>integer</replaceable>;
|
||||
min-retry-time <replaceable>integer</replaceable>;
|
||||
multi-master <replaceable>boolean</replaceable>;
|
||||
|
|
@ -943,6 +944,7 @@ zone <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
|
|||
dnskey-sig-validity <replaceable>integer</replaceable>;
|
||||
dnssec-dnskey-kskonly <replaceable>boolean</replaceable>;
|
||||
dnssec-loadkeys-interval <replaceable>integer</replaceable>;
|
||||
dnssec-policy <replaceable>string</replaceable>;
|
||||
dnssec-secure-to-insecure <replaceable>boolean</replaceable>;
|
||||
dnssec-update-mode ( maintain | no-resign );
|
||||
file <replaceable>quoted_string</replaceable>;
|
||||
|
|
@ -967,7 +969,7 @@ zone <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
|
|||
max-transfer-idle-out <replaceable>integer</replaceable>;
|
||||
max-transfer-time-in <replaceable>integer</replaceable>;
|
||||
max-transfer-time-out <replaceable>integer</replaceable>;
|
||||
max-zone-ttl ( unlimited | <replaceable>ttlval</replaceable> );
|
||||
max-zone-ttl ( unlimited | <replaceable>duration</replaceable> );
|
||||
min-refresh-time <replaceable>integer</replaceable>;
|
||||
min-retry-time <replaceable>integer</replaceable>;
|
||||
multi-master <replaceable>boolean</replaceable>;
|
||||
|
|
@ -1008,6 +1010,26 @@ zone <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
|
|||
</literallayout>
|
||||
</refsection>
|
||||
|
||||
<refsection><info><title>DNSSEC-POLICY</title></info>
|
||||
|
||||
<literallayout class="normal">
|
||||
dnssec-policy <replaceable>string</replaceable> {
|
||||
dnskey-ttl <replaceable>ttlval</replaceable>;
|
||||
keys { ( csk | ksk | zsk ) key-directory lifetime <replaceable>duration</replaceable> algorithm <replaceable>integer</replaceable> [ <replaceable>integer</replaceable> ] ; ... };
|
||||
parent-ds-ttl <replaceable>duration</replaceable>;
|
||||
parent-propagation-delay <replaceable>duration</replaceable>;
|
||||
parent-registration-delay <replaceable>duration</replaceable>;
|
||||
publish-safety <replaceable>duration</replaceable>;
|
||||
retire-safety <replaceable>duration</replaceable>;
|
||||
signatures-refresh <replaceable>duration</replaceable>;
|
||||
signatures-validity <replaceable>duration</replaceable>;
|
||||
signatures-validity-dnskey <replaceable>duration</replaceable>;
|
||||
zone-max-ttl <replaceable>duration</replaceable>;
|
||||
zone-propagation-delay <replaceable>duration</replaceable>;
|
||||
};
|
||||
</literallayout>
|
||||
</refsection>
|
||||
|
||||
<refsection><info><title>FILES</title></info>
|
||||
|
||||
<para><filename>/etc/named.conf</filename>
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include <isc/util.h>
|
||||
|
||||
#include <isccfg/grammar.h>
|
||||
#include <isccfg/kaspconf.h>
|
||||
#include <isccfg/namedconf.h>
|
||||
|
||||
#include <bind9/check.h>
|
||||
|
|
@ -68,6 +69,7 @@
|
|||
#include <dns/forward.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/journal.h>
|
||||
#include <dns/kasp.h>
|
||||
#include <dns/keytable.h>
|
||||
#include <dns/keyvalues.h>
|
||||
#include <dns/lib.h>
|
||||
|
|
@ -459,8 +461,8 @@ configure_alternates(const cfg_obj_t *config, dns_view_t *view,
|
|||
static isc_result_t
|
||||
configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
||||
const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
|
||||
dns_viewlist_t *viewlist, cfg_aclconfctx_t *aclconf,
|
||||
bool added, bool old_rpz_ok,
|
||||
dns_viewlist_t *viewlist, dns_kasplist_t* kasplist,
|
||||
cfg_aclconfctx_t *aclconf, bool added, bool old_rpz_ok,
|
||||
bool modify);
|
||||
|
||||
static isc_result_t
|
||||
|
|
@ -2039,7 +2041,13 @@ conf_dnsrps_num(const cfg_obj_t *obj, const char *name,
|
|||
return;
|
||||
}
|
||||
|
||||
conf_dnsrps_sadd(ctx, " %s %d", name, cfg_obj_asuint32(sub_obj));
|
||||
if (cfg_obj_isduration(sub_obj)) {
|
||||
conf_dnsrps_sadd(ctx, " %s %d", name,
|
||||
cfg_obj_asduration(sub_obj));
|
||||
} else {
|
||||
conf_dnsrps_sadd(ctx, " %s %d", name,
|
||||
cfg_obj_asuint32(sub_obj));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2221,15 +2229,15 @@ configure_rpz_zone(dns_view_t *view, const cfg_listelt_t *element,
|
|||
}
|
||||
|
||||
obj = cfg_tuple_get(rpz_obj, "max-policy-ttl");
|
||||
if (cfg_obj_isuint32(obj)) {
|
||||
zone->max_policy_ttl = cfg_obj_asuint32(obj);
|
||||
if (cfg_obj_isduration(obj)) {
|
||||
zone->max_policy_ttl = cfg_obj_asduration(obj);
|
||||
} else {
|
||||
zone->max_policy_ttl = ttl_default;
|
||||
}
|
||||
|
||||
obj = cfg_tuple_get(rpz_obj, "min-update-interval");
|
||||
if (cfg_obj_isuint32(obj)) {
|
||||
zone->min_update_interval = cfg_obj_asuint32(obj);
|
||||
if (cfg_obj_isduration(obj)) {
|
||||
zone->min_update_interval = cfg_obj_asduration(obj);
|
||||
} else {
|
||||
zone->min_update_interval = minupdateinterval_default;
|
||||
}
|
||||
|
|
@ -2448,14 +2456,14 @@ configure_rpz(dns_view_t *view, const cfg_obj_t **maps,
|
|||
}
|
||||
|
||||
sub_obj = cfg_tuple_get(rpz_obj, "max-policy-ttl");
|
||||
if (cfg_obj_isuint32(sub_obj))
|
||||
ttl_default = cfg_obj_asuint32(sub_obj);
|
||||
if (cfg_obj_isduration(sub_obj))
|
||||
ttl_default = cfg_obj_asduration(sub_obj);
|
||||
else
|
||||
ttl_default = DNS_RPZ_MAX_TTL_DEFAULT;
|
||||
|
||||
sub_obj = cfg_tuple_get(rpz_obj, "min-update-interval");
|
||||
if (cfg_obj_isuint32(sub_obj))
|
||||
minupdateinterval_default = cfg_obj_asuint32(sub_obj);
|
||||
if (cfg_obj_isduration(sub_obj))
|
||||
minupdateinterval_default = cfg_obj_asduration(sub_obj);
|
||||
else
|
||||
minupdateinterval_default = DNS_RPZ_MINUPDATEINTERVAL_DEFAULT;
|
||||
|
||||
|
|
@ -2679,7 +2687,8 @@ catz_addmodzone_taskaction(isc_task_t *task, isc_event_t *event0) {
|
|||
dns_view_thaw(ev->view);
|
||||
result = configure_zone(cfg->config, zoneobj, cfg->vconfig,
|
||||
ev->cbd->server->mctx, ev->view,
|
||||
&ev->cbd->server->viewlist, cfg->actx,
|
||||
&ev->cbd->server->viewlist,
|
||||
&ev->cbd->server->kasplist, cfg->actx,
|
||||
true, false, ev->mod);
|
||||
dns_view_freeze(ev->view);
|
||||
isc_task_endexclusive(task);
|
||||
|
|
@ -2992,8 +3001,8 @@ configure_catz_zone(dns_view_t *view, const cfg_obj_t *config,
|
|||
}
|
||||
|
||||
obj = cfg_tuple_get(catz_obj, "min-update-interval");
|
||||
if (obj != NULL && cfg_obj_isuint32(obj))
|
||||
opts->min_update_interval = cfg_obj_asuint32(obj);
|
||||
if (obj != NULL && cfg_obj_isduration(obj))
|
||||
opts->min_update_interval = cfg_obj_asduration(obj);
|
||||
|
||||
cleanup:
|
||||
if (pview != NULL)
|
||||
|
|
@ -3641,7 +3650,7 @@ configure_dnstap(const cfg_obj_t **maps, dns_view_t *view) {
|
|||
result = named_config_get(maps, "fstrm-set-reopen-interval",
|
||||
&obj);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
i = cfg_obj_asuint32(obj);
|
||||
i = cfg_obj_asduration(obj);
|
||||
fstrm_iothr_options_set_reopen_interval(fopt, i);
|
||||
}
|
||||
|
||||
|
|
@ -3764,11 +3773,10 @@ register_one_plugin(const cfg_obj_t *config, const cfg_obj_t *obj,
|
|||
* global defaults in 'config' used exclusively.
|
||||
*/
|
||||
static isc_result_t
|
||||
configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
||||
cfg_obj_t *config, cfg_obj_t *vconfig,
|
||||
named_cachelist_t *cachelist, const cfg_obj_t *bindkeys,
|
||||
isc_mem_t *mctx, cfg_aclconfctx_t *actx,
|
||||
bool need_hints)
|
||||
configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
|
||||
cfg_obj_t *vconfig, named_cachelist_t *cachelist,
|
||||
dns_kasplist_t *kasplist, const cfg_obj_t *bindkeys,
|
||||
isc_mem_t *mctx, cfg_aclconfctx_t *actx, bool need_hints)
|
||||
{
|
||||
const cfg_obj_t *maps[4];
|
||||
const cfg_obj_t *cfgmaps[3];
|
||||
|
|
@ -3895,8 +3903,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
|||
{
|
||||
const cfg_obj_t *zconfig = cfg_listelt_value(element);
|
||||
CHECK(configure_zone(config, zconfig, vconfig, mctx, view,
|
||||
viewlist, actx, false, old_rpz_ok,
|
||||
false));
|
||||
viewlist, kasplist, actx, false,
|
||||
old_rpz_ok, false));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -4217,22 +4225,22 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
|||
obj = NULL;
|
||||
result = named_config_get(maps, "max-cache-ttl", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
view->maxcachettl = cfg_obj_asuint32(obj);
|
||||
view->maxcachettl = cfg_obj_asduration(obj);
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "max-ncache-ttl", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
view->maxncachettl = cfg_obj_asuint32(obj);
|
||||
view->maxncachettl = cfg_obj_asduration(obj);
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "min-cache-ttl", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
view->mincachettl = cfg_obj_asuint32(obj);
|
||||
view->mincachettl = cfg_obj_asduration(obj);
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "min-ncache-ttl", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
view->minncachettl = cfg_obj_asuint32(obj);
|
||||
view->minncachettl = cfg_obj_asduration(obj);
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "synth-from-dnssec", &obj);
|
||||
|
|
@ -4242,7 +4250,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
|||
obj = NULL;
|
||||
result = named_config_get(maps, "max-stale-ttl", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
max_stale_ttl = ISC_MAX(cfg_obj_asuint32(obj), 1);
|
||||
max_stale_ttl = ISC_MAX(cfg_obj_asduration(obj), 1);
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "stale-answer-enable", &obj);
|
||||
|
|
@ -4392,7 +4400,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
|||
obj = NULL;
|
||||
result = named_config_get(maps, "stale-answer-ttl", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
view->staleanswerttl = ISC_MAX(cfg_obj_asuint32(obj), 1);
|
||||
view->staleanswerttl = ISC_MAX(cfg_obj_asduration(obj), 1);
|
||||
|
||||
/*
|
||||
* Resolver.
|
||||
|
|
@ -4512,7 +4520,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
|||
obj = NULL;
|
||||
result = named_config_get(maps, "lame-ttl", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
lame_ttl = cfg_obj_asuint32(obj);
|
||||
lame_ttl = cfg_obj_asduration(obj);
|
||||
if (lame_ttl > 1800)
|
||||
lame_ttl = 1800;
|
||||
dns_resolver_setlamettl(view->resolver, lame_ttl);
|
||||
|
|
@ -5216,12 +5224,12 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
|||
obj = NULL;
|
||||
result = named_config_get(maps, "nta-recheck", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
view->nta_recheck = cfg_obj_asuint32(obj);
|
||||
view->nta_recheck = cfg_obj_asduration(obj);
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "nta-lifetime", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
view->nta_lifetime = cfg_obj_asuint32(obj);
|
||||
view->nta_lifetime = cfg_obj_asduration(obj);
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "preferred-glue", &obj);
|
||||
|
|
@ -5464,7 +5472,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
|
|||
obj = NULL;
|
||||
result = named_config_get(maps, "servfail-ttl", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
fail_ttl = cfg_obj_asuint32(obj);
|
||||
fail_ttl = cfg_obj_asduration(obj);
|
||||
if (fail_ttl > 30)
|
||||
fail_ttl = 30;
|
||||
dns_view_setfailttl(view, fail_ttl);
|
||||
|
|
@ -5893,8 +5901,8 @@ create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist,
|
|||
static isc_result_t
|
||||
configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
||||
const cfg_obj_t *vconfig, isc_mem_t *mctx, dns_view_t *view,
|
||||
dns_viewlist_t *viewlist, cfg_aclconfctx_t *aclconf,
|
||||
bool added, bool old_rpz_ok,
|
||||
dns_viewlist_t *viewlist, dns_kasplist_t *kasplist,
|
||||
cfg_aclconfctx_t *aclconf, bool added, bool old_rpz_ok,
|
||||
bool modify)
|
||||
{
|
||||
dns_view_t *pview = NULL; /* Production view */
|
||||
|
|
@ -6111,8 +6119,8 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||
zone));
|
||||
dns_zone_setstats(zone, named_g_server->zonestats);
|
||||
}
|
||||
CHECK(named_zone_configure(config, vconfig, zconfig,
|
||||
aclconf, zone, NULL));
|
||||
CHECK(named_zone_configure(config, vconfig, zconfig, aclconf,
|
||||
kasplist, zone, NULL));
|
||||
dns_zone_attach(zone, &view->redirect);
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -6249,8 +6257,11 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||
strcasecmp(ztypestr, "master") == 0 ||
|
||||
strcasecmp(ztypestr, "secondary") == 0 ||
|
||||
strcasecmp(ztypestr, "slave") == 0) &&
|
||||
cfg_map_get(zoptions, "inline-signing", &signing) == ISC_R_SUCCESS &&
|
||||
cfg_obj_asboolean(signing))
|
||||
((cfg_map_get(zoptions, "inline-signing", &signing) ==
|
||||
ISC_R_SUCCESS && cfg_obj_asboolean(signing)) ||
|
||||
(cfg_map_get(zoptions, "dnssec-policy", &signing) ==
|
||||
ISC_R_SUCCESS && signing != NULL &&
|
||||
strcmp(cfg_obj_asstring(signing), "none") != 0)))
|
||||
{
|
||||
dns_zone_getraw(zone, &raw);
|
||||
if (raw == NULL) {
|
||||
|
|
@ -6274,8 +6285,8 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
|
|||
/*
|
||||
* Configure the zone.
|
||||
*/
|
||||
CHECK(named_zone_configure(config, vconfig, zconfig,
|
||||
aclconf, zone, raw));
|
||||
CHECK(named_zone_configure(config, vconfig, zconfig, aclconf, kasplist,
|
||||
zone, raw));
|
||||
|
||||
/*
|
||||
* Add the zone to its view in the new view list.
|
||||
|
|
@ -7567,9 +7578,10 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
|
|||
element = cfg_list_next(element))
|
||||
{
|
||||
const cfg_obj_t *zconfig = cfg_listelt_value(element);
|
||||
CHECK(configure_zone(config, zconfig, vconfig, mctx,
|
||||
view, &named_g_server->viewlist, actx,
|
||||
true, false, false));
|
||||
CHECK(configure_zone(config, zconfig, vconfig, mctx, view,
|
||||
&named_g_server->viewlist,
|
||||
&named_g_server->kasplist, actx, true,
|
||||
false, false));
|
||||
}
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
|
|
@ -7753,8 +7765,9 @@ configure_newzone(const cfg_obj_t *zconfig, cfg_obj_t *config,
|
|||
cfg_aclconfctx_t *actx)
|
||||
{
|
||||
return (configure_zone(config, zconfig, vconfig, mctx, view,
|
||||
&named_g_server->viewlist, actx, true,
|
||||
false, false));
|
||||
&named_g_server->viewlist,
|
||||
&named_g_server->kasplist, actx, true, false,
|
||||
false));
|
||||
}
|
||||
|
||||
/*%
|
||||
|
|
@ -7989,9 +8002,13 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
const cfg_obj_t *obj;
|
||||
const cfg_obj_t *options;
|
||||
const cfg_obj_t *usev4ports, *avoidv4ports, *usev6ports, *avoidv6ports;
|
||||
const cfg_obj_t *kasps;
|
||||
dns_kasp_t *kasp = NULL;
|
||||
dns_kasp_t *kasp_next = NULL;
|
||||
dns_kasplist_t tmpkasplist, kasplist;
|
||||
const cfg_obj_t *views;
|
||||
dns_view_t *view = NULL;
|
||||
dns_view_t *view_next;
|
||||
dns_view_t *view_next = NULL;
|
||||
dns_viewlist_t tmpviewlist;
|
||||
dns_viewlist_t viewlist, builtin_viewlist;
|
||||
in_port_t listen_port, udpport_low, udpport_high;
|
||||
|
|
@ -8020,6 +8037,7 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
dns_aclenv_t *env =
|
||||
ns_interfacemgr_getaclenv(named_g_server->interfacemgr);
|
||||
|
||||
ISC_LIST_INIT(kasplist);
|
||||
ISC_LIST_INIT(viewlist);
|
||||
ISC_LIST_INIT(builtin_viewlist);
|
||||
ISC_LIST_INIT(cachelist);
|
||||
|
|
@ -8560,7 +8578,7 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
obj = NULL;
|
||||
result = named_config_get(maps, "interface-interval", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
interface_interval = cfg_obj_asuint32(obj) * 60;
|
||||
interface_interval = cfg_obj_asduration(obj);
|
||||
if (interface_interval == 0) {
|
||||
CHECK(isc_timer_reset(server->interface_timer,
|
||||
isc_timertype_inactive,
|
||||
|
|
@ -8634,6 +8652,39 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
*/
|
||||
(void)configure_session_key(maps, server, named_g_mctx);
|
||||
|
||||
/*
|
||||
* Create the DNSSEC key and signing policies (KASP).
|
||||
*/
|
||||
kasps = NULL;
|
||||
(void)cfg_map_get(config, "dnssec-policy", &kasps);
|
||||
for (element = cfg_list_first(kasps);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
cfg_obj_t *kconfig = cfg_listelt_value(element);
|
||||
kasp = NULL;
|
||||
CHECK(cfg_kasp_fromconfig(kconfig, named_g_mctx, &kasplist,
|
||||
&kasp));
|
||||
INSIST(kasp != NULL);
|
||||
dns_kasp_freeze(kasp);
|
||||
dns_kasp_detach(&kasp);
|
||||
}
|
||||
/*
|
||||
* Create the default kasp.
|
||||
*/
|
||||
kasp = NULL;
|
||||
CHECK(cfg_kasp_fromconfig(NULL, named_g_mctx, &kasplist, &kasp));
|
||||
INSIST(kasp != NULL);
|
||||
dns_kasp_freeze(kasp);
|
||||
dns_kasp_detach(&kasp);
|
||||
|
||||
tmpkasplist = server->kasplist;
|
||||
server->kasplist = kasplist;
|
||||
kasplist = tmpkasplist;
|
||||
|
||||
/*
|
||||
* Configure the views.
|
||||
*/
|
||||
views = NULL;
|
||||
(void)cfg_map_get(config, "view", &views);
|
||||
|
||||
|
|
@ -8712,8 +8763,8 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
view = NULL;
|
||||
CHECK(find_view(vconfig, &viewlist, &view));
|
||||
CHECK(configure_view(view, &viewlist, config, vconfig,
|
||||
&cachelist, bindkeys, named_g_mctx,
|
||||
named_g_aclconfctx, true));
|
||||
&cachelist, &server->kasplist, bindkeys,
|
||||
named_g_mctx, named_g_aclconfctx, true));
|
||||
dns_view_freeze(view);
|
||||
dns_view_detach(&view);
|
||||
}
|
||||
|
|
@ -8726,9 +8777,8 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
view = NULL;
|
||||
CHECK(find_view(NULL, &viewlist, &view));
|
||||
CHECK(configure_view(view, &viewlist, config, NULL,
|
||||
&cachelist, bindkeys,
|
||||
named_g_mctx, named_g_aclconfctx,
|
||||
true));
|
||||
&cachelist, &server->kasplist, bindkeys,
|
||||
named_g_mctx, named_g_aclconfctx, true));
|
||||
dns_view_freeze(view);
|
||||
dns_view_detach(&view);
|
||||
}
|
||||
|
|
@ -8747,9 +8797,8 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
|
||||
CHECK(create_view(vconfig, &builtin_viewlist, &view));
|
||||
CHECK(configure_view(view, &viewlist, config, vconfig,
|
||||
&cachelist, bindkeys,
|
||||
named_g_mctx, named_g_aclconfctx,
|
||||
false));
|
||||
&cachelist, &server->kasplist, bindkeys,
|
||||
named_g_mctx, named_g_aclconfctx, false));
|
||||
dns_view_freeze(view);
|
||||
dns_view_detach(&view);
|
||||
view = NULL;
|
||||
|
|
@ -9185,6 +9234,10 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
dns_view_detach(&view);
|
||||
}
|
||||
|
||||
if (kasp != NULL) {
|
||||
dns_kasp_detach(&kasp);
|
||||
}
|
||||
|
||||
ISC_LIST_APPENDLIST(viewlist, builtin_viewlist, link);
|
||||
|
||||
/*
|
||||
|
|
@ -9207,6 +9260,15 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
dns_view_detach(&view);
|
||||
}
|
||||
|
||||
/*
|
||||
* Same cleanup for kasp list.
|
||||
*/
|
||||
for (kasp = ISC_LIST_HEAD(kasplist); kasp != NULL; kasp = kasp_next) {
|
||||
kasp_next = ISC_LIST_NEXT(kasp, link);
|
||||
ISC_LIST_UNLINK(kasplist, kasp, link);
|
||||
dns_kasp_detach(&kasp);
|
||||
}
|
||||
|
||||
/* Same cleanup for cache list. */
|
||||
while ((nsc = ISC_LIST_HEAD(cachelist)) != NULL) {
|
||||
ISC_LIST_UNLINK(cachelist, nsc, link);
|
||||
|
|
@ -9454,7 +9516,8 @@ named_server_flushonshutdown(named_server_t *server, bool flush) {
|
|||
static void
|
||||
shutdown_server(isc_task_t *task, isc_event_t *event) {
|
||||
isc_result_t result;
|
||||
dns_view_t *view, *view_next;
|
||||
dns_view_t *view, *view_next = NULL;
|
||||
dns_kasp_t *kasp, *kasp_next = NULL;
|
||||
named_server_t *server = (named_server_t *)event->ev_arg;
|
||||
bool flush = server->flushonshutdown;
|
||||
named_cache_t *nsc;
|
||||
|
|
@ -9484,9 +9547,17 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
(void) named_server_saventa(server);
|
||||
|
||||
for (view = ISC_LIST_HEAD(server->viewlist);
|
||||
view != NULL;
|
||||
view = view_next) {
|
||||
for (kasp = ISC_LIST_HEAD(server->kasplist); kasp != NULL;
|
||||
kasp = kasp_next)
|
||||
{
|
||||
kasp_next = ISC_LIST_NEXT(kasp, link);
|
||||
ISC_LIST_UNLINK(server->kasplist, kasp, link);
|
||||
dns_kasp_detach(&kasp);
|
||||
}
|
||||
|
||||
for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
|
||||
view = view_next)
|
||||
{
|
||||
view_next = ISC_LIST_NEXT(view, link);
|
||||
ISC_LIST_UNLINK(server->viewlist, view, link);
|
||||
if (flush)
|
||||
|
|
@ -9604,6 +9675,7 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
|
|||
|
||||
/* Initialize server data structures. */
|
||||
server->interfacemgr = NULL;
|
||||
ISC_LIST_INIT(server->kasplist);
|
||||
ISC_LIST_INIT(server->viewlist);
|
||||
server->in_roothints = NULL;
|
||||
|
||||
|
|
@ -9791,6 +9863,7 @@ named_server_destroy(named_server_t **serverp) {
|
|||
|
||||
isc_event_free(&server->reload_event);
|
||||
|
||||
INSIST(ISC_LIST_EMPTY(server->kasplist));
|
||||
INSIST(ISC_LIST_EMPTY(server->viewlist));
|
||||
INSIST(ISC_LIST_EMPTY(server->cachelist));
|
||||
|
||||
|
|
@ -11760,7 +11833,10 @@ named_server_rekey(named_server_t *server, isc_lex_t *lex,
|
|||
|
||||
keyopts = dns_zone_getkeyopts(zone);
|
||||
|
||||
/* "rndc loadkeys" requires "auto-dnssec maintain". */
|
||||
/*
|
||||
* "rndc loadkeys" requires "auto-dnssec maintain"
|
||||
* or a "dnssec-policy".
|
||||
*/
|
||||
if ((keyopts & DNS_ZONEKEY_ALLOW) == 0)
|
||||
result = ISC_R_NOPERM;
|
||||
else if ((keyopts & DNS_ZONEKEY_MAINTAIN) == 0 && !fullsign)
|
||||
|
|
@ -12925,7 +13001,8 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
|
|||
dns_view_thaw(view);
|
||||
result = configure_zone(cfg->config, zoneobj, cfg->vconfig,
|
||||
server->mctx, view, &server->viewlist,
|
||||
cfg->actx, true, false, false);
|
||||
&server->kasplist, cfg->actx, true, false,
|
||||
false);
|
||||
dns_view_freeze(view);
|
||||
|
||||
isc_task_endexclusive(server->task);
|
||||
|
|
@ -13103,7 +13180,8 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
|
|||
dns_view_thaw(view);
|
||||
result = configure_zone(cfg->config, zoneobj, cfg->vconfig,
|
||||
server->mctx, view, &server->viewlist,
|
||||
cfg->actx, true, false, true);
|
||||
&server->kasplist, cfg->actx, true, false,
|
||||
true);
|
||||
dns_view_freeze(view);
|
||||
|
||||
exclusive = false;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <dns/ipkeylist.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/journal.h>
|
||||
#include <dns/kasp.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/name.h>
|
||||
#include <dns/masterdump.h>
|
||||
|
|
@ -840,8 +841,9 @@ process_notifytype(dns_notifytype_t ntype, dns_zonetype_t ztype,
|
|||
|
||||
isc_result_t
|
||||
named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac,
|
||||
dns_zone_t *zone, dns_zone_t *raw)
|
||||
const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac,
|
||||
dns_kasplist_t *kasplist, dns_zone_t *zone,
|
||||
dns_zone_t *raw)
|
||||
{
|
||||
isc_result_t result;
|
||||
const char *zname;
|
||||
|
|
@ -853,6 +855,7 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||
const cfg_obj_t *options = NULL;
|
||||
const cfg_obj_t *obj;
|
||||
const char *filename = NULL;
|
||||
const char *kaspname = NULL;
|
||||
const char *dupcheck;
|
||||
dns_notifytype_t notifytype = dns_notifytype_yes;
|
||||
uint32_t count;
|
||||
|
|
@ -868,7 +871,8 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||
int32_t journal_size;
|
||||
bool multi;
|
||||
bool alt;
|
||||
dns_view_t *view;
|
||||
dns_view_t *view = NULL;
|
||||
dns_kasp_t *kasp = NULL;
|
||||
bool check = false, fail = false;
|
||||
bool warn = false, ignore = false;
|
||||
bool ixfrdiff;
|
||||
|
|
@ -1045,8 +1049,8 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||
} else if (result == ISC_R_SUCCESS) {
|
||||
dns_ttl_t maxttl = 0; /* unlimited */
|
||||
|
||||
if (cfg_obj_isuint32(obj))
|
||||
maxttl = cfg_obj_asuint32(obj);
|
||||
if (cfg_obj_isduration(obj))
|
||||
maxttl = cfg_obj_asduration(obj);
|
||||
dns_zone_setmaxttl(zone, maxttl);
|
||||
if (raw != NULL)
|
||||
dns_zone_setmaxttl(raw, maxttl);
|
||||
|
|
@ -1192,6 +1196,24 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||
*/
|
||||
if (ztype != dns_zone_stub && ztype != dns_zone_staticstub &&
|
||||
ztype != dns_zone_redirect) {
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "dnssec-policy", &obj);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
kaspname = cfg_obj_asstring(obj);
|
||||
if (strcmp(kaspname, "none") != 0) {
|
||||
result = dns_kasplist_find(kasplist, kaspname,
|
||||
&kasp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(obj, named_g_lctx,
|
||||
ISC_LOG_ERROR,
|
||||
"'dnssec-policy '%s' not "
|
||||
"found ", kaspname);
|
||||
RETERR(result);
|
||||
}
|
||||
dns_zone_setkasp(zone, kasp);
|
||||
}
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "notify", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
|
|
@ -1481,38 +1503,52 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||
bool allow = false, maint = false;
|
||||
bool sigvalinsecs;
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "dnskey-sig-validity", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
seconds = cfg_obj_asuint32(obj) * 86400;
|
||||
if (kasp) {
|
||||
seconds = (uint32_t) dns_kasp_sigvalidity_dnskey(kasp);
|
||||
} else {
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "dnskey-sig-validity",
|
||||
&obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
seconds = cfg_obj_asuint32(obj) * 86400;
|
||||
}
|
||||
dns_zone_setkeyvalidityinterval(zone, seconds);
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "sig-validity-interval", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
|
||||
sigvalinsecs = ns_server_getoption(named_g_server->sctx,
|
||||
NS_SERVER_SIGVALINSECS);
|
||||
validity = cfg_tuple_get(obj, "validity");
|
||||
seconds = cfg_obj_asuint32(validity);
|
||||
if (!sigvalinsecs) {
|
||||
seconds *= 86400;
|
||||
}
|
||||
dns_zone_setsigvalidityinterval(zone, seconds);
|
||||
|
||||
resign = cfg_tuple_get(obj, "re-sign");
|
||||
if (cfg_obj_isvoid(resign)) {
|
||||
seconds /= 4;
|
||||
} else if (!sigvalinsecs) {
|
||||
if (seconds > 7 * 86400) {
|
||||
seconds = cfg_obj_asuint32(resign) * 86400;
|
||||
} else {
|
||||
seconds = cfg_obj_asuint32(resign) * 3600;
|
||||
}
|
||||
if (kasp) {
|
||||
seconds = (uint32_t) dns_kasp_sigvalidity(kasp);
|
||||
dns_zone_setsigvalidityinterval(zone, seconds);
|
||||
seconds = (uint32_t) dns_kasp_sigrefresh(kasp);
|
||||
dns_zone_setsigresigninginterval(zone, seconds);
|
||||
} else {
|
||||
seconds = cfg_obj_asuint32(resign);
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "sig-validity-interval",
|
||||
&obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
|
||||
sigvalinsecs = ns_server_getoption(named_g_server->sctx,
|
||||
NS_SERVER_SIGVALINSECS);
|
||||
validity = cfg_tuple_get(obj, "validity");
|
||||
seconds = cfg_obj_asuint32(validity);
|
||||
if (!sigvalinsecs) {
|
||||
seconds *= 86400;
|
||||
}
|
||||
dns_zone_setsigvalidityinterval(zone, seconds);
|
||||
|
||||
resign = cfg_tuple_get(obj, "re-sign");
|
||||
if (cfg_obj_isvoid(resign)) {
|
||||
seconds /= 4;
|
||||
} else if (!sigvalinsecs) {
|
||||
seconds = cfg_obj_asuint32(resign);
|
||||
if (seconds > 7 * 86400) {
|
||||
seconds *= 86400;
|
||||
} else {
|
||||
seconds *= 3600;
|
||||
}
|
||||
} else {
|
||||
seconds = cfg_obj_asuint32(resign);
|
||||
}
|
||||
dns_zone_setsigresigninginterval(zone, seconds);
|
||||
}
|
||||
dns_zone_setsigresigninginterval(zone, seconds);
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "key-directory", &obj);
|
||||
|
|
@ -1541,12 +1577,20 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
dns_zone_setoption(zone, DNS_ZONEOPT_UPDATECHECKKSK,
|
||||
cfg_obj_asboolean(obj));
|
||||
/*
|
||||
* This setting will be ignored if dnssec-policy is used.
|
||||
* named-checkconf will error if both are configured.
|
||||
*/
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "dnssec-dnskey-kskonly", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
dns_zone_setoption(zone, DNS_ZONEOPT_DNSKEYKSKONLY,
|
||||
cfg_obj_asboolean(obj));
|
||||
/*
|
||||
* This setting will be ignored if dnssec-policy is used.
|
||||
* named-checkconf will error if both are configured.
|
||||
*/
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "dnssec-loadkeys-interval",
|
||||
|
|
@ -1557,7 +1601,11 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||
|
||||
obj = NULL;
|
||||
result = cfg_map_get(zoptions, "auto-dnssec", &obj);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (dns_zone_getkasp(zone) != NULL) {
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, true);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_CREATE, true);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, true);
|
||||
} else if (result == ISC_R_SUCCESS) {
|
||||
const char *arg = cfg_obj_asstring(obj);
|
||||
if (strcasecmp(arg, "allow") == 0) {
|
||||
allow = true;
|
||||
|
|
@ -1570,6 +1618,7 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
|||
ISC_UNREACHABLE();
|
||||
}
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_CREATE, false);
|
||||
dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -443,7 +443,8 @@
|
|||
allowed to incrementally re-sign over time.
|
||||
</para>
|
||||
<para>
|
||||
This command requires that the
|
||||
This command requires that the zone is configured with a
|
||||
<command>dnssec-policy</command>, or that the
|
||||
<command>auto-dnssec</command> zone option
|
||||
be set to <literal>maintain</literal>,
|
||||
and also requires the zone to be configured to
|
||||
|
|
@ -849,7 +850,8 @@
|
|||
re-signed with the new key set.
|
||||
</para>
|
||||
<para>
|
||||
This command requires that the
|
||||
This command requires that the zone is configured with a
|
||||
<command>dnssec-policy</command>, or that the
|
||||
<command>auto-dnssec</command> zone option be set
|
||||
to <literal>allow</literal> or
|
||||
<literal>maintain</literal>,
|
||||
|
|
|
|||
22
bin/tests/system/checkconf/bad-kasp1.conf
Normal file
22
bin/tests/system/checkconf/bad-kasp1.conf
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Using the keyword 'default' is not allowed.
|
||||
dnssec-policy "default" {
|
||||
signatures-refresh P5D;
|
||||
};
|
||||
|
||||
zone "example.net" {
|
||||
type master;
|
||||
file "example.db";
|
||||
dnssec-policy "default";
|
||||
};
|
||||
|
||||
22
bin/tests/system/checkconf/bad-kasp2.conf
Normal file
22
bin/tests/system/checkconf/bad-kasp2.conf
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
include "good-kasp.conf";
|
||||
|
||||
// Bad zone configuration because this has dnssec-policy and other DNSSEC sign
|
||||
// configuration options (auto-dnssec).
|
||||
zone "example.net" {
|
||||
type master;
|
||||
file "example.db";
|
||||
dnssec-policy "test";
|
||||
auto-dnssec maintain;
|
||||
allow-update { any; };
|
||||
};
|
||||
22
bin/tests/system/checkconf/bad-kasp3.conf
Normal file
22
bin/tests/system/checkconf/bad-kasp3.conf
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
include "good-kasp.conf";
|
||||
|
||||
// Bad zone configuration because this has dnssec-policy with no matching
|
||||
// dnssec-policy configuration (good-kasp.conf has "test", zone refers to
|
||||
// "nosuchpolicy".
|
||||
zone "example.net" {
|
||||
type master;
|
||||
file "example.db";
|
||||
dnssec-policy "nosuchpolicy";
|
||||
};
|
||||
|
||||
23
bin/tests/system/checkconf/bad-kasp4.conf
Normal file
23
bin/tests/system/checkconf/bad-kasp4.conf
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Bad kasp configuration because this has an invalid duration for
|
||||
// signatures-refresh.
|
||||
dnssec-policy "badduration" {
|
||||
signatures-refresh PT20Sabcd;
|
||||
};
|
||||
|
||||
zone "example.net" {
|
||||
type master;
|
||||
file "example.db";
|
||||
dnssec-policy "badduration";
|
||||
};
|
||||
|
||||
22
bin/tests/system/checkconf/bad-kasp5.conf
Normal file
22
bin/tests/system/checkconf/bad-kasp5.conf
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Using the keyword 'none' is not allowed.
|
||||
dnssec-policy "none" {
|
||||
signatures-refresh P5D;
|
||||
};
|
||||
|
||||
zone "example.net" {
|
||||
type master;
|
||||
file "example.db";
|
||||
dnssec-policy "none";
|
||||
};
|
||||
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
# information regarding copyright ownership.
|
||||
|
||||
rm -f good.conf.in good.conf.out badzero.conf *.out
|
||||
rm -f good-kasp.conf.in
|
||||
rm -rf test.keydir
|
||||
rm -f checkconf.out*
|
||||
rm -f diff.out*
|
||||
|
|
|
|||
56
bin/tests/system/checkconf/good-kasp.conf
Normal file
56
bin/tests/system/checkconf/good-kasp.conf
Normal 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is just a random selection of DNSSEC configuration options.
|
||||
*/
|
||||
|
||||
/* cut here */
|
||||
dnssec-policy "test" {
|
||||
dnskey-ttl 3600;
|
||||
keys {
|
||||
ksk key-directory lifetime P1Y algorithm 13 256;
|
||||
zsk key-directory lifetime P30D algorithm 13;
|
||||
csk key-directory lifetime P30D algorithm 8 2048;
|
||||
};
|
||||
publish-safety PT3600S;
|
||||
retire-safety PT3600S;
|
||||
signatures-refresh P3D;
|
||||
signatures-validity P2W;
|
||||
signatures-validity-dnskey P14D;
|
||||
zone-max-ttl 86400;
|
||||
zone-propagation-delay PT5M;
|
||||
parent-ds-ttl 7200;
|
||||
parent-propagation-delay PT1H;
|
||||
parent-registration-delay P1D;
|
||||
};
|
||||
options {
|
||||
dnssec-policy "default";
|
||||
};
|
||||
zone "example1" {
|
||||
type master;
|
||||
file "example1.db";
|
||||
};
|
||||
zone "example2" {
|
||||
type master;
|
||||
file "example2.db";
|
||||
dnssec-policy "test";
|
||||
};
|
||||
zone "example3" {
|
||||
type master;
|
||||
file "example3.db";
|
||||
dnssec-policy "default";
|
||||
};
|
||||
zone "example4" {
|
||||
type master;
|
||||
file "example4.db";
|
||||
dnssec-policy "none";
|
||||
};
|
||||
|
|
@ -14,6 +14,24 @@
|
|||
*/
|
||||
|
||||
/* cut here */
|
||||
dnssec-policy "test" {
|
||||
dnskey-ttl 3600;
|
||||
keys {
|
||||
ksk key-directory lifetime P1Y algorithm 13 256;
|
||||
zsk key-directory lifetime P30D algorithm 13;
|
||||
csk key-directory lifetime P30D algorithm 8 2048;
|
||||
};
|
||||
publish-safety PT3600S;
|
||||
retire-safety PT3600S;
|
||||
signatures-refresh P3D;
|
||||
signatures-validity P2W;
|
||||
signatures-validity-dnskey P14D;
|
||||
zone-max-ttl 86400;
|
||||
zone-propagation-delay PT5M;
|
||||
parent-ds-ttl 7200;
|
||||
parent-propagation-delay PT1H;
|
||||
parent-registration-delay P1D;
|
||||
};
|
||||
options {
|
||||
avoid-v4-udp-ports {
|
||||
100;
|
||||
|
|
@ -60,6 +78,7 @@ options {
|
|||
validate-except {
|
||||
"corp";
|
||||
};
|
||||
dnssec-policy "test";
|
||||
transfer-source 0.0.0.0 dscp 63;
|
||||
zone-statistics none;
|
||||
};
|
||||
|
|
@ -140,6 +159,28 @@ view "third" {
|
|||
};
|
||||
};
|
||||
};
|
||||
view "fourth" {
|
||||
zone "dnssec-test" {
|
||||
type master;
|
||||
file "dnssec-test.db";
|
||||
dnssec-policy "test";
|
||||
};
|
||||
zone "dnssec-default" {
|
||||
type master;
|
||||
file "dnssec-default.db";
|
||||
dnssec-policy "default";
|
||||
};
|
||||
zone "dnssec-inherit" {
|
||||
type master;
|
||||
file "dnssec-inherit.db";
|
||||
};
|
||||
zone "dnssec-none" {
|
||||
type master;
|
||||
file "dnssec-none.db";
|
||||
dnssec-policy "none";
|
||||
};
|
||||
dnssec-policy "default";
|
||||
};
|
||||
view "chaos" chaos {
|
||||
zone "hostname.bind" chaos {
|
||||
type master;
|
||||
|
|
|
|||
|
|
@ -8,4 +8,8 @@ clone IN third in-view first
|
|||
dnssec IN third master
|
||||
p IN third primary
|
||||
s IN third secondary
|
||||
dnssec-test IN fourth master
|
||||
dnssec-default IN fourth master
|
||||
dnssec-inherit IN fourth master
|
||||
dnssec-none IN fourth master
|
||||
hostname.bind chaos chaos master
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
include "good-kasp.conf";
|
||||
|
||||
zone "nsec3.net" {
|
||||
type master;
|
||||
file "nsec3.db";
|
||||
dnssec-policy "test";
|
||||
auto-dnssec maintain;
|
||||
dnskey-sig-validity 3600;
|
||||
dnssec-dnskey-kskonly yes;
|
||||
dnssec-secure-to-insecure yes;
|
||||
dnssec-update-mode maintain;
|
||||
inline-signing yes;
|
||||
sig-validity-interval 3600;
|
||||
update-check-ksk yes;
|
||||
allow-update { any; };
|
||||
};
|
||||
|
||||
|
|
@ -466,5 +466,38 @@ grep "'geoip-use-ecs' is obsolete" < checkconf.out$n > /dev/null || ret=1
|
|||
if [ $ret != 0 ]; then echo_i "failed"; ret=1; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "checking named-checkconf kasp warnings ($n)"
|
||||
ret=0
|
||||
$CHECKCONF kasp-and-other-dnssec-options.conf > checkconf.out$n 2>&1
|
||||
grep "'auto-dnssec maintain;' cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1
|
||||
grep "dnskey-sig-validity: cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1
|
||||
grep "dnssec-dnskey-kskonly: cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1
|
||||
grep "dnssec-secure-to-insecure: cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1
|
||||
grep "dnssec-update-mode: cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1
|
||||
grep "inline-signing: cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1
|
||||
grep "sig-validity-interval: cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1
|
||||
grep "update-check-ksk: cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "check that a good 'kasp' configuration is accepted ($n)"
|
||||
ret=0
|
||||
$CHECKCONF good-kasp.conf > checkconf.out$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 named-checkconf prints a known good kasp config ($n)"
|
||||
ret=0
|
||||
awk 'BEGIN { ok = 0; } /cut here/ { ok = 1; getline } ok == 1 { print }' good-kasp.conf > good-kasp.conf.in
|
||||
[ -s good-kasp.conf.in ] || ret=1
|
||||
$CHECKCONF -p good-kasp.conf.in | grep -v '^good-kasp.conf.in:' > good-kasp.conf.out 2>&1 || ret=1
|
||||
cmp good-kasp.conf.in good-kasp.conf.out || ret=1
|
||||
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
|
|
|
|||
|
|
@ -1485,7 +1485,7 @@ n=$((n+1))
|
|||
test "$ret" -eq 0 || echo_i "failed"
|
||||
status=$((status+ret))
|
||||
|
||||
echo_i "checking that dnsssec-signzone updates originalttl on ttl changes ($n)"
|
||||
echo_i "checking that dnssec-signzone updates originalttl on ttl changes ($n)"
|
||||
ret=0
|
||||
zone=example
|
||||
key1=$($KEYGEN -K signer -q -a RSASHA1 -b 1024 -n zone $zone)
|
||||
|
|
|
|||
13
bin/tests/system/kasp/README
Normal file
13
bin/tests/system/kasp/README
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
|
||||
See COPYRIGHT in the source root or http://isc.org/copyright.html for terms.
|
||||
|
||||
The test setup for the KASP tests.
|
||||
|
||||
ns1 is reserved for the root server.
|
||||
|
||||
ns2 is running primary service for ns3.
|
||||
|
||||
ns3 is an authoritative server for the various test domains.
|
||||
|
||||
ns4 and ns5 are authoritative servers for various test domains related to views.
|
||||
26
bin/tests/system/kasp/clean.sh
Normal file
26
bin/tests/system/kasp/clean.sh
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
rm -f ./keygen.*
|
||||
rm -f ./K*.private ./K*.key ./K*.state ./K*.cmp
|
||||
rm -rf ./keys/
|
||||
rm -f dig.out* rrsig.out.* keyevent.out.*
|
||||
rm -f ns*/named.conf ns*/named.memstats ns*/named.run*
|
||||
rm -f ns*/*.jnl ns*/*.jbk
|
||||
rm -f ns*/K*.private ns*/K*.key ns*/K*.state
|
||||
rm -f ns*/dsset-* ns*/*.db ns*/*.db.signed
|
||||
rm -f ns*/keygen.out.* ns*/settime.out.* ns*/signer.out.*
|
||||
rm -f ns*/managed-keys.bind
|
||||
rm -f ns*/*.mkeys
|
||||
# NS3 specific
|
||||
rm -f ns3/zones ns3/*.db.infile
|
||||
25
bin/tests/system/kasp/kasp.conf
Normal file
25
bin/tests/system/kasp/kasp.conf
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is just a random selection of configuration options.
|
||||
*/
|
||||
|
||||
dnssec-policy "kasp" {
|
||||
dnskey-ttl 200;
|
||||
|
||||
keys {
|
||||
csk key-directory lifetime P1Y algorithm 13;
|
||||
ksk key-directory lifetime P1Y algorithm 8;
|
||||
zsk key-directory lifetime P30D algorithm 8 1024;
|
||||
zsk key-directory lifetime P6M algorithm 8 2000;
|
||||
};
|
||||
};
|
||||
58
bin/tests/system/kasp/ns2/named.conf.in
Normal file
58
bin/tests/system/kasp/ns2/named.conf.in
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// NS2
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.2;
|
||||
notify-source 10.53.0.2;
|
||||
transfer-source 10.53.0.2;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.2; };
|
||||
listen-on-v6 { none; };
|
||||
allow-transfer { any; };
|
||||
recursion no;
|
||||
dnssec-policy "none";
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
/* Inherit dnssec-policy (which is none) */
|
||||
|
||||
zone "unsigned.tld" {
|
||||
type master;
|
||||
file "unsigned.tld.db";
|
||||
};
|
||||
|
||||
/* Override dnssec-policy */
|
||||
|
||||
zone "signed.tld" {
|
||||
type master;
|
||||
dnssec-policy "default";
|
||||
file "signed.tld.db";
|
||||
};
|
||||
|
||||
/* Primary service for ns3 */
|
||||
|
||||
zone "secondary.kasp" {
|
||||
type master;
|
||||
file "secondary.kasp.db";
|
||||
allow-transfer { 10.53.0.3; };
|
||||
notify yes;
|
||||
};
|
||||
27
bin/tests/system/kasp/ns2/secondary.kasp.db.in
Normal file
27
bin/tests/system/kasp/ns2/secondary.kasp.db.in
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
; 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.
|
||||
|
||||
$TTL 300
|
||||
@ IN SOA secondary.kasp. hostmaster.kasp. (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
NS ns2
|
||||
NS ns3
|
||||
ns2 A 10.53.0.2
|
||||
ns3 A 10.53.0.3
|
||||
|
||||
a A 10.0.0.1
|
||||
b A 10.0.0.2
|
||||
c A 10.0.0.3
|
||||
|
||||
28
bin/tests/system/kasp/ns2/secondary.kasp.db.in2
Normal file
28
bin/tests/system/kasp/ns2/secondary.kasp.db.in2
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
; 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.
|
||||
|
||||
$TTL 300
|
||||
@ IN SOA secondary.kasp. hostmaster.kasp. (
|
||||
2 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
NS ns2
|
||||
NS ns3
|
||||
ns2 A 10.53.0.2
|
||||
ns3 A 10.53.0.3
|
||||
|
||||
a A 10.0.0.11
|
||||
b A 10.0.0.2
|
||||
c A 10.0.0.3
|
||||
d A 10.0.0.4
|
||||
|
||||
33
bin/tests/system/kasp/ns2/setup.sh
Normal file
33
bin/tests/system/kasp/ns2/setup.sh
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# 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.
|
||||
|
||||
# shellcheck source=conf.sh
|
||||
. "$SYSTEMTESTTOP/conf.sh"
|
||||
|
||||
echo_i "ns2/setup.sh"
|
||||
|
||||
zone="secondary.kasp"
|
||||
echo_i "setting up zone: $zone"
|
||||
zonefile="${zone}.db"
|
||||
infile="${zonefile}.in"
|
||||
cp $infile $zonefile
|
||||
|
||||
zone="signed.tld"
|
||||
echo_i "setting up zone: $zone"
|
||||
zonefile="${zone}.db"
|
||||
infile="template.tld.db.in"
|
||||
cp $infile $zonefile
|
||||
|
||||
zone="unsigned.tld"
|
||||
echo_i "setting up zone: $zone"
|
||||
zonefile="${zone}.db"
|
||||
infile="template.tld.db.in"
|
||||
cp $infile $zonefile
|
||||
25
bin/tests/system/kasp/ns2/template.tld.db.in
Normal file
25
bin/tests/system/kasp/ns2/template.tld.db.in
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
; 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.
|
||||
|
||||
$TTL 300
|
||||
@ IN SOA secondary.kasp. hostmaster.kasp. (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
NS ns2
|
||||
ns2 A 10.53.0.2
|
||||
|
||||
a A 10.0.0.1
|
||||
b A 10.0.0.2
|
||||
c A 10.0.0.3
|
||||
|
||||
319
bin/tests/system/kasp/ns3/named.conf.in
Normal file
319
bin/tests/system/kasp/ns3/named.conf.in
Normal file
|
|
@ -0,0 +1,319 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// NS3
|
||||
|
||||
include "policies/kasp.conf";
|
||||
include "policies/autosign.conf";
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.3;
|
||||
notify-source 10.53.0.3;
|
||||
transfer-source 10.53.0.3;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.3; };
|
||||
listen-on-v6 { none; };
|
||||
allow-transfer { any; };
|
||||
recursion no;
|
||||
dnssec-policy "rsasha1";
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
/* Zones that are getting initially signed */
|
||||
|
||||
/* The default case: No keys created, using default policy. */
|
||||
zone "default.kasp" {
|
||||
type master;
|
||||
file "default.kasp.db";
|
||||
dnssec-policy "default";
|
||||
};
|
||||
|
||||
/* A master zone with dnssec-policy, no keys created. */
|
||||
zone "rsasha1.kasp" {
|
||||
type master;
|
||||
file "rsasha1.kasp.db";
|
||||
dnssec-policy "rsasha1";
|
||||
};
|
||||
|
||||
/* A zone that inherits dnssec-policy. */
|
||||
zone "inherit.kasp" {
|
||||
type master;
|
||||
file "inherit.kasp.db";
|
||||
};
|
||||
|
||||
/* A zone that overrides dnssec-policy. */
|
||||
zone "unsigned.kasp" {
|
||||
type master;
|
||||
file "unsigned.kasp.db";
|
||||
dnssec-policy "none";
|
||||
};
|
||||
|
||||
/* A master zone with dnssec-policy but keys already created. */
|
||||
zone "dnssec-keygen.kasp" {
|
||||
type master;
|
||||
file "dnssec-keygen.kasp.db";
|
||||
dnssec-policy "rsasha1";
|
||||
};
|
||||
|
||||
/* A secondary zone with dnssec-policy. */
|
||||
zone "secondary.kasp" {
|
||||
type secondary;
|
||||
masters { 10.53.0.2; };
|
||||
file "secondary.kasp.db";
|
||||
dnssec-policy "rsasha1";
|
||||
};
|
||||
|
||||
/*
|
||||
* A configured dnssec-policy but some keys already created.
|
||||
*/
|
||||
zone "some-keys.kasp" {
|
||||
type master;
|
||||
file "some-keys.kasp.db";
|
||||
dnssec-policy "rsasha1";
|
||||
};
|
||||
|
||||
/*
|
||||
* A configured dnssec-policy but some keys already in use.
|
||||
*/
|
||||
zone "legacy-keys.kasp" {
|
||||
type master;
|
||||
file "legacy-keys.kasp.db";
|
||||
dnssec-policy "rsasha1";
|
||||
};
|
||||
|
||||
/*
|
||||
* A configured dnssec-policy with (too) many keys pregenerated.
|
||||
*/
|
||||
zone "pregenerated.kasp" {
|
||||
type master;
|
||||
file "pregenerated.kasp.db";
|
||||
dnssec-policy "rsasha1";
|
||||
};
|
||||
|
||||
/*
|
||||
* Different algorithms.
|
||||
*/
|
||||
zone "rsasha1-nsec3.kasp" {
|
||||
type master;
|
||||
file "rsasha1-nsec3.kasp.db";
|
||||
dnssec-policy "rsasha1-nsec3";
|
||||
};
|
||||
zone "rsasha256.kasp" {
|
||||
type master;
|
||||
file "rsasha256.kasp.db";
|
||||
dnssec-policy "rsasha256";
|
||||
};
|
||||
zone "rsasha512.kasp" {
|
||||
type master;
|
||||
file "rsasha512.kasp.db";
|
||||
dnssec-policy "rsasha512";
|
||||
};
|
||||
zone "ecdsa256.kasp" {
|
||||
type master;
|
||||
file "ecdsa256.kasp.db";
|
||||
dnssec-policy "ecdsa256";
|
||||
};
|
||||
zone "ecdsa384.kasp" {
|
||||
type master;
|
||||
file "ecdsa384.kasp.db";
|
||||
dnssec-policy "ecdsa384";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zones in different signing states.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Zone that has expired signatures.
|
||||
*/
|
||||
zone "expired-sigs.autosign" {
|
||||
type master;
|
||||
file "expired-sigs.autosign.db";
|
||||
dnssec-policy "autosign";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zone that has valid, fresh signatures.
|
||||
*/
|
||||
zone "fresh-sigs.autosign" {
|
||||
type master;
|
||||
file "fresh-sigs.autosign.db";
|
||||
dnssec-policy "autosign";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zone that has unfresh signatures.
|
||||
*/
|
||||
zone "unfresh-sigs.autosign" {
|
||||
type master;
|
||||
file "unfresh-sigs.autosign.db";
|
||||
dnssec-policy "autosign";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zone that has missing private ZSK.
|
||||
*/
|
||||
zone "zsk-missing.autosign" {
|
||||
type master;
|
||||
file "zsk-missing.autosign.db";
|
||||
dnssec-policy "autosign";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zone that has inactive ZSK.
|
||||
*/
|
||||
zone "zsk-retired.autosign" {
|
||||
type master;
|
||||
file "zsk-retired.autosign.db";
|
||||
dnssec-policy "autosign";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zones for testing ZSK Pre-Publication steps.
|
||||
*/
|
||||
zone "step1.zsk-prepub.autosign" {
|
||||
type master;
|
||||
file "step1.zsk-prepub.autosign.db";
|
||||
dnssec-policy "zsk-prepub";
|
||||
};
|
||||
zone "step2.zsk-prepub.autosign" {
|
||||
type master;
|
||||
file "step2.zsk-prepub.autosign.db";
|
||||
dnssec-policy "zsk-prepub";
|
||||
};
|
||||
zone "step3.zsk-prepub.autosign" {
|
||||
type master;
|
||||
file "step3.zsk-prepub.autosign.db";
|
||||
dnssec-policy "zsk-prepub";
|
||||
};
|
||||
zone "step4.zsk-prepub.autosign" {
|
||||
type master;
|
||||
file "step4.zsk-prepub.autosign.db";
|
||||
dnssec-policy "zsk-prepub";
|
||||
};
|
||||
zone "step5.zsk-prepub.autosign" {
|
||||
type master;
|
||||
file "step5.zsk-prepub.autosign.db";
|
||||
dnssec-policy "zsk-prepub";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zones for testing KSK Double-KSK steps.
|
||||
*/
|
||||
zone "step1.ksk-doubleksk.autosign" {
|
||||
type master;
|
||||
file "step1.ksk-doubleksk.autosign.db";
|
||||
dnssec-policy "ksk-doubleksk";
|
||||
};
|
||||
zone "step2.ksk-doubleksk.autosign" {
|
||||
type master;
|
||||
file "step2.ksk-doubleksk.autosign.db";
|
||||
dnssec-policy "ksk-doubleksk";
|
||||
};
|
||||
zone "step3.ksk-doubleksk.autosign" {
|
||||
type master;
|
||||
file "step3.ksk-doubleksk.autosign.db";
|
||||
dnssec-policy "ksk-doubleksk";
|
||||
};
|
||||
zone "step4.ksk-doubleksk.autosign" {
|
||||
type master;
|
||||
file "step4.ksk-doubleksk.autosign.db";
|
||||
dnssec-policy "ksk-doubleksk";
|
||||
};
|
||||
zone "step5.ksk-doubleksk.autosign" {
|
||||
type master;
|
||||
file "step5.ksk-doubleksk.autosign.db";
|
||||
dnssec-policy "ksk-doubleksk";
|
||||
};
|
||||
zone "step6.ksk-doubleksk.autosign" {
|
||||
type master;
|
||||
file "step6.ksk-doubleksk.autosign.db";
|
||||
dnssec-policy "ksk-doubleksk";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zones for testing CSK rollover steps.
|
||||
*/
|
||||
zone "step1.csk-roll.autosign" {
|
||||
type master;
|
||||
file "step1.csk-roll.autosign.db";
|
||||
dnssec-policy "csk-roll";
|
||||
};
|
||||
zone "step2.csk-roll.autosign" {
|
||||
type master;
|
||||
file "step2.csk-roll.autosign.db";
|
||||
dnssec-policy "csk-roll";
|
||||
};
|
||||
zone "step3.csk-roll.autosign" {
|
||||
type master;
|
||||
file "step3.csk-roll.autosign.db";
|
||||
dnssec-policy "csk-roll";
|
||||
};
|
||||
zone "step4.csk-roll.autosign" {
|
||||
type master;
|
||||
file "step4.csk-roll.autosign.db";
|
||||
dnssec-policy "csk-roll";
|
||||
};
|
||||
zone "step5.csk-roll.autosign" {
|
||||
type master;
|
||||
file "step5.csk-roll.autosign.db";
|
||||
dnssec-policy "csk-roll";
|
||||
};
|
||||
zone "step6.csk-roll.autosign" {
|
||||
type master;
|
||||
file "step6.csk-roll.autosign.db";
|
||||
dnssec-policy "csk-roll";
|
||||
};
|
||||
zone "step7.csk-roll.autosign" {
|
||||
type master;
|
||||
file "step7.csk-roll.autosign.db";
|
||||
dnssec-policy "csk-roll";
|
||||
};
|
||||
|
||||
zone "step1.csk-roll2.autosign" {
|
||||
type master;
|
||||
file "step1.csk-roll2.autosign.db";
|
||||
dnssec-policy "csk-roll2";
|
||||
};
|
||||
zone "step2.csk-roll2.autosign" {
|
||||
type master;
|
||||
file "step2.csk-roll2.autosign.db";
|
||||
dnssec-policy "csk-roll2";
|
||||
};
|
||||
zone "step3.csk-roll2.autosign" {
|
||||
type master;
|
||||
file "step3.csk-roll2.autosign.db";
|
||||
dnssec-policy "csk-roll2";
|
||||
};
|
||||
zone "step4.csk-roll2.autosign" {
|
||||
type master;
|
||||
file "step4.csk-roll2.autosign.db";
|
||||
dnssec-policy "csk-roll2";
|
||||
};
|
||||
zone "step5.csk-roll2.autosign" {
|
||||
type master;
|
||||
file "step5.csk-roll2.autosign.db";
|
||||
dnssec-policy "csk-roll2";
|
||||
};
|
||||
zone "step6.csk-roll2.autosign" {
|
||||
type master;
|
||||
file "step6.csk-roll2.autosign.db";
|
||||
dnssec-policy "csk-roll2";
|
||||
};
|
||||
110
bin/tests/system/kasp/ns3/policies/autosign.conf
Normal file
110
bin/tests/system/kasp/ns3/policies/autosign.conf
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
dnssec-policy "autosign" {
|
||||
|
||||
signatures-refresh P1W;
|
||||
signatures-validity P2W;
|
||||
signatures-validity-dnskey P2W;
|
||||
|
||||
dnskey-ttl 300;
|
||||
|
||||
keys {
|
||||
ksk key-directory lifetime P2Y algorithm 13;
|
||||
zsk key-directory lifetime P1Y algorithm 13;
|
||||
};
|
||||
};
|
||||
|
||||
dnssec-policy "zsk-prepub" {
|
||||
|
||||
signatures-refresh P1W;
|
||||
signatures-validity P2W;
|
||||
signatures-validity-dnskey P2W;
|
||||
|
||||
dnskey-ttl 3600;
|
||||
publish-safety P1D;
|
||||
retire-safety P2D;
|
||||
|
||||
keys {
|
||||
ksk key-directory lifetime P2Y algorithm 13;
|
||||
zsk key-directory lifetime P30D algorithm 13;
|
||||
};
|
||||
|
||||
zone-propagation-delay PT1H;
|
||||
zone-max-ttl 1d;
|
||||
};
|
||||
|
||||
dnssec-policy "ksk-doubleksk" {
|
||||
|
||||
signatures-refresh P1W;
|
||||
signatures-validity P2W;
|
||||
signatures-validity-dnskey P2W;
|
||||
|
||||
dnskey-ttl 2h;
|
||||
publish-safety P1D;
|
||||
retire-safety P2D;
|
||||
|
||||
keys {
|
||||
ksk key-directory lifetime P60D algorithm 13;
|
||||
zsk key-directory lifetime P1Y algorithm 13;
|
||||
};
|
||||
|
||||
zone-propagation-delay PT1H;
|
||||
zone-max-ttl 1d;
|
||||
|
||||
parent-ds-ttl 3600;
|
||||
parent-registration-delay P1D;
|
||||
parent-propagation-delay PT1H;
|
||||
};
|
||||
|
||||
dnssec-policy "csk-roll" {
|
||||
|
||||
signatures-refresh P5D;
|
||||
signatures-validity 30d;
|
||||
signatures-validity-dnskey 30d;
|
||||
|
||||
dnskey-ttl 1h;
|
||||
publish-safety PT1H;
|
||||
retire-safety 2h;
|
||||
|
||||
keys {
|
||||
csk key-directory lifetime P6M algorithm 13;
|
||||
};
|
||||
|
||||
zone-propagation-delay 1h;
|
||||
zone-max-ttl P1D;
|
||||
|
||||
parent-ds-ttl 1h;
|
||||
parent-registration-delay 1d;
|
||||
parent-propagation-delay 1h;
|
||||
};
|
||||
|
||||
dnssec-policy "csk-roll2" {
|
||||
|
||||
signatures-refresh 12h;
|
||||
signatures-validity P1D;
|
||||
signatures-validity-dnskey P1D;
|
||||
|
||||
dnskey-ttl 1h;
|
||||
publish-safety PT1H;
|
||||
retire-safety 1h;
|
||||
|
||||
keys {
|
||||
csk key-directory lifetime P6M algorithm 13;
|
||||
};
|
||||
|
||||
zone-propagation-delay PT1H;
|
||||
zone-max-ttl 1d;
|
||||
|
||||
parent-ds-ttl PT1H;
|
||||
parent-registration-delay P1W;
|
||||
parent-propagation-delay PT1H;
|
||||
};
|
||||
70
bin/tests/system/kasp/ns3/policies/kasp.conf
Normal file
70
bin/tests/system/kasp/ns3/policies/kasp.conf
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
dnssec-policy "rsasha1" {
|
||||
dnskey-ttl 1234;
|
||||
|
||||
keys {
|
||||
ksk key-directory lifetime P10Y algorithm 5;
|
||||
zsk key-directory lifetime P5Y algorithm 5;
|
||||
zsk key-directory lifetime P1Y algorithm 5 2000;
|
||||
};
|
||||
};
|
||||
|
||||
dnssec-policy "rsasha1-nsec3" {
|
||||
dnskey-ttl 1234;
|
||||
|
||||
keys {
|
||||
ksk key-directory lifetime P10Y algorithm 7;
|
||||
zsk key-directory lifetime P5Y algorithm 7;
|
||||
zsk key-directory lifetime P1Y algorithm 7 2000;
|
||||
};
|
||||
};
|
||||
|
||||
dnssec-policy "rsasha256" {
|
||||
dnskey-ttl 1234;
|
||||
|
||||
keys {
|
||||
ksk key-directory lifetime P10Y algorithm 8;
|
||||
zsk key-directory lifetime P5Y algorithm 8;
|
||||
zsk key-directory lifetime P1Y algorithm 8 2000;
|
||||
};
|
||||
};
|
||||
|
||||
dnssec-policy "rsasha512" {
|
||||
dnskey-ttl 1234;
|
||||
|
||||
keys {
|
||||
ksk key-directory lifetime P10Y algorithm 10;
|
||||
zsk key-directory lifetime P5Y algorithm 10;
|
||||
zsk key-directory lifetime P1Y algorithm 10 2000;
|
||||
};
|
||||
};
|
||||
|
||||
dnssec-policy "ecdsa256" {
|
||||
dnskey-ttl 1234;
|
||||
|
||||
keys {
|
||||
ksk key-directory lifetime P10Y algorithm 13;
|
||||
zsk key-directory lifetime P5Y algorithm 13;
|
||||
zsk key-directory lifetime P1Y algorithm 13 256;
|
||||
};
|
||||
};
|
||||
|
||||
dnssec-policy "ecdsa384" {
|
||||
dnskey-ttl 1234;
|
||||
|
||||
keys {
|
||||
ksk key-directory lifetime P10Y algorithm 14;
|
||||
zsk key-directory lifetime P5Y algorithm 14;
|
||||
zsk key-directory lifetime P1Y algorithm 14 384;
|
||||
};
|
||||
};
|
||||
654
bin/tests/system/kasp/ns3/setup.sh
Normal file
654
bin/tests/system/kasp/ns3/setup.sh
Normal file
|
|
@ -0,0 +1,654 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# 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.
|
||||
|
||||
# shellcheck source=conf.sh
|
||||
. "$SYSTEMTESTTOP/conf.sh"
|
||||
|
||||
echo_i "ns3/setup.sh"
|
||||
|
||||
setup() {
|
||||
zone="$1"
|
||||
echo_i "setting up zone: $zone"
|
||||
zonefile="${zone}.db"
|
||||
infile="${zone}.db.infile"
|
||||
echo $zone >> zones
|
||||
}
|
||||
|
||||
private_type_record() {
|
||||
_zone=$1
|
||||
_algorithm=$2
|
||||
_keyfile=$3
|
||||
|
||||
_id=$(keyfile_to_key_id "$_keyfile")
|
||||
|
||||
printf "%s. 0 IN TYPE65534 \# 5 %02x%04x0000\n" $_zone $_algorithm $_id
|
||||
}
|
||||
|
||||
|
||||
# Make lines shorter by storing key states in environment variables.
|
||||
H="HIDDEN"
|
||||
R="RUMOURED"
|
||||
O="OMNIPRESENT"
|
||||
U="UNRETENTIVE"
|
||||
|
||||
#
|
||||
# Set up zones that will be initially signed.
|
||||
#
|
||||
for zn in default rsasha1 dnssec-keygen some-keys legacy-keys pregenerated \
|
||||
rsasha1-nsec3 rsasha256 rsasha512 ecdsa256 ecdsa384 inherit
|
||||
do
|
||||
setup "${zn}.kasp"
|
||||
cp template.db.in $zonefile
|
||||
done
|
||||
|
||||
# Set up zone that stays unsigned.
|
||||
zone="unsigned.kasp"
|
||||
echo_i "setting up zone: $zone"
|
||||
zonefile="${zone}.db"
|
||||
infile="${zone}.db.infile"
|
||||
cp template.db.in $zonefile
|
||||
|
||||
# Some of these zones already have keys.
|
||||
zone="dnssec-keygen.kasp"
|
||||
$KEYGEN -k rsasha1 -l policies/kasp.conf $zone > keygen.out.$zone.1 2>&1
|
||||
|
||||
zone="some-keys.kasp"
|
||||
$KEYGEN -P none -A none -a RSASHA1 -b 2000 -L 1234 $zone > keygen.out.$zone.1 2>&1
|
||||
$KEYGEN -P none -A none -a RSASHA1 -f KSK -L 1234 $zone > keygen.out.$zone.2 2>&1
|
||||
|
||||
zone="legacy.kasp"
|
||||
$KEYGEN -a RSASHA1 -b 2000 -L 1234 $zone > keygen.out.$zone.1 2>&1
|
||||
$KEYGEN -a RSASHA1 -f KSK -L 1234 $zone > keygen.out.$zone.2 2>&1
|
||||
|
||||
zone="pregenerated.kasp"
|
||||
$KEYGEN -k rsasha1 -l policies/kasp.conf $zone > keygen.out.$zone.1 2>&1
|
||||
$KEYGEN -k rsasha1 -l policies/kasp.conf $zone > keygen.out.$zone.2 2>&1
|
||||
|
||||
#
|
||||
# Set up zones that are already signed.
|
||||
#
|
||||
|
||||
# These signatures are set to expire long in the past, update immediately.
|
||||
setup expired-sigs.autosign
|
||||
KSK=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 300 $zone 2> keygen.out.$zone.1`
|
||||
ZSK=`$KEYGEN -a ECDSAP256SHA256 -L 300 $zone 2> keygen.out.$zone.2`
|
||||
T="now-6mo"
|
||||
$SETTIME -s -P $T -A $T -g $O -d $O $T -k $O $T -r $O $T $KSK > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $T -A $T -g $O -k $O $T -z $O $T $ZSK > settime.out.$zone.2 2>&1
|
||||
cat template.db.in "${KSK}.key" "${ZSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK >> "$infile"
|
||||
private_type_record $zone 13 $ZSK >> "$infile"
|
||||
$SIGNER -PS -x -s now-2mo -e now-1mo -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# These signatures are still good, and can be reused.
|
||||
setup fresh-sigs.autosign
|
||||
KSK=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 300 $zone 2> keygen.out.$zone.1`
|
||||
ZSK=`$KEYGEN -a ECDSAP256SHA256 -L 300 $zone 2> keygen.out.$zone.2`
|
||||
T="now-6mo"
|
||||
$SETTIME -s -P $T -A $T -g $O -d $O $T -k $O $T -r $O $T $KSK > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $T -A $T -g $O -k $O $T -z $O $T $ZSK > settime.out.$zone.2 2>&1
|
||||
cat template.db.in "${KSK}.key" "${ZSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK >> "$infile"
|
||||
private_type_record $zone 13 $ZSK >> "$infile"
|
||||
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# These signatures are still good, but not fresh enough, update immediately.
|
||||
setup unfresh-sigs.autosign
|
||||
KSK=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 300 $zone 2> keygen.out.$zone.1`
|
||||
ZSK=`$KEYGEN -a ECDSAP256SHA256 -L 300 $zone 2> keygen.out.$zone.2`
|
||||
T="now-6mo"
|
||||
$SETTIME -s -P $T -A $T -g $O -d $O $T -k $O $T -r $O $T $KSK > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $T -A $T -g $O -k $O $T -z $O $T $ZSK > settime.out.$zone.2 2>&1
|
||||
cat template.db.in "${KSK}.key" "${ZSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK >> "$infile"
|
||||
private_type_record $zone 13 $ZSK >> "$infile"
|
||||
$SIGNER -S -x -s now-1w -e now+1w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# These signatures are already expired, and the private ZSK is missing.
|
||||
setup zsk-missing.autosign
|
||||
KSK=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 300 $zone 2> keygen.out.$zone.1`
|
||||
ZSK=`$KEYGEN -a ECDSAP256SHA256 -L 300 $zone 2> keygen.out.$zone.2`
|
||||
T="now-6mo"
|
||||
$SETTIME -s -P $T -A $T -g $O -d $O $T -k $O $T -r $O $T $KSK > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $T -A $T -g $O -k $O $T -z $O $T $ZSK > settime.out.$zone.2 2>&1
|
||||
cat template.db.in "${KSK}.key" "${ZSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK >> "$infile"
|
||||
private_type_record $zone 13 $ZSK >> "$infile"
|
||||
$SIGNER -PS -x -s now-2w -e now-1mi -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
rm -f ${ZSK}.private
|
||||
|
||||
# These signatures are already expired, and the private ZSK is retired.
|
||||
setup zsk-retired.autosign
|
||||
KSK=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 300 $zone 2> keygen.out.$zone.1`
|
||||
ZSK=`$KEYGEN -a ECDSAP256SHA256 -L 300 $zone 2> keygen.out.$zone.2`
|
||||
T="now-6mo"
|
||||
$SETTIME -s -P $T -A $T -g $O -d $O $T -k $O $T -r $O $T $KSK > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $T -A $T -g $O -k $O $T -z $O $T $ZSK > settime.out.$zone.2 2>&1
|
||||
cat template.db.in "${KSK}.key" "${ZSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK >> "$infile"
|
||||
private_type_record $zone 13 $ZSK >> "$infile"
|
||||
$SIGNER -PS -x -s now-2w -e now-1mi -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
$SETTIME -s -I now -g HIDDEN $ZSK > settime.out.$zone.3 2>&1
|
||||
|
||||
#
|
||||
# The zones at zsk-prepub.autosign represent the various steps of a ZSK
|
||||
# Pre-Publication rollover.
|
||||
#
|
||||
|
||||
# Step 1:
|
||||
# Introduce the first key. This will immediately be active.
|
||||
setup step1.zsk-prepub.autosign
|
||||
KSK=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 3600 $zone 2> keygen.out.$zone.1`
|
||||
ZSK=`$KEYGEN -a ECDSAP256SHA256 -L 3600 $zone 2> keygen.out.$zone.2`
|
||||
TactN="now"
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -r $O $TactN -d $O $TactN $KSK > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -z $O $TactN $ZSK > settime.out.$zone.2 2>&1
|
||||
cat template.db.in "${KSK}.key" "${ZSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK >> "$infile"
|
||||
private_type_record $zone 13 $ZSK >> "$infile"
|
||||
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 2:
|
||||
# It is time to pre-publish the successor ZSK.
|
||||
setup step2.zsk-prepub.autosign
|
||||
KSK=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 3600 $zone 2> keygen.out.$zone.1`
|
||||
ZSK=`$KEYGEN -a ECDSAP256SHA256 -L 3600 $zone 2> keygen.out.$zone.2`
|
||||
# According to RFC 7583: Tpub(N+1) <= Tact(N) + Lzsk - Ipub
|
||||
# Also: Ipub = Dprp + TTLkey (+publish-safety)
|
||||
# so: Tact(N) = Tpub(N+1) + Ipub - Lzsk = now + (1d2h) - 30d =
|
||||
# now + 26h - 30d = now − 694h
|
||||
TactN="now-694h"
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -r $O $TactN -d $O $TactN $KSK > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -z $O $TactN $ZSK > settime.out.$zone.2 2>&1
|
||||
cat template.db.in "${KSK}.key" "${ZSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK >> "$infile"
|
||||
private_type_record $zone 13 $ZSK >> "$infile"
|
||||
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 3:
|
||||
# After the publication interval has passed the DNSKEY of the successor ZSK
|
||||
# is OMNIPRESENT and the zone can thus be signed with the successor ZSK.
|
||||
setup step3.zsk-prepub.autosign
|
||||
KSK=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 3600 $zone 2> keygen.out.$zone.1`
|
||||
ZSK1=`$KEYGEN -a ECDSAP256SHA256 -L 3600 $zone 2> keygen.out.$zone.2`
|
||||
ZSK2=`$KEYGEN -a ECDSAP256SHA256 -L 3600 $zone 2> keygen.out.$zone.3`
|
||||
# According to RFC 7583: Tpub(N+1) <= Tact(N) + Lzsk - Ipub
|
||||
# Also: Tret(N) = Tact(N+1) = Tact(N) + Lzsk
|
||||
# so: Tact(N) = Tact(N+1) - Lzsk = now - 30d
|
||||
# and: Tpub(N+1) = Tact(N+1) - Ipub = now - 26h
|
||||
# and: Tret(N+1) = Tact(N+1) + Lzsk
|
||||
TactN="now-30d"
|
||||
TpubN1="now-26h"
|
||||
TretN1="now+30d"
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -r $O $TactN -d $O $TactN $KSK > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $TactN -A $TactN -I now -g $H -k $O $TactN -z $O $TactN $ZSK1 > settime.out.$zone.2 2>&1
|
||||
$SETTIME -s -S $ZSK1 -i 0 $ZSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A now -I $TretN1 -g $O -k $R $TpubN1 -z $H $TpubN1 $ZSK2 > settime.out.$zone.4 2>&1
|
||||
cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK >> "$infile"
|
||||
private_type_record $zone 13 $ZSK1 >> "$infile"
|
||||
private_type_record $zone 13 $ZSK2 >> "$infile"
|
||||
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 4:
|
||||
# After the retire interval has passed the predecessor DNSKEY can be
|
||||
# removed from the zone.
|
||||
setup step4.zsk-prepub.autosign
|
||||
KSK=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 3600 $zone 2> keygen.out.$zone.1`
|
||||
ZSK1=`$KEYGEN -a ECDSAP256SHA256 -L 3600 $zone 2> keygen.out.$zone.2`
|
||||
ZSK2=`$KEYGEN -a ECDSAP256SHA256 -L 3600 $zone 2> keygen.out.$zone.3`
|
||||
# According to RFC 7583: Tret(N) = Tact(N) + Lzsk
|
||||
# Also: Tdea(N) = Tret(N) + Iret
|
||||
# Also: Iret = Dsgn + Dprp + TTLsig (+retire-safety)
|
||||
# so: Tact(N) = Tdea(N) - Iret - Lzsk = now - (1w1h1d2d) - 30d =
|
||||
# now - (10d1h) - 30d = now - 961h
|
||||
# and: Tret(N) = Tdea(N) - Iret = now - (10d1h) = now - 241h
|
||||
# and: Tpub(N+1) = Tdea(N) - Iret - Ipub = now - (10d1h) - 26h =
|
||||
# now - 267h
|
||||
# and: Tact(N+1) = Tdea(N) - Iret = Tret(N)
|
||||
# and: Tret(N+1) = Tdea(N) - Iret + Lzsk = now - (10d1h) + 30d =
|
||||
# now + 479h
|
||||
TactN="now-961h"
|
||||
TretN="now-241h"
|
||||
TpubN1="now-267h"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+479h"
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -r $O $TactN -d $O $TactN $KSK > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $O $TactN -z $U $TretN $ZSK1 > settime.out.$zone.2 2>&1
|
||||
$SETTIME -s -S $ZSK1 -i 0 $ZSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TactN1 -I $TretN1 -g $O -k $O $TactN1 -z $R $TactN1 $ZSK2 > settime.out.$zone.4 2>&1
|
||||
cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" > "$infile"
|
||||
$SIGNER -PS -x -s now-2w -e now-1mi -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 5:
|
||||
# The predecessor DNSKEY is removed long enough that is has become HIDDEN.
|
||||
setup step5.zsk-prepub.autosign
|
||||
KSK=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 3600 $zone 2> keygen.out.$zone.1`
|
||||
ZSK1=`$KEYGEN -a ECDSAP256SHA256 -L 3600 $zone 2> keygen.out.$zone.2`
|
||||
ZSK2=`$KEYGEN -a ECDSAP256SHA256 -L 3600 $zone 2> keygen.out.$zone.3`
|
||||
# Substract DNSKEY TTL from all the times (1h).
|
||||
TactN="now-962h"
|
||||
TretN="now-242h"
|
||||
TpubN1="now-268h"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+478h"
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -r $O $TactN -d $O $TactN $KSK > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -D now -g $H -k $U $TretN -z $U $TretN $ZSK1 > settime.out.$zone.2 2>&1
|
||||
$SETTIME -s -S $ZSK1 -i 0 $ZSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TactN1 -I $TretN1 -g $O -k $O $TactN1 -z $R $TactN1 $ZSK2 > settime.out.$zone.4 2>&1
|
||||
cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK >> "$infile"
|
||||
private_type_record $zone 13 $ZSK1 >> "$infile"
|
||||
private_type_record $zone 13 $ZSK2 >> "$infile"
|
||||
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
#
|
||||
# The zones at ksk-doubleksk.autosign represent the various steps of a KSK
|
||||
# Double-KSK rollover.
|
||||
#
|
||||
|
||||
# Step 1:
|
||||
# Introduce the first key. This will immediately be active.
|
||||
setup step1.ksk-doubleksk.autosign
|
||||
KSK=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 7200 $zone 2> keygen.out.$zone.1`
|
||||
ZSK=`$KEYGEN -a ECDSAP256SHA256 -L 7200 $zone 2> keygen.out.$zone.2`
|
||||
TactN="now"
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -r $O $TactN -d $O $TactN $KSK > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -z $O $TactN $ZSK > settime.out.$zone.2 2>&1
|
||||
cat template.db.in "${KSK}.key" "${ZSK}.key" > "$infile"
|
||||
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 2:
|
||||
# It is time to submit the introduce the new KSK.
|
||||
setup step2.ksk-doubleksk.autosign
|
||||
KSK=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 7200 $zone 2> keygen.out.$zone.1`
|
||||
ZSK=`$KEYGEN -a ECDSAP256SHA256 -L 7200 $zone 2> keygen.out.$zone.2`
|
||||
# According to RFC 7583: Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC
|
||||
# Also: IpubC = DprpC + TTLkey (+publish-safety)
|
||||
# so: Tact(N) = Tpub(N+1) - Lksk + Dreg + IpubC = now - 60d + (1d3h)
|
||||
# now - 1440h + 27h = now - 1413h
|
||||
TactN="now-1413h"
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -r $O $TactN -d $O $TactN $KSK > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -z $O $TactN $ZSK > settime.out.$zone.2 2>&1
|
||||
cat template.db.in "${KSK}.key" "${ZSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK >> "$infile"
|
||||
private_type_record $zone 13 $ZSK >> "$infile"
|
||||
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 3:
|
||||
# It is time to submit the DS.
|
||||
setup step3.ksk-doubleksk.autosign
|
||||
KSK1=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 7200 $zone 2> keygen.out.$zone.1`
|
||||
KSK2=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 7200 $zone 2> keygen.out.$zone.2`
|
||||
ZSK=`$KEYGEN -a ECDSAP256SHA256 -L 7200 $zone 2> keygen.out.$zone.3`
|
||||
# According to RFC 7583: Tsbm(N+1) >= Trdy(N+1)
|
||||
# Also: Tact(N+1) = Tsbm(N+1) + Dreg
|
||||
# so: Tact(N) = Tsbm(N+1) + Dreg - Lksk = now + 1d - 60d = now - 59d
|
||||
# and: Tret(N) = Tsbm(N+1) + Dreg = now + 1d
|
||||
# and: Tpub(N+1) <= Tsbm(N+1) - IpubC = now + 27h
|
||||
# and: Tret(N+1) = Tsbm(N+1) + Dreg + Lksk = 1d + 60d
|
||||
TactN="now-59d"
|
||||
TretN="now+1d"
|
||||
TpubN1="now-27h"
|
||||
TretN1="now+61d"
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $O $TactN -r $O $TactN -d $O $TactN $KSK1 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -S $KSK1 -i 0 $KSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TretN -I $TretN1 -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 $KSK2 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -z $O $TactN $ZSK > settime.out.$zone.2 2>&1
|
||||
cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK1 >> "$infile"
|
||||
private_type_record $zone 13 $KSK2 >> "$infile"
|
||||
private_type_record $zone 13 $ZSK >> "$infile"
|
||||
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 4:
|
||||
# The DS should be swapped now.
|
||||
setup step4.ksk-doubleksk.autosign
|
||||
KSK1=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 7200 $zone 2> keygen.out.$zone.1`
|
||||
KSK2=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 7200 $zone 2> keygen.out.$zone.2`
|
||||
ZSK=`$KEYGEN -a ECDSAP256SHA256 -L 7200 $zone 2> keygen.out.$zone.3`
|
||||
# According to RFC 7583: Tdea(N) = Tret(N) + Iret
|
||||
# Also: Tret(N) = Tsbm(N+1) + Dreg
|
||||
# Also: Tact(N+1) = Tret(N)
|
||||
# Also: Iret = DprpP + TTLds (+retire-safety)
|
||||
# so: Tact(N) = Tdea(N) - Lksk - Iret = now - 60d - 2d2h = now - 1490h
|
||||
# and: Tret(N) = Tdea(N) - Iret = now - 2d2h = 50h
|
||||
# and: Tpub(N+1) = Tdea(N) - Iret - Dreg - IpubC = now - 50h - 1d - 1d3h = now - 101h
|
||||
# and: Tsbm(N+1) = Tdea(N) - Iret - Dreg = now - 50h - 1d = now - 74h
|
||||
# and: Tact(N+1) = Tret(N)
|
||||
# and: Tret(N+1) = Tdea(N) + Lksk - Iret = now + 60d - 2d2h = now + 1390h
|
||||
TactN="now-1490h"
|
||||
TretN="now-50h"
|
||||
TpubN1="now-101h"
|
||||
TsbmN1="now-74h"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+1390h"
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $O $TactN -r $O $TactN -d $U $TsbmN1 $KSK1 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -S $KSK1 -i 0 $KSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TactN1 -I $TretN1 -g $O -k $O $TsbmN1 -r $O $TsbmN1 -d $R $TsbmN1 $KSK2 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -z $O $TactN $ZSK > settime.out.$zone.2 2>&1
|
||||
cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK1 >> "$infile"
|
||||
private_type_record $zone 13 $KSK2 >> "$infile"
|
||||
private_type_record $zone 13 $ZSK >> "$infile"
|
||||
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 5:
|
||||
# The predecessor DNSKEY is removed long enough that is has become HIDDEN.
|
||||
setup step5.ksk-doubleksk.autosign
|
||||
KSK1=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 7200 $zone 2> keygen.out.$zone.1`
|
||||
KSK2=`$KEYGEN -a ECDSAP256SHA256 -f KSK -L 7200 $zone 2> keygen.out.$zone.2`
|
||||
ZSK=`$KEYGEN -a ECDSAP256SHA256 -L 7200 $zone 2> keygen.out.$zone.3`
|
||||
# Substract DNSKEY TTL from all the times (2h).
|
||||
TactN="now-1492h"
|
||||
TretN="now-52h"
|
||||
TpubN1="now-102h"
|
||||
TsbmN1="now-75h"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+1388h"
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $U $TretN -r $U $TretN -d $H $TretN $KSK1 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -S $KSK1 -i 0 $KSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TactN1 -I $TretN1 -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 $KSK2 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -z $O $TactN $ZSK > settime.out.$zone.2 2>&1
|
||||
cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $KSK1 >> "$infile"
|
||||
private_type_record $zone 13 $KSK2 >> "$infile"
|
||||
private_type_record $zone 13 $ZSK >> "$infile"
|
||||
$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
#
|
||||
# The zones at csk-roll.autosign represent the various steps of a CSK rollover
|
||||
# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover).
|
||||
#
|
||||
|
||||
# Step 1:
|
||||
# Introduce the first key. This will immediately be active.
|
||||
setup step1.csk-roll.autosign
|
||||
CSK=`$KEYGEN -k csk-roll -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
TactN="now"
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN $CSK > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 2:
|
||||
# It is time to introduce the new CSK.
|
||||
setup step2.csk-roll.autosign
|
||||
CSK=`$KEYGEN -k csk-roll -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
# According to RFC 7583: ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub
|
||||
# According to RFC 7583: KSK: Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC
|
||||
# Also: Ipub = Dprp + TTLkey (+publish-safety)
|
||||
# Also: IpubC = DprpC + TTLkey (+publish-safety)
|
||||
# Both sums are almost the same, but the KSK case has Dreg in the equation.
|
||||
# so: Tact(N) = Tpub(N+1) - Lcsk + Dreg + IpubC = now - 6mo + 1d + 3h =
|
||||
# now - 4464h + 24h + 3h = now - 4437h
|
||||
TactN="now-4437h"
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN $CSK > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 3:
|
||||
# It is time to submit the DS and to roll signatures.
|
||||
setup step3.csk-roll.autosign
|
||||
CSK1=`$KEYGEN -k csk-roll -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
CSK2=`$KEYGEN -k csk-roll -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
# According to RFC 7583: Tsbm(N+1) >= Trdy(N+1)
|
||||
# Also: Tact(N+1) = Tsbm(N+1) + Dreg
|
||||
# so: Tact(N) = Tsbm(N+1) + Dreg - Lksk = now + 1d - 6mo = now - 185d
|
||||
# and: Tret(N) = Tsbm(N+1) + Dreg = now + 1d
|
||||
# and: Tpub(N+1) <= Tsbm(N+1) - IpubC = now - 3h
|
||||
# and: Tret(N+1) = Tsbm(N+1) + Dreg + Lksk = now + 1d + 6mo = now + 187d
|
||||
TactN="now-185d"
|
||||
TretN="now+1d"
|
||||
TpubN1="now-3h"
|
||||
TretN1="now+187d"
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN $CSK1 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -S $CSK1 -i 0 $CSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TretN -I $TretN1 -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 -z $H $TpubN1 $CSK2 > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK1 >> "$infile"
|
||||
private_type_record $zone 13 $CSK2 >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 4:
|
||||
# Some time later all the ZRRSIG records should be from the new CSK, and the
|
||||
# DS should be swapped. The ZRRSIG records are all replaced after Iret
|
||||
# which is Dsgn + Dprp + TTLsig + retire-safety (25d + 1h + 1d + 2h = 26d3h).
|
||||
# The DS is swapped after Dreg + DprpP + TTLds + retire-safety
|
||||
# (1d + 1h + 1h + 2h = 1d4h). In other words, the DS is swapped before all
|
||||
# zone signatures are replaced.
|
||||
setup step4.csk-roll.autosign
|
||||
CSK1=`$KEYGEN -k csk-roll -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
CSK2=`$KEYGEN -k csk-roll -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
# According to RFC 7583: Tdea(N) = Tret(N) + Iret
|
||||
# Also: Iret = 1h + 1h + 2h = 4h
|
||||
# Also: Tact(N+1) = Tret(N)
|
||||
# so: Tact(N) = Tdea(N) - Lksk - Iret = now - 6mo - 4h = now - 4468h
|
||||
# and: Tret(N) = Tdea(N) - Iret = now - 4h = now - 4h
|
||||
# and: Tpub(N+1) = Tdea(N) - Iret - Dreg - IpubC = now - 4h - 1d - 3h = now - 31h
|
||||
# and: Tsbm(N+1) = Tdea(N) - Iret - Dreg = now - 4h - 1d = now - 28h
|
||||
# and: Tact(N+1) = Tret(N)
|
||||
# and: Tret(N+1) = Tdea(N) + Lksk - Iret = now + 6mo - 4h = now + 4460h
|
||||
TactN="now-4468h"
|
||||
TretN="now-4h"
|
||||
TpubN1="now-31h"
|
||||
TsbmN1="now-28h"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+4460h"
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $O $TactN -r $O $TactN -d $U $TsbmN1 -z $U $TsbmN1 $CSK1 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -S $CSK1 -i 0 $CSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TactN1 -I $TretN1 -g $O -k $O $TsbmN1 -r $O $TsbmN1 -d $R $TsbmN1 -z $R $TsbmN1 $CSK2 > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK1 >> "$infile"
|
||||
private_type_record $zone 13 $CSK2 >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 5:
|
||||
# After the DS is swapped in step 4, also the KRRSIG records can be removed.
|
||||
# At this time these have all become hidden.
|
||||
setup step5.csk-roll.autosign
|
||||
CSK1=`$KEYGEN -k csk-roll -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
CSK2=`$KEYGEN -k csk-roll -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
# Substract DNSKEY TTL plus zone propagation delay from all the times (2h).
|
||||
TactN="now-4470h"
|
||||
TretN="now-6h"
|
||||
TdeaN="now-2h"
|
||||
TpubN1="now-33h"
|
||||
TsbmN1="now-30h"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+4458h"
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $O $TactN -r $U $TdeaN -d $H $TdeaN -z $U $TsbmN1 $CSK1 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -S $CSK1 -i 0 $CSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TactN1 -I $TretN1 -g $O -k $O $TsbmN1 -r $O $TsbmN1 -d $O $TdeaN -z $R $TsbmN1 $CSK2 > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK1 >> "$infile"
|
||||
private_type_record $zone 13 $CSK2 >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 6:
|
||||
# After the retire interval has passed the predecessor DNSKEY can be
|
||||
# removed from the zone.
|
||||
setup step6.csk-roll.autosign
|
||||
CSK1=`$KEYGEN -k csk-roll -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
CSK2=`$KEYGEN -k csk-roll -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
# According to RFC 7583: Tdea(N) = Tret(N) + Iret
|
||||
# Also: Tret(N) = Tact(N) + Lzsk
|
||||
# Also: Iret = Dsgn + Dprp + TTLsig (+retire-safety)
|
||||
# so: Tact(N) = Tdea(N) - Iret - Lzsk = now - 25d1h1d2h - 6mo =
|
||||
# now - 26d3h - 6mo = now - 627h - 4464h = now - 5091h
|
||||
# and: Tret(N) = Tdea(N) - Iret = now - 627h
|
||||
# and: Tpub(N+1) = Tdea(N) - Iret - Ipub = now - 627h - 3h = now - 630h
|
||||
# and: Tact(N+1) = Tdea(N) - Iret = Tret(N)
|
||||
# and: Tret(N+1) = Tdea(N) - Iret + Lzsk = now - 627h + 6mo = now + 3837h
|
||||
TactN="now-5091h"
|
||||
TretN="now-627h"
|
||||
TdeaN="now-623h"
|
||||
TpubN1="now-630h"
|
||||
TsbmN1="now-627h"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+3837h"
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $O $TactN -r $H $TdeaN -d $H $TdeaN -z $U $TsbmN1 $CSK1 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -S $CSK1 -i 0 $CSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TactN1 -I $TretN1 -g $O -k $O $TsbmN1 -r $O $TsbmN1 -d $O $TdeaN -z $R $TsbmN1 $CSK2 > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK1 >> "$infile"
|
||||
private_type_record $zone 13 $CSK2 >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 7:
|
||||
# Some time later the predecessor DNSKEY enters the HIDDEN state.
|
||||
setup step7.csk-roll.autosign
|
||||
CSK1=`$KEYGEN -k csk-roll -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
CSK2=`$KEYGEN -k csk-roll -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
# Substract DNSKEY TTL plus zone propagation delay from all the times (2h).
|
||||
TactN="now-5093h"
|
||||
TretN="now-629h"
|
||||
TdeaN="now-625h"
|
||||
TpubN1="now-632h"
|
||||
TsbmN1="now-629h"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+3835h"
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $U now-2h -r $H $TdeaN -d $H $TdeaN -z $H $TsbmN1 $CSK1 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -S $CSK1 -i 0 $CSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TactN1 -I $TretN1 -g $O -k $O $TsbmN1 -r $O $TsbmN1 -d $O $TdeaN -z $O $TsbmN1 $CSK2 > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK1 >> "$infile"
|
||||
private_type_record $zone 13 $CSK2 >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
#
|
||||
# The zones at csk-roll2.autosign represent the various steps of a CSK rollover
|
||||
# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover).
|
||||
# This scenario differs from the above one because the zone signatures (ZRRSIG)
|
||||
# are replaced with the new key sooner than the DS is swapped.
|
||||
#
|
||||
|
||||
# Step 1:
|
||||
# Introduce the first key. This will immediately be active.
|
||||
setup step1.csk-roll2.autosign
|
||||
CSK=`$KEYGEN -k csk-roll2 -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
TactN="now"
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN $CSK > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 2:
|
||||
# It is time to introduce the new CSK.
|
||||
setup step2.csk-roll2.autosign
|
||||
CSK=`$KEYGEN -k csk-roll2 -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
# According to RFC 7583: ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub
|
||||
# According to RFC 7583: KSK: Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC
|
||||
# Also: Ipub = Dprp + TTLkey (+publish-safety)
|
||||
# Also: IpubC = DprpC + TTLkey (+publish-safety)
|
||||
# Both sums are almost the same, but the KSK case has Dreg in the equation.
|
||||
# so: Tact(N) = Tpub(N+1) - Lcsk + Dreg + IpubC = now - 6mo + 1w + 3h =
|
||||
# now - 4464h + 168h + 3h = now - 4635h
|
||||
TactN="now-4635h"
|
||||
$SETTIME -s -P $TactN -A $TactN -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN $CSK > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 3:
|
||||
# It is time to submit the DS and to roll signatures.
|
||||
setup step3.csk-roll2.autosign
|
||||
CSK1=`$KEYGEN -k csk-roll2 -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
CSK2=`$KEYGEN -k csk-roll2 -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
# According to RFC 7583: Tsbm(N+1) >= Trdy(N+1)
|
||||
# Also: Tact(N+1) = Tsbm(N+1) + Dreg
|
||||
# so: Tact(N) = Tsbm(N+1) + Dreg - Lksk = now + 1w - 6mo = now - 179d
|
||||
# and: Tret(N) = Tsbm(N+1) + Dreg = now + 1w
|
||||
# and: Tpub(N+1) <= Tsbm(N+1) - IpubC = now - 3h
|
||||
# and: Tret(N+1) = Tsbm(N+1) + Dreg + Lksk = now + 1w + 6mo = now + 193d
|
||||
TactN="now-179d"
|
||||
TretN="now+1w"
|
||||
TpubN1="now-3h"
|
||||
TretN1="now+193d"
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN $CSK1 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -S $CSK1 -i 0 $CSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TretN -I $TretN1 -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 -z $H $TpubN1 $CSK2 > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK1 >> "$infile"
|
||||
private_type_record $zone 13 $CSK2 >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 4:
|
||||
# Some time later all the ZRRSIG records should be from the new CSK, and the
|
||||
# DS should be swapped. The ZRRSIG records are all replaced after Iret
|
||||
# which is Dsgn + Dprp + TTLsig + retire-safety (12h + 1h + 1d + 2h = 38h).
|
||||
# The DS is swapped after Dreg + DprpP + TTLds + retire-safety
|
||||
# (1w + 1h + 1h + 1h = 1w3h). In other words, the zone signatures are
|
||||
# replaced before the DS is swapped.
|
||||
setup step4.csk-roll2.autosign
|
||||
CSK1=`$KEYGEN -k csk-roll2 -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
CSK2=`$KEYGEN -k csk-roll2 -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
# According to RFC 7583: Tdea(N) = Tret(N) + Iret
|
||||
# Also: Tret(N) = Tact(N) + Lzsk
|
||||
# Also: Iret = Dsgn + Dprp + TTLsig (+retire-safety)
|
||||
# so: Tact(N) = Tdea(N) - Iret - Lzsk = now - 38h - 6mo = now - 4502h
|
||||
# and: Tret(N) = Tdea(N) - Iret = now - 38h
|
||||
# and: Tpub(N+1) = Tdea(N) - Iret - Ipub = now - 41h
|
||||
# and: Tact(N+1) = Tdea(N) - Iret = Tret(N)
|
||||
# and: Tret(N+1) = Tdea(N) - Iret + Lzsk = now - 38h + 6mo = now + 4426h
|
||||
TactN="now-4502h"
|
||||
TretN="now-38h"
|
||||
TpubN1="now-41h"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+4426"
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $O $TactN -r $O $TactN -d $U $TretN -z $U $TretN $CSK1 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -S $CSK1 -i 0 $CSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TactN1 -I $TretN1 -g $O -k $O $TretN -r $O $TretN -d $R $TretN -z $R $TretN $CSK2 > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK1 >> "$infile"
|
||||
private_type_record $zone 13 $CSK2 >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 5:
|
||||
# Some time later the DS can be swapped and the old DNSKEY can be removed from
|
||||
# the zone.
|
||||
setup step5.csk-roll2.autosign
|
||||
CSK1=`$KEYGEN -k csk-roll2 -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
CSK2=`$KEYGEN -k csk-roll2 -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
# Substract Dreg + Iret (174h).
|
||||
TactN="now-4676h"
|
||||
TretN="now-212h"
|
||||
TpubN1="now-215h"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+4252h"
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $O $TactN -r $O $TactN -d $U $TretN -z $H $TretN $CSK1 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -S $CSK1 -i 0 $CSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TactN1 -I $TretN1 -g $O -k $O $TretN -r $O $TretN -d $R $TretN -z $O $TretN $CSK2 > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK1 >> "$infile"
|
||||
private_type_record $zone 13 $CSK2 >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# Step 6:
|
||||
# Some time later the predecessor DNSKEY enters the HIDDEN state.
|
||||
setup step6.csk-roll2.autosign
|
||||
CSK1=`$KEYGEN -k csk-roll2 -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
CSK2=`$KEYGEN -k csk-roll2 -l policies/autosign.conf $zone 2> keygen.out.$zone.1`
|
||||
# Substract DNSKEY TTL plus zone propagation delay (2h).
|
||||
TactN="now-4678h"
|
||||
TretN="now-214h"
|
||||
TdeaN="now-2h"
|
||||
TpubN1="now-217h"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+4250h"
|
||||
$SETTIME -s -P $TactN -A $TactN -I $TretN -g $H -k $U $TdeaN -r $U $TdeaN -d $H $TretN -z $H $TretN $CSK1 > settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -S $CSK1 -i 0 $CSK2 > settime.out.$zone.3 2>&1
|
||||
$SETTIME -s -P $TpubN1 -A $TactN1 -I $TretN1 -g $O -k $O $TretN -r $O $TretN -d $O $TretN -z $O $TretN $CSK2 > settime.out.$zone.1 2>&1
|
||||
cat template.db.in "${CSK1}.key" "${CSK2}.key" > "$infile"
|
||||
private_type_record $zone 13 $CSK1 >> "$infile"
|
||||
private_type_record $zone 13 $CSK2 >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
25
bin/tests/system/kasp/ns3/template.db.in
Normal file
25
bin/tests/system/kasp/ns3/template.db.in
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
; 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.
|
||||
|
||||
$TTL 300
|
||||
@ IN SOA mname1. . (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
NS ns3
|
||||
ns3 A 10.53.0.3
|
||||
|
||||
a A 10.0.0.1
|
||||
b A 10.0.0.2
|
||||
c A 10.0.0.3
|
||||
|
||||
25
bin/tests/system/kasp/ns3/template2.db.in
Normal file
25
bin/tests/system/kasp/ns3/template2.db.in
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
; 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.
|
||||
|
||||
$TTL 300
|
||||
@ IN SOA mname1. . (
|
||||
2 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
NS ns3
|
||||
ns3 A 10.53.0.3
|
||||
|
||||
a A 10.0.0.11
|
||||
b A 10.0.0.2
|
||||
c A 10.0.0.3
|
||||
d A 10.0.0.4
|
||||
117
bin/tests/system/kasp/ns4/named.conf.in
Normal file
117
bin/tests/system/kasp/ns4/named.conf.in
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// NS4
|
||||
|
||||
key "sha1" {
|
||||
algorithm "hmac-sha1";
|
||||
secret "FrSt77yPTFx6hTs4i2tKLB9LmE0=";
|
||||
};
|
||||
|
||||
key "sha224" {
|
||||
algorithm "hmac-sha224";
|
||||
secret "hXfwwwiag2QGqblopofai9NuW28q/1rH4CaTnA==";
|
||||
};
|
||||
|
||||
key "sha256" {
|
||||
algorithm "hmac-sha256";
|
||||
secret "R16NojROxtxH/xbDl//ehDsHm5DjWTQ2YXV+hGC2iBY=";
|
||||
};
|
||||
|
||||
dnssec-policy "test" {
|
||||
keys {
|
||||
csk key-directory lifetime 0 algorithm 14;
|
||||
};
|
||||
};
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.4;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.4; };
|
||||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
dnssec-policy "test";
|
||||
};
|
||||
|
||||
view "inherit" {
|
||||
match-clients { key "sha1"; };
|
||||
|
||||
/* Inherit dnssec-policy 'test' */
|
||||
zone "inherit.inherit.signed" {
|
||||
type master;
|
||||
file "inherit.inherit.signed.db";
|
||||
};
|
||||
|
||||
/* Override dnssec-policy */
|
||||
zone "override.inherit.signed" {
|
||||
type master;
|
||||
dnssec-policy "default";
|
||||
file "override.inherit.signed.db";
|
||||
};
|
||||
|
||||
/* Unset dnssec-policy */
|
||||
zone "none.inherit.signed" {
|
||||
type master;
|
||||
dnssec-policy "none";
|
||||
file "none.inherit.signed.db";
|
||||
};
|
||||
};
|
||||
|
||||
view "override" {
|
||||
match-clients { key "sha224"; };
|
||||
dnssec-policy "default";
|
||||
|
||||
/* Inherit dnssec-policy 'test' */
|
||||
zone "inherit.override.signed" {
|
||||
type master;
|
||||
file "inherit.override.signed.db";
|
||||
};
|
||||
|
||||
/* Override dnssec-policy */
|
||||
zone "override.override.signed" {
|
||||
type master;
|
||||
dnssec-policy "test";
|
||||
file "override.override.signed.db";
|
||||
};
|
||||
|
||||
/* Unset dnssec-policy */
|
||||
zone "none.override.signed" {
|
||||
type master;
|
||||
dnssec-policy "none";
|
||||
file "none.override.signed.db";
|
||||
};
|
||||
};
|
||||
|
||||
view "none" {
|
||||
match-clients { key "sha256"; };
|
||||
dnssec-policy "none";
|
||||
|
||||
/* Inherit dnssec-policy 'none' */
|
||||
zone "inherit.none.signed" {
|
||||
type master;
|
||||
file "inherit.none.signed.db";
|
||||
};
|
||||
|
||||
/* Override dnssec-policy */
|
||||
zone "override.none.signed" {
|
||||
type master;
|
||||
dnssec-policy "test";
|
||||
file "override.none.signed.db";
|
||||
};
|
||||
|
||||
/* Unset dnssec-policy */
|
||||
zone "none.none.signed" {
|
||||
type master;
|
||||
dnssec-policy "none";
|
||||
file "none.none.signed.db";
|
||||
};
|
||||
};
|
||||
28
bin/tests/system/kasp/ns4/setup.sh
Normal file
28
bin/tests/system/kasp/ns4/setup.sh
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# 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.
|
||||
|
||||
# shellcheck source=conf.sh
|
||||
. "$SYSTEMTESTTOP/conf.sh"
|
||||
|
||||
echo_i "ns4/setup.sh"
|
||||
|
||||
#
|
||||
# Set up zones that potentially will be initially signed.
|
||||
#
|
||||
for zn in inherit.inherit override.inherit none.inherit \
|
||||
inherit.override override.override none.override \
|
||||
inherit.none override.none none.none
|
||||
do
|
||||
zone="$zn.signed"
|
||||
echo_i "setting up zone: $zone"
|
||||
zonefile="${zone}.db"
|
||||
cp template.db.in $zonefile
|
||||
done
|
||||
25
bin/tests/system/kasp/ns4/template.db.in
Normal file
25
bin/tests/system/kasp/ns4/template.db.in
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
; 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.
|
||||
|
||||
$TTL 300
|
||||
@ IN SOA mname1. . (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
NS ns4
|
||||
ns4 A 10.53.0.4
|
||||
|
||||
a A 10.0.0.1
|
||||
b A 10.0.0.2
|
||||
c A 10.0.0.3
|
||||
|
||||
117
bin/tests/system/kasp/ns5/named.conf.in
Normal file
117
bin/tests/system/kasp/ns5/named.conf.in
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// NS5
|
||||
|
||||
key "sha1" {
|
||||
algorithm "hmac-sha1";
|
||||
secret "FrSt77yPTFx6hTs4i2tKLB9LmE0=";
|
||||
};
|
||||
|
||||
key "sha224" {
|
||||
algorithm "hmac-sha224";
|
||||
secret "hXfwwwiag2QGqblopofai9NuW28q/1rH4CaTnA==";
|
||||
};
|
||||
|
||||
key "sha256" {
|
||||
algorithm "hmac-sha256";
|
||||
secret "R16NojROxtxH/xbDl//ehDsHm5DjWTQ2YXV+hGC2iBY=";
|
||||
};
|
||||
|
||||
dnssec-policy "test" {
|
||||
keys {
|
||||
csk key-directory lifetime 0 algorithm 14;
|
||||
};
|
||||
};
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.5;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.5; };
|
||||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
dnssec-policy "none";
|
||||
};
|
||||
|
||||
view "inherit" {
|
||||
match-clients { key "sha1"; };
|
||||
|
||||
/* Inherit dnssec-policy 'none' */
|
||||
zone "inherit.inherit.unsigned" {
|
||||
type master;
|
||||
file "inherit.inherit.unsigned.db";
|
||||
};
|
||||
|
||||
/* Override dnssec-policy */
|
||||
zone "override.inherit.unsigned" {
|
||||
type master;
|
||||
dnssec-policy "default";
|
||||
file "override.inherit.unsigned.db";
|
||||
};
|
||||
|
||||
/* Unset dnssec-policy */
|
||||
zone "none.inherit.unsigned" {
|
||||
type master;
|
||||
dnssec-policy "none";
|
||||
file "none.inherit.unsigned.db";
|
||||
};
|
||||
};
|
||||
|
||||
view "override" {
|
||||
match-clients { key "sha224"; };
|
||||
dnssec-policy "default";
|
||||
|
||||
/* Inherit dnssec-policy 'default' */
|
||||
zone "inherit.override.unsigned" {
|
||||
type master;
|
||||
file "inherit.override.unsigned.db";
|
||||
};
|
||||
|
||||
/* Override dnssec-policy */
|
||||
zone "override.override.unsigned" {
|
||||
type master;
|
||||
dnssec-policy "test";
|
||||
file "override.override.unsigned.db";
|
||||
};
|
||||
|
||||
/* Unset dnssec-policy */
|
||||
zone "none.override.unsigned" {
|
||||
type master;
|
||||
dnssec-policy "none";
|
||||
file "none.override.unsigned.db";
|
||||
};
|
||||
};
|
||||
|
||||
view "none" {
|
||||
match-clients { key "sha256"; };
|
||||
dnssec-policy "none";
|
||||
|
||||
/* Inherit dnssec-policy 'none' */
|
||||
zone "inherit.none.unsigned" {
|
||||
type master;
|
||||
file "inherit.none.unsigned.db";
|
||||
};
|
||||
|
||||
/* Override dnssec-policy */
|
||||
zone "override.none.unsigned" {
|
||||
type master;
|
||||
dnssec-policy "test";
|
||||
file "override.none.unsigned.db";
|
||||
};
|
||||
|
||||
/* Unset dnssec-policy */
|
||||
zone "none.none.unsigned" {
|
||||
type master;
|
||||
dnssec-policy "none";
|
||||
file "none.none.unsigned.db";
|
||||
};
|
||||
};
|
||||
28
bin/tests/system/kasp/ns5/setup.sh
Normal file
28
bin/tests/system/kasp/ns5/setup.sh
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# 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.
|
||||
|
||||
# shellcheck source=conf.sh
|
||||
. "$SYSTEMTESTTOP/conf.sh"
|
||||
|
||||
echo_i "ns5/setup.sh"
|
||||
|
||||
#
|
||||
# Set up zones that potentially will be initially signed.
|
||||
#
|
||||
for zn in inherit.inherit override.inherit none.inherit \
|
||||
inherit.override override.override none.override \
|
||||
inherit.none override.none none.none
|
||||
do
|
||||
zone="$zn.unsigned"
|
||||
echo_i "setting up zone: $zone"
|
||||
zonefile="${zone}.db"
|
||||
cp template.db.in $zonefile
|
||||
done
|
||||
25
bin/tests/system/kasp/ns5/template.db.in
Normal file
25
bin/tests/system/kasp/ns5/template.db.in
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
; 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.
|
||||
|
||||
$TTL 300
|
||||
@ IN SOA mname1. . (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
NS ns5
|
||||
ns5 A 10.53.0.5
|
||||
|
||||
a A 10.0.0.1
|
||||
b A 10.0.0.2
|
||||
c A 10.0.0.3
|
||||
|
||||
42
bin/tests/system/kasp/setup.sh
Normal file
42
bin/tests/system/kasp/setup.sh
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# 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.
|
||||
|
||||
# shellcheck source=conf.sh
|
||||
. "$SYSTEMTESTTOP/conf.sh"
|
||||
|
||||
set -e
|
||||
|
||||
$SHELL clean.sh
|
||||
|
||||
mkdir keys
|
||||
|
||||
copy_setports ns2/named.conf.in ns2/named.conf
|
||||
copy_setports ns3/named.conf.in ns3/named.conf
|
||||
copy_setports ns4/named.conf.in ns4/named.conf
|
||||
copy_setports ns5/named.conf.in ns5/named.conf
|
||||
|
||||
# Setup zones
|
||||
(
|
||||
cd ns2
|
||||
$SHELL setup.sh
|
||||
)
|
||||
(
|
||||
cd ns3
|
||||
$SHELL setup.sh
|
||||
)
|
||||
(
|
||||
cd ns4
|
||||
$SHELL setup.sh
|
||||
)
|
||||
(
|
||||
cd ns5
|
||||
$SHELL setup.sh
|
||||
)
|
||||
2080
bin/tests/system/kasp/tests.sh
Normal file
2080
bin/tests/system/kasp/tests.sh
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -3120,6 +3120,16 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
|
|||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row rowsep="0">
|
||||
<entry colname="1">
|
||||
<para><command>dnssec-policy</command></para>
|
||||
</entry>
|
||||
<entry colname="2">
|
||||
<para>
|
||||
describes a DNSSEC key and signing policy for zones.
|
||||
</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row rowsep="0">
|
||||
<entry colname="1">
|
||||
<para><command>include</command></para>
|
||||
|
|
@ -11004,6 +11014,224 @@ example.com CNAME rpz-tcp-only.
|
|||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="dnssec_policy_grammar"><info><title><command>dnssec-policy</command> Statement Grammar</title></info>
|
||||
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="dnssec-policy.grammar.xml"/>
|
||||
</section>
|
||||
|
||||
<section xml:id="dnssec_policy"><info><title><command>dnssec-policy</command> Statement Definition
|
||||
and Usage</title></info>
|
||||
|
||||
<para>
|
||||
The <command>dnssec-policy</command> statement defines a key and
|
||||
signing policy (KASP) for zones.
|
||||
</para>
|
||||
<para>
|
||||
KASP is used to determine how one or more zones need to be signed
|
||||
with DNSSEC. For example, how often RRSIG records need to be
|
||||
refreshed, or what cryptographic algorithms to use.
|
||||
</para>
|
||||
<para>
|
||||
You can configure multiple policies. To attach a policy to a zone
|
||||
simply add <userinput>dnssec-policy "policy_name"</userinput>
|
||||
option to the <command>zone</command> statement with a matching
|
||||
policy name.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>dnskey-ttl</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The TTL of the DNSKEY resource records.
|
||||
Default is <constant>3600</constant> seconds.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>keys</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
A list of keys to use. Each line represents one key. Here is
|
||||
an example (for illustration purposes only) of some possible
|
||||
keys in a <command>dnssec-policy</command>:
|
||||
</para>
|
||||
|
||||
<programlisting>keys {
|
||||
ksk key-directory lifetime P5Y algorithm 8 2048;
|
||||
zsk key-directory lifetime P30D algorithm 8;
|
||||
csk key-directory lifetime P6MT12H3M15S algorithm 13;
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
This example lists three keys. The first token determines
|
||||
what RRsets the key will sign. If set to
|
||||
<userinput>ksk</userinput> the key will sign the DNSKEY, CDS,
|
||||
and CDNSKEY RRsets, if set to <userinput>zsk</userinput> the
|
||||
key will sign the other RRsets, and if set to
|
||||
<userinput>csk</userinput> the key will sign all RRsets.
|
||||
</para>
|
||||
<para>
|
||||
The following part determines where the key will be stored.
|
||||
Currently keys can only be stored in the configured
|
||||
<command>key-directory</command>.
|
||||
</para>
|
||||
<para>
|
||||
The third token tells how long the key may be used. In the
|
||||
example the first key has a lifetime of 5 years, the second
|
||||
key may be used for 30 days and the third key has a rather
|
||||
peculiar lifetime of 6 months, 12 hours, 3 minutes and 15
|
||||
seconds.
|
||||
</para>
|
||||
<para>
|
||||
The last token(s) are the key's algorithm and algorithm length.
|
||||
The length may be omitted as shown in the example for the
|
||||
second and third key.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>publish-safety</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
A margin that is added to the publish interval in key timing
|
||||
equations to give some extra time to cover unforeseen events.
|
||||
Default is <constant>PT5M</constant> (5 minutes).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>retire-safety</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
A margin that is added to the retire interval in key timing
|
||||
equations to give some extra time to cover unforeseen events.
|
||||
Default is <constant>PT5M</constant> (5 minutes).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>signatures-refresh</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This determines when a RRSIG record needs to be refreshed.
|
||||
The signatures is renewed when the time until the expiration
|
||||
time is closer than <command>signatures-refresh</command>.
|
||||
<command>signatures-resign</command> interval.
|
||||
Default is <constant>P5D</constant> (5 days), meaning a
|
||||
signature that will expire in 5 days or sooner will be
|
||||
refreshed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>signatures-validity</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The validity period of an RRSIG record (minus the inception
|
||||
offset and jitter). Default is <constant>P2W</constant>
|
||||
(2 weeks).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>signatures-validity-dnskey</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Like <command>signatures-validity</command> but for DNSKEY
|
||||
records. Default is <constant>P2W</constant> (2 weeks).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>zone-max-ttl</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Like <command>max-zone-ttl</command>, specifies the maximum
|
||||
permissible TTL value in seconds. When loading a zone file
|
||||
using a <option>masterfile-format</option> or
|
||||
<constant>text</constant> or <constant>raw</constant>,
|
||||
any record encountered with a TTL higher than
|
||||
<option>zone-max-ttl</option> will be capped to the maximum
|
||||
permissible TTL value.
|
||||
</para>
|
||||
<para>
|
||||
This is needed in DNSSEC-maintained zones because when
|
||||
rolling to a new DNSKEY, the old key needs to remain
|
||||
available until RRSIG records have expired from
|
||||
caches. The <option>zone-max-ttl</option> option guarantees
|
||||
that the largest TTL in the zone will be no higher than the
|
||||
set value.
|
||||
</para>
|
||||
<para>
|
||||
(NOTE: Because <constant>map</constant>-format files
|
||||
load directly into memory, this option cannot be
|
||||
used with them.)
|
||||
</para>
|
||||
<para>
|
||||
The default value is <constant>PT24H</constant> (24 hours).
|
||||
A <option>zone-max-ttl</option> of zero is treated as if
|
||||
the default value is in use.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>zone-propagation-delay</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The expected propagation delay from when a zone is updated
|
||||
and when the new version of the zone is served by all its
|
||||
name servers. Default is <constant>PT5M</constant> (5 minutes).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>parent-ds-ttl</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The TTL of the DS RRset that the parent uses. Default is
|
||||
<constant>PT1H</constant> (1 hour).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>parent-propagation-delay</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The expected propagation delay from when the parent zone is
|
||||
updated and when the new version of the parent zone is served
|
||||
by all its name servers. Default is
|
||||
<constant>PT1H</constant> (1 hour).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>parent-registration-delay</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The expected registration delay from when a DS RRset change
|
||||
is requested and when the DS RRset has been updated in the
|
||||
parent zone. Default is <constant>P1D</constant> (1 day).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="managed-keys"><info><title><command>managed-keys</command> Statement Grammar</title></info>
|
||||
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="managed-keys.grammar.xml"/>
|
||||
</section>
|
||||
|
|
@ -11878,6 +12106,17 @@ view "external" {
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>dnssec-policy</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The key and signing policy for this zone. Set to
|
||||
<userinput>"default"</userinput> if you want to make use
|
||||
of the default policy.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>dnssec-update-mode</command></term>
|
||||
<listitem>
|
||||
|
|
|
|||
30
doc/arm/dnssec-policy.grammar.xml
Normal file
30
doc/arm/dnssec-policy.grammar.xml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<!--
|
||||
- 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-options.pl -->
|
||||
|
||||
<programlisting>
|
||||
<command>dnssec-policy</command> <replaceable>string</replaceable> {
|
||||
<command>dnskey-ttl</command> <replaceable>ttlval</replaceable>;
|
||||
<command>keys</command> { ( csk | ksk | zsk ) key-directory <replaceable>duration</replaceable> <replaceable>integer</replaceable> [ <replaceable>integer</replaceable> ] ; ... };
|
||||
<command>parent-ds-ttl</command> <replaceable>duration</replaceable>;
|
||||
<command>parent-propagation-delay</command> <replaceable>duration</replaceable>;
|
||||
<command>parent-registration-delay</command> <replaceable>duration</replaceable>;
|
||||
<command>publish-safety</command> <replaceable>duration</replaceable>;
|
||||
<command>retire-safety</command> <replaceable>duration</replaceable>;
|
||||
<command>signatures-refresh</command> <replaceable>duration</replaceable>;
|
||||
<command>signatures-validity</command> <replaceable>duration</replaceable>;
|
||||
<command>signatures-validity-dnskey</command> <replaceable>duration</replaceable>;
|
||||
<command>zone-max-ttl</command> <replaceable>duration</replaceable>;
|
||||
<command>zone-propagation-delay</command> <replaceable>duration</replaceable>;
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
|
|
@ -15,30 +15,50 @@
|
|||
<section><info><title>Converting from insecure to secure</title></info>
|
||||
|
||||
</section>
|
||||
<para>Changing a zone from insecure to secure can be done in two
|
||||
ways: using a dynamic DNS update, or the
|
||||
<command>auto-dnssec</command> zone option.</para>
|
||||
<para>For either method, you need to configure
|
||||
<command>named</command> so that it can see the
|
||||
<filename>K*</filename> files which contain the public and private
|
||||
parts of the keys that will be used to sign the zone. These files
|
||||
will have been generated by
|
||||
<command>dnssec-keygen</command>. You can do this by placing them
|
||||
in the key-directory, as specified in
|
||||
<filename>named.conf</filename>:</para>
|
||||
<programlisting>
|
||||
<para>
|
||||
Changing a zone from insecure to secure can be done in three
|
||||
ways: using a dynamic DNS update, use the
|
||||
<command>auto-dnssec</command> zone option, or set a DNSSEC
|
||||
policy for the zone with <command>dnssec-policy</command>.
|
||||
</para>
|
||||
<para>
|
||||
For either method, you need to configure
|
||||
<command>named</command> so that it can see the
|
||||
<filename>K*</filename> files which contain the public and private
|
||||
parts of the keys that will be used to sign the zone. These files
|
||||
will have been generated by
|
||||
<command>dnssec-keygen</command> (or created when needed by
|
||||
<command>named</command> if <command>dnssec-policy</command> is
|
||||
used). Keys should be placed in the key-directory, as specified in
|
||||
<filename>named.conf</filename>:</para>
|
||||
<programlisting>
|
||||
zone example.net {
|
||||
type master;
|
||||
update-policy local;
|
||||
file "dynamic/example.net/example.net";
|
||||
key-directory "dynamic/example.net";
|
||||
};
|
||||
</programlisting>
|
||||
<para>If one KSK and one ZSK DNSKEY key have been generated, this
|
||||
configuration will cause all records in the zone to be signed
|
||||
with the ZSK, and the DNSKEY RRset to be signed with the KSK as
|
||||
well. An NSEC chain will be generated as part of the initial
|
||||
signing process.</para>
|
||||
</programlisting>
|
||||
<para>
|
||||
If one KSK and one ZSK DNSKEY key have been generated, this
|
||||
configuration will cause all records in the zone to be signed
|
||||
with the ZSK, and the DNSKEY RRset to be signed with the KSK as
|
||||
well. An NSEC chain will be generated as part of the initial
|
||||
signing process.
|
||||
</para>
|
||||
<para>
|
||||
With <command>dnssec-policy</command> you specify what keys should
|
||||
be KSK and/or ZSK. If you want a key to sign all records with a key
|
||||
you will need to specify a CSK:
|
||||
</para>
|
||||
<programlisting>
|
||||
dnssec-policy csk {
|
||||
keys {
|
||||
csk key-directory lifetime P5Y algorithm 13;
|
||||
};
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
<section><info><title>Dynamic DNS update method</title></info>
|
||||
|
||||
</section>
|
||||
|
|
@ -50,16 +70,20 @@
|
|||
> update add example.net DNSKEY 257 3 7 AwEAAd/7odU/64o2LGsifbLtQmtO8dFDtTAZXSX2+X3e/UNlq9IHq3Y0 XtC0Iuawl/qkaKVxXe2lo8Ct+dM6UehyCqk=
|
||||
> send
|
||||
</screen>
|
||||
<para>While the update request will complete almost immediately,
|
||||
the zone will not be completely signed until
|
||||
<command>named</command> has had time to walk the zone and
|
||||
generate the NSEC and RRSIG records. The NSEC record at the apex
|
||||
will be added last, to signal that there is a complete NSEC
|
||||
chain.</para>
|
||||
<para>If you wish to sign using NSEC3 instead of NSEC, you should
|
||||
add an NSEC3PARAM record to the initial update request. If you
|
||||
wish the NSEC3 chain to have the OPTOUT bit set, set it in the
|
||||
flags field of the NSEC3PARAM record.</para>
|
||||
<para>
|
||||
While the update request will complete almost immediately,
|
||||
the zone will not be completely signed until
|
||||
<command>named</command> has had time to walk the zone and
|
||||
generate the NSEC and RRSIG records. The NSEC record at the apex
|
||||
will be added last, to signal that there is a complete NSEC
|
||||
chain.
|
||||
</para>
|
||||
<para>
|
||||
If you wish to sign using NSEC3 instead of NSEC, you should
|
||||
add an NSEC3PARAM record to the initial update request. If you
|
||||
wish the NSEC3 chain to have the OPTOUT bit set, set it in the
|
||||
flags field of the NSEC3PARAM record.
|
||||
</para>
|
||||
<screen>
|
||||
% nsupdate
|
||||
> ttl 3600
|
||||
|
|
@ -68,90 +92,113 @@
|
|||
> update add example.net NSEC3PARAM 1 1 100 1234567890
|
||||
> send
|
||||
</screen>
|
||||
<para>Again, this update request will complete almost
|
||||
immediately; however, the record won't show up until
|
||||
<command>named</command> has had a chance to build/remove the
|
||||
relevant chain. A private type record will be created to record
|
||||
the state of the operation (see below for more details), and will
|
||||
be removed once the operation completes.</para>
|
||||
<para>While the initial signing and NSEC/NSEC3 chain generation
|
||||
is happening, other updates are possible as well.</para>
|
||||
<para>
|
||||
Again, this update request will complete almost
|
||||
immediately; however, the record won't show up until
|
||||
<command>named</command> has had a chance to build/remove the
|
||||
relevant chain. A private type record will be created to record
|
||||
the state of the operation (see below for more details), and will
|
||||
be removed once the operation completes.
|
||||
</para>
|
||||
<para>
|
||||
While the initial signing and NSEC/NSEC3 chain generation
|
||||
is happening, other updates are possible as well.
|
||||
</para>
|
||||
|
||||
<section><info><title>Fully automatic zone signing</title></info>
|
||||
|
||||
</section>
|
||||
<para>To enable automatic signing, add the
|
||||
<command>auto-dnssec</command> option to the zone statement in
|
||||
<filename>named.conf</filename>.
|
||||
<command>auto-dnssec</command> has two possible arguments:
|
||||
<constant>allow</constant> or
|
||||
<constant>maintain</constant>.</para>
|
||||
<para>With
|
||||
<command>auto-dnssec allow</command>,
|
||||
<command>named</command> can search the key directory for keys
|
||||
matching the zone, insert them into the zone, and use them to
|
||||
sign the zone. It will do so only when it receives an
|
||||
<command>rndc sign <zonename></command>.</para>
|
||||
<para>
|
||||
<!-- TODO: this is repeated in the ARM -->
|
||||
<command>auto-dnssec maintain</command> includes the above
|
||||
functionality, but will also automatically adjust the zone's
|
||||
DNSKEY records on schedule according to the keys' timing metadata.
|
||||
(See <xref linkend="man.dnssec-keygen"/> and
|
||||
<xref linkend="man.dnssec-settime"/> for more information.)
|
||||
To enable automatic signing, you can set a
|
||||
<command>dnssec-policy</command>, or add the
|
||||
<command>auto-dnssec</command> option to the zone statement in
|
||||
<filename>named.conf</filename>.
|
||||
<command>auto-dnssec</command> has two possible arguments:
|
||||
<constant>allow</constant> or
|
||||
<constant>maintain</constant>.
|
||||
</para>
|
||||
<para>
|
||||
<command>named</command> will periodically search the key directory
|
||||
for keys matching the zone, and if the keys' metadata indicates
|
||||
that any change should be made the zone, such as adding, removing,
|
||||
or revoking a key, then that action will be carried out. By default,
|
||||
the key directory is checked for changes every 60 minutes; this period
|
||||
can be adjusted with the <option>dnssec-loadkeys-interval</option>, up
|
||||
to a maximum of 24 hours. The <command>rndc loadkeys</command> forces
|
||||
<command>named</command> to check for key updates immediately.
|
||||
With <command>auto-dnssec allow</command>,
|
||||
<command>named</command> can search the key directory for keys
|
||||
matching the zone, insert them into the zone, and use them to
|
||||
sign the zone. It will do so only when it receives an
|
||||
<command>rndc sign <zonename></command>.
|
||||
</para>
|
||||
<para>
|
||||
If keys are present in the key directory the first time the zone
|
||||
is loaded, the zone will be signed immediately, without waiting for an
|
||||
<command>rndc sign</command> or <command>rndc loadkeys</command>
|
||||
command. (Those commands can still be used when there are unscheduled
|
||||
key changes, however.)
|
||||
<!-- TODO: this is repeated in the ARM -->
|
||||
<command>auto-dnssec maintain</command> includes the above
|
||||
functionality, but will also automatically adjust the zone's
|
||||
DNSKEY records on schedule according to the keys' timing metadata.
|
||||
(See <xref linkend="man.dnssec-keygen"/> and
|
||||
<xref linkend="man.dnssec-settime"/> for more information.)
|
||||
</para>
|
||||
<para>
|
||||
When new keys are added to a zone, the TTL is set to match that
|
||||
of any existing DNSKEY RRset. If there is no existing DNSKEY RRset,
|
||||
then the TTL will be set to the TTL specified when the key was
|
||||
created (using the <command>dnssec-keygen -L</command> option), if
|
||||
any, or to the SOA TTL.
|
||||
<command>dnssec-policy</command> is like
|
||||
<command>auto-dnssec maintain</command>, but will also automatically
|
||||
create new keys when necessary. Also any configuration related
|
||||
to DNSSEC signing is retrieved from the policy (ignoring existing
|
||||
DNSSEC named.conf options).
|
||||
</para>
|
||||
<para>
|
||||
If you wish the zone to be signed using NSEC3 instead of NSEC,
|
||||
submit an NSEC3PARAM record via dynamic update prior to the
|
||||
scheduled publication and activation of the keys. If you wish the
|
||||
NSEC3 chain to have the OPTOUT bit set, set it in the flags field
|
||||
of the NSEC3PARAM record. The NSEC3PARAM record will not appear in
|
||||
the zone immediately, but it will be stored for later reference. When
|
||||
the zone is signed and the NSEC3 chain is completed, the NSEC3PARAM
|
||||
record will appear in the zone.
|
||||
<command>named</command> will periodically search the key directory
|
||||
for keys matching the zone, and if the keys' metadata indicates
|
||||
that any change should be made the zone, such as adding, removing,
|
||||
or revoking a key, then that action will be carried out. By default,
|
||||
the key directory is checked for changes every 60 minutes; this period
|
||||
can be adjusted with the <option>dnssec-loadkeys-interval</option>, up
|
||||
to a maximum of 24 hours. The <command>rndc loadkeys</command> forces
|
||||
<command>named</command> to check for key updates immediately.
|
||||
</para>
|
||||
<para>Using the
|
||||
<command>auto-dnssec</command> option requires the zone to be
|
||||
configured to allow dynamic updates, by adding an
|
||||
<command>allow-update</command> or
|
||||
<command>update-policy</command> statement to the zone
|
||||
configuration. If this has not been done, the configuration will
|
||||
fail.</para>
|
||||
<para>
|
||||
If keys are present in the key directory the first time the zone
|
||||
is loaded, the zone will be signed immediately, without waiting for an
|
||||
<command>rndc sign</command> or <command>rndc loadkeys</command>
|
||||
command. (Those commands can still be used when there are unscheduled
|
||||
key changes, however.)
|
||||
</para>
|
||||
<para>
|
||||
When new keys are added to a zone, the TTL is set to match that
|
||||
of any existing DNSKEY RRset. If there is no existing DNSKEY RRset,
|
||||
then the TTL will be set to the TTL specified when the key was
|
||||
created (using the <command>dnssec-keygen -L</command> option), if
|
||||
any, or to the SOA TTL.
|
||||
</para>
|
||||
<para>
|
||||
If you wish the zone to be signed using NSEC3 instead of NSEC,
|
||||
submit an NSEC3PARAM record via dynamic update prior to the
|
||||
scheduled publication and activation of the keys. If you wish the
|
||||
NSEC3 chain to have the OPTOUT bit set, set it in the flags field
|
||||
of the NSEC3PARAM record. The NSEC3PARAM record will not appear in
|
||||
the zone immediately, but it will be stored for later reference. When
|
||||
the zone is signed and the NSEC3 chain is completed, the NSEC3PARAM
|
||||
record will appear in the zone.
|
||||
</para>
|
||||
<para>
|
||||
Using the
|
||||
<command>auto-dnssec</command> option requires the zone to be
|
||||
configured to allow dynamic updates, by adding an
|
||||
<command>allow-update</command> or
|
||||
<command>update-policy</command> statement to the zone
|
||||
configuration. If this has not been done, the configuration will
|
||||
fail.
|
||||
</para>
|
||||
|
||||
<section><info><title>Private-type records</title></info>
|
||||
|
||||
</section>
|
||||
<para>The state of the signing process is signaled by
|
||||
private-type records (with a default type value of 65534). When
|
||||
signing is complete, these records will have a nonzero value for
|
||||
the final octet (for those records which have a nonzero initial
|
||||
octet).</para>
|
||||
<para>The private type record format: If the first octet is
|
||||
non-zero then the record indicates that the zone needs to be
|
||||
signed with the key matching the record, or that all signatures
|
||||
that match the record should be removed.</para>
|
||||
<para>
|
||||
The state of the signing process is signaled by
|
||||
private-type records (with a default type value of 65534). When
|
||||
signing is complete, these records will have a nonzero value for
|
||||
the final octet (for those records which have a nonzero initial
|
||||
octet).
|
||||
</para>
|
||||
<para>
|
||||
The private type record format: If the first octet is
|
||||
non-zero then the record indicates that the zone needs to be
|
||||
signed with the key matching the record, or that all signatures
|
||||
that match the record should be removed.
|
||||
</para>
|
||||
<para>
|
||||
<literallayout>
|
||||
<!-- TODO: how to format this? -->
|
||||
|
|
@ -161,14 +208,18 @@
|
|||
complete flag (octet 5)
|
||||
</literallayout>
|
||||
</para>
|
||||
<para>Only records flagged as "complete" can be removed via
|
||||
dynamic update. Attempts to remove other private type records
|
||||
will be silently ignored.</para>
|
||||
<para>If the first octet is zero (this is a reserved algorithm
|
||||
number that should never appear in a DNSKEY record) then the
|
||||
record indicates changes to the NSEC3 chains are in progress. The
|
||||
rest of the record contains an NSEC3PARAM record. The flag field
|
||||
tells what operation to perform based on the flag bits.</para>
|
||||
<para>
|
||||
Only records flagged as "complete" can be removed via
|
||||
dynamic update. Attempts to remove other private type records
|
||||
will be silently ignored.
|
||||
</para>
|
||||
<para>
|
||||
If the first octet is zero (this is a reserved algorithm
|
||||
number that should never appear in a DNSKEY record) then the
|
||||
record indicates changes to the NSEC3 chains are in progress. The
|
||||
rest of the record contains an NSEC3PARAM record. The flag field
|
||||
tells what operation to perform based on the flag bits.
|
||||
</para>
|
||||
<para>
|
||||
<literallayout>
|
||||
<!-- TODO: how to format this? -->
|
||||
|
|
@ -181,106 +232,139 @@
|
|||
<section><info><title>DNSKEY rollovers</title></info>
|
||||
|
||||
</section>
|
||||
<para>As with insecure-to-secure conversions, rolling DNSSEC
|
||||
keys can be done in two ways: using a dynamic DNS update, or the
|
||||
<command>auto-dnssec</command> zone option.</para>
|
||||
<para>
|
||||
As with insecure-to-secure conversions, rolling DNSSEC
|
||||
keys can be done in two ways: using a dynamic DNS update, or the
|
||||
<command>auto-dnssec</command> zone option.
|
||||
</para>
|
||||
|
||||
<section><info><title>Dynamic DNS update method</title></info>
|
||||
|
||||
</section>
|
||||
<para> To perform key rollovers via dynamic update, you need to add
|
||||
the <filename>K*</filename> files for the new keys so that
|
||||
<command>named</command> can find them. You can then add the new
|
||||
DNSKEY RRs via dynamic update.
|
||||
<command>named</command> will then cause the zone to be signed
|
||||
with the new keys. When the signing is complete the private type
|
||||
records will be updated so that the last octet is non
|
||||
zero.</para>
|
||||
<para>If this is for a KSK you need to inform the parent and any
|
||||
trust anchor repositories of the new KSK.</para>
|
||||
<para>You should then wait for the maximum TTL in the zone before
|
||||
removing the old DNSKEY. If it is a KSK that is being updated,
|
||||
you also need to wait for the DS RRset in the parent to be
|
||||
updated and its TTL to expire. This ensures that all clients will
|
||||
be able to verify at least one signature when you remove the old
|
||||
DNSKEY.</para>
|
||||
<para>The old DNSKEY can be removed via UPDATE. Take care to
|
||||
specify the correct key.
|
||||
<command>named</command> will clean out any signatures generated
|
||||
by the old key after the update completes.</para>
|
||||
<para>
|
||||
To perform key rollovers via dynamic update, you need to add
|
||||
the <filename>K*</filename> files for the new keys so that
|
||||
<command>named</command> can find them. You can then add the new
|
||||
DNSKEY RRs via dynamic update.
|
||||
<command>named</command> will then cause the zone to be signed
|
||||
with the new keys. When the signing is complete the private type
|
||||
records will be updated so that the last octet is non
|
||||
zero.
|
||||
</para>
|
||||
<para>
|
||||
If this is for a KSK you need to inform the parent and any
|
||||
trust anchor repositories of the new KSK.
|
||||
</para>
|
||||
<para>
|
||||
You should then wait for the maximum TTL in the zone before
|
||||
removing the old DNSKEY. If it is a KSK that is being updated,
|
||||
you also need to wait for the DS RRset in the parent to be
|
||||
updated and its TTL to expire. This ensures that all clients will
|
||||
be able to verify at least one signature when you remove the old
|
||||
DNSKEY.
|
||||
</para>
|
||||
<para>
|
||||
The old DNSKEY can be removed via UPDATE. Take care to
|
||||
specify the correct key.
|
||||
<command>named</command> will clean out any signatures generated
|
||||
by the old key after the update completes.
|
||||
</para>
|
||||
|
||||
<section><info><title>Automatic key rollovers</title></info>
|
||||
|
||||
</section>
|
||||
<para>When a new key reaches its activation date (as set by
|
||||
<command>dnssec-keygen</command> or <command>dnssec-settime</command>),
|
||||
if the <command>auto-dnssec</command> zone option is set to
|
||||
<constant>maintain</constant>, <command>named</command> will
|
||||
automatically carry out the key rollover. If the key's algorithm
|
||||
has not previously been used to sign the zone, then the zone will
|
||||
be fully signed as quickly as possible. However, if the new key
|
||||
is replacing an existing key of the same algorithm, then the
|
||||
zone will be re-signed incrementally, with signatures from the
|
||||
old key being replaced with signatures from the new key as their
|
||||
signature validity periods expire. By default, this rollover
|
||||
completes in 30 days, after which it will be safe to remove the
|
||||
old key from the DNSKEY RRset.</para>
|
||||
<para>
|
||||
When a new key reaches its activation date (as set by
|
||||
<command>dnssec-keygen</command> or <command>dnssec-settime</command>),
|
||||
if the <command>auto-dnssec</command> zone option is set to
|
||||
<constant>maintain</constant>, <command>named</command> will
|
||||
automatically carry out the key rollover. If the key's algorithm
|
||||
has not previously been used to sign the zone, then the zone will
|
||||
be fully signed as quickly as possible. However, if the new key
|
||||
is replacing an existing key of the same algorithm, then the
|
||||
zone will be re-signed incrementally, with signatures from the
|
||||
old key being replaced with signatures from the new key as their
|
||||
signature validity periods expire. By default, this rollover
|
||||
completes in 30 days, after which it will be safe to remove the
|
||||
old key from the DNSKEY RRset.
|
||||
</para>
|
||||
|
||||
<section><info><title>NSEC3PARAM rollovers via UPDATE</title></info>
|
||||
|
||||
</section>
|
||||
<para>Add the new NSEC3PARAM record via dynamic update. When the
|
||||
new NSEC3 chain has been generated, the NSEC3PARAM flag field
|
||||
will be zero. At this point you can remove the old NSEC3PARAM
|
||||
record. The old chain will be removed after the update request
|
||||
completes.</para>
|
||||
<para>
|
||||
Add the new NSEC3PARAM record via dynamic update. When the
|
||||
new NSEC3 chain has been generated, the NSEC3PARAM flag field
|
||||
will be zero. At this point you can remove the old NSEC3PARAM
|
||||
record. The old chain will be removed after the update request
|
||||
completes.
|
||||
</para>
|
||||
|
||||
<section><info><title>Converting from NSEC to NSEC3</title></info>
|
||||
|
||||
</section>
|
||||
<para>To do this, you just need to add an NSEC3PARAM record. When
|
||||
the conversion is complete, the NSEC chain will have been removed
|
||||
and the NSEC3PARAM record will have a zero flag field. The NSEC3
|
||||
chain will be generated before the NSEC chain is
|
||||
destroyed.</para>
|
||||
<para>
|
||||
To do this, you just need to add an NSEC3PARAM record. When
|
||||
the conversion is complete, the NSEC chain will have been removed
|
||||
and the NSEC3PARAM record will have a zero flag field. The NSEC3
|
||||
chain will be generated before the NSEC chain is
|
||||
destroyed.
|
||||
</para>
|
||||
<para>
|
||||
NSEC3 is not supported yet with <command>dnssec-policy</command>.
|
||||
</para>
|
||||
|
||||
<section><info><title>Converting from NSEC3 to NSEC</title></info>
|
||||
|
||||
</section>
|
||||
<para>To do this, use <command>nsupdate</command> to
|
||||
remove all NSEC3PARAM records with a zero flag
|
||||
field. The NSEC chain will be generated before the NSEC3 chain is
|
||||
removed.</para>
|
||||
<para>
|
||||
To do this, use <command>nsupdate</command> to
|
||||
remove all NSEC3PARAM records with a zero flag
|
||||
field. The NSEC chain will be generated before the NSEC3 chain is
|
||||
removed.
|
||||
</para>
|
||||
|
||||
<section><info><title>Converting from secure to insecure</title></info>
|
||||
|
||||
</section>
|
||||
<para>To convert a signed zone to unsigned using dynamic DNS,
|
||||
delete all the DNSKEY records from the zone apex using
|
||||
<command>nsupdate</command>. All signatures, NSEC or NSEC3 chains,
|
||||
and associated NSEC3PARAM records will be removed automatically.
|
||||
This will take place after the update request completes.</para>
|
||||
<para> This requires the
|
||||
<command>dnssec-secure-to-insecure</command> option to be set to
|
||||
<userinput>yes</userinput> in
|
||||
<filename>named.conf</filename>.</para>
|
||||
<para>In addition, if the <command>auto-dnssec maintain</command>
|
||||
zone statement is used, it should be removed or changed to
|
||||
<command>allow</command> instead (or it will re-sign).
|
||||
<para>
|
||||
To convert a signed zone to unsigned using dynamic DNS,
|
||||
delete all the DNSKEY records from the zone apex using
|
||||
<command>nsupdate</command>. All signatures, NSEC or NSEC3 chains,
|
||||
and associated NSEC3PARAM records will be removed automatically.
|
||||
This will take place after the update request completes.</para>
|
||||
<para> This requires the
|
||||
<command>dnssec-secure-to-insecure</command> option to be set to
|
||||
<userinput>yes</userinput> in
|
||||
<filename>named.conf</filename>.</para>
|
||||
<para>In addition, if the <command>auto-dnssec maintain</command>
|
||||
zone statement is used, it should be removed or changed to
|
||||
<command>allow</command> instead (or it will re-sign).
|
||||
</para>
|
||||
|
||||
<section><info><title>Periodic re-signing</title></info>
|
||||
|
||||
</section>
|
||||
<para>In any secure zone which supports dynamic updates, <command>named</command>
|
||||
will periodically re-sign RRsets which have not been re-signed as
|
||||
a result of some update action. The signature lifetimes will be
|
||||
adjusted so as to spread the re-sign load over time rather than
|
||||
all at once.</para>
|
||||
<para>
|
||||
In any secure zone which supports dynamic updates, <command>named</command>
|
||||
will periodically re-sign RRsets which have not been re-signed as
|
||||
a result of some update action. The signature lifetimes will be
|
||||
adjusted so as to spread the re-sign load over time rather than
|
||||
all at once.
|
||||
</para>
|
||||
|
||||
<section><info><title>NSEC3 and OPTOUT</title></info>
|
||||
|
||||
</section>
|
||||
<para>
|
||||
<command>named</command> only supports creating new NSEC3 chains
|
||||
where all the NSEC3 records in the zone have the same OPTOUT
|
||||
state.
|
||||
<command>named</command> supports UPDATES to zones where the NSEC3
|
||||
records in the chain have mixed OPTOUT state.
|
||||
<command>named</command> does not support changing the OPTOUT
|
||||
state of an individual NSEC3 record, the entire chain needs to be
|
||||
changed if the OPTOUT state of an individual NSEC3 needs to be
|
||||
changed.</para>
|
||||
<command>named</command> only supports creating new NSEC3 chains
|
||||
where all the NSEC3 records in the zone have the same OPTOUT
|
||||
state.
|
||||
<command>named</command> supports UPDATES to zones where the NSEC3
|
||||
records in the chain have mixed OPTOUT state.
|
||||
<command>named</command> does not support changing the OPTOUT
|
||||
state of an individual NSEC3 record, the entire chain needs to be
|
||||
changed if the OPTOUT state of an individual NSEC3 needs to be
|
||||
changed.
|
||||
</para>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
<command>dnskey-sig-validity</command> <replaceable>integer</replaceable>;
|
||||
<command>dnssec-dnskey-kskonly</command> <replaceable>boolean</replaceable>;
|
||||
<command>dnssec-loadkeys-interval</command> <replaceable>integer</replaceable>;
|
||||
<command>dnssec-policy</command> <replaceable>string</replaceable>;
|
||||
<command>dnssec-secure-to-insecure</command> <replaceable>boolean</replaceable>;
|
||||
<command>dnssec-update-mode</command> ( maintain | no-resign );
|
||||
<command>file</command> <replaceable>quoted_string</replaceable>;
|
||||
|
|
@ -51,7 +52,7 @@
|
|||
<command>max-records</command> <replaceable>integer</replaceable>;
|
||||
<command>max-transfer-idle-out</command> <replaceable>integer</replaceable>;
|
||||
<command>max-transfer-time-out</command> <replaceable>integer</replaceable>;
|
||||
<command>max-zone-ttl</command> ( unlimited | <replaceable>ttlval</replaceable> );
|
||||
<command>max-zone-ttl</command> ( unlimited | <replaceable>duration</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> ];
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
[ 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> ]; ... } ] [ zone-directory <replaceable>quoted_string</replaceable> ] [
|
||||
<command>in-memory</command> <replaceable>boolean</replaceable> ] [ min-update-interval <replaceable>ttlval</replaceable> ]; ... };
|
||||
<command>in-memory</command> <replaceable>boolean</replaceable> ] [ min-update-interval <replaceable>duration</replaceable> ]; ... };
|
||||
<command>check-dup-records</command> ( fail | warn | ignore );
|
||||
<command>check-integrity</command> <replaceable>boolean</replaceable>;
|
||||
<command>check-mx</command> ( fail | warn | ignore );
|
||||
|
|
@ -127,18 +127,18 @@
|
|||
<command>fstrm-set-output-notify-threshold</command> <replaceable>integer</replaceable>;
|
||||
<command>fstrm-set-output-queue-model</command> ( mpsc | spsc );
|
||||
<command>fstrm-set-output-queue-size</command> <replaceable>integer</replaceable>;
|
||||
<command>fstrm-set-reopen-interval</command> <replaceable>ttlval</replaceable>;
|
||||
<command>fstrm-set-reopen-interval</command> <replaceable>duration</replaceable>;
|
||||
<command>geoip-directory</command> ( <replaceable>quoted_string</replaceable> | none );
|
||||
<command>glue-cache</command> <replaceable>boolean</replaceable>;
|
||||
<command>heartbeat-interval</command> <replaceable>integer</replaceable>;
|
||||
<command>hostname</command> ( <replaceable>quoted_string</replaceable> | none );
|
||||
<command>inline-signing</command> <replaceable>boolean</replaceable>;
|
||||
<command>interface-interval</command> <replaceable>ttlval</replaceable>;
|
||||
<command>interface-interval</command> <replaceable>duration</replaceable>;
|
||||
<command>ixfr-from-differences</command> ( primary | master | secondary | slave |
|
||||
<replaceable>boolean</replaceable> );
|
||||
<command>keep-response-order</command> { <replaceable>address_match_element</replaceable>; ... };
|
||||
<command>key-directory</command> <replaceable>quoted_string</replaceable>;
|
||||
<command>lame-ttl</command> <replaceable>ttlval</replaceable>;
|
||||
<command>lame-ttl</command> <replaceable>duration</replaceable>;
|
||||
<command>listen-on</command> [ port <replaceable>integer</replaceable> ] [ dscp
|
||||
<replaceable>integer</replaceable> ] {
|
||||
<replaceable>address_match_element</replaceable>; ... };
|
||||
|
|
@ -152,28 +152,28 @@
|
|||
<command>masterfile-style</command> ( full | relative );
|
||||
<command>match-mapped-addresses</command> <replaceable>boolean</replaceable>;
|
||||
<command>max-cache-size</command> ( default | unlimited | <replaceable>sizeval</replaceable> | <replaceable>percentage</replaceable> );
|
||||
<command>max-cache-ttl</command> <replaceable>ttlval</replaceable>;
|
||||
<command>max-cache-ttl</command> <replaceable>duration</replaceable>;
|
||||
<command>max-clients-per-query</command> <replaceable>integer</replaceable>;
|
||||
<command>max-journal-size</command> ( default | unlimited | <replaceable>sizeval</replaceable> );
|
||||
<command>max-ncache-ttl</command> <replaceable>ttlval</replaceable>;
|
||||
<command>max-ncache-ttl</command> <replaceable>duration</replaceable>;
|
||||
<command>max-records</command> <replaceable>integer</replaceable>;
|
||||
<command>max-recursion-depth</command> <replaceable>integer</replaceable>;
|
||||
<command>max-recursion-queries</command> <replaceable>integer</replaceable>;
|
||||
<command>max-refresh-time</command> <replaceable>integer</replaceable>;
|
||||
<command>max-retry-time</command> <replaceable>integer</replaceable>;
|
||||
<command>max-rsa-exponent-size</command> <replaceable>integer</replaceable>;
|
||||
<command>max-stale-ttl</command> <replaceable>ttlval</replaceable>;
|
||||
<command>max-stale-ttl</command> <replaceable>duration</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>max-udp-size</command> <replaceable>integer</replaceable>;
|
||||
<command>max-zone-ttl</command> ( unlimited | <replaceable>ttlval</replaceable> );
|
||||
<command>max-zone-ttl</command> ( unlimited | <replaceable>duration</replaceable> );
|
||||
<command>memstatistics</command> <replaceable>boolean</replaceable>;
|
||||
<command>memstatistics-file</command> <replaceable>quoted_string</replaceable>;
|
||||
<command>message-compression</command> <replaceable>boolean</replaceable>;
|
||||
<command>min-cache-ttl</command> <replaceable>ttlval</replaceable>;
|
||||
<command>min-ncache-ttl</command> <replaceable>ttlval</replaceable>;
|
||||
<command>min-cache-ttl</command> <replaceable>duration</replaceable>;
|
||||
<command>min-ncache-ttl</command> <replaceable>duration</replaceable>;
|
||||
<command>min-refresh-time</command> <replaceable>integer</replaceable>;
|
||||
<command>min-retry-time</command> <replaceable>integer</replaceable>;
|
||||
<command>minimal-any</command> <replaceable>boolean</replaceable>;
|
||||
|
|
@ -190,8 +190,8 @@
|
|||
<command>notify-source-v6</command> ( <replaceable>ipv6_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ]
|
||||
[ dscp <replaceable>integer</replaceable> ];
|
||||
<command>notify-to-soa</command> <replaceable>boolean</replaceable>;
|
||||
<command>nta-lifetime</command> <replaceable>ttlval</replaceable>;
|
||||
<command>nta-recheck</command> <replaceable>ttlval</replaceable>;
|
||||
<command>nta-lifetime</command> <replaceable>duration</replaceable>;
|
||||
<command>nta-recheck</command> <replaceable>duration</replaceable>;
|
||||
<command>nxdomain-redirect</command> <replaceable>string</replaceable>;
|
||||
<command>pid-file</command> ( <replaceable>quoted_string</replaceable> | none );
|
||||
<command>port</command> <replaceable>integer</replaceable>;
|
||||
|
|
@ -238,13 +238,13 @@
|
|||
<command>response-padding</command> { <replaceable>address_match_element</replaceable>; ... } block-size
|
||||
<replaceable>integer</replaceable>;
|
||||
<command>response-policy</command> { zone <replaceable>string</replaceable> [ add-soa <replaceable>boolean</replaceable> ] [ log
|
||||
<replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>ttlval</replaceable> ] [ min-update-interval
|
||||
<replaceable>ttlval</replaceable> ] [ policy ( cname | disabled | drop | given | no-op |
|
||||
<replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>duration</replaceable> ] [ min-update-interval
|
||||
<replaceable>duration</replaceable> ] [ policy ( cname | disabled | drop | given | no-op |
|
||||
<command>nodata</command> | nxdomain | passthru | tcp-only <replaceable>quoted_string</replaceable> ) ] [
|
||||
<command>recursive-only</command> <replaceable>boolean</replaceable> ] [ nsip-enable <replaceable>boolean</replaceable> ] [
|
||||
<command>nsdname-enable</command> <replaceable>boolean</replaceable> ]; ... } [ add-soa <replaceable>boolean</replaceable> ] [
|
||||
<command>break-dnssec</command> <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>ttlval</replaceable> ] [
|
||||
<command>min-update-interval</command> <replaceable>ttlval</replaceable> ] [ min-ns-dots <replaceable>integer</replaceable> ] [
|
||||
<command>break-dnssec</command> <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>duration</replaceable> ] [
|
||||
<command>min-update-interval</command> <replaceable>duration</replaceable> ] [ min-ns-dots <replaceable>integer</replaceable> ] [
|
||||
<command>nsip-wait-recurse</command> <replaceable>boolean</replaceable> ] [ qname-wait-recurse <replaceable>boolean</replaceable> ]
|
||||
[ recursive-only <replaceable>boolean</replaceable> ] [ nsip-enable <replaceable>boolean</replaceable> ] [
|
||||
<command>nsdname-enable</command> <replaceable>boolean</replaceable> ] [ dnsrps-enable <replaceable>boolean</replaceable> ] [
|
||||
|
|
@ -258,7 +258,7 @@
|
|||
<command>serial-query-rate</command> <replaceable>integer</replaceable>;
|
||||
<command>serial-update-method</command> ( date | increment | unixtime );
|
||||
<command>server-id</command> ( <replaceable>quoted_string</replaceable> | none | hostname );
|
||||
<command>servfail-ttl</command> <replaceable>ttlval</replaceable>;
|
||||
<command>servfail-ttl</command> <replaceable>duration</replaceable>;
|
||||
<command>session-keyalg</command> <replaceable>string</replaceable>;
|
||||
<command>session-keyfile</command> ( <replaceable>quoted_string</replaceable> | none );
|
||||
<command>session-keyname</command> <replaceable>string</replaceable>;
|
||||
|
|
@ -269,7 +269,7 @@
|
|||
<command>sortlist</command> { <replaceable>address_match_element</replaceable>; ... };
|
||||
<command>stacksize</command> ( default | unlimited | <replaceable>sizeval</replaceable> );
|
||||
<command>stale-answer-enable</command> <replaceable>boolean</replaceable>;
|
||||
<command>stale-answer-ttl</command> <replaceable>ttlval</replaceable>;
|
||||
<command>stale-answer-ttl</command> <replaceable>duration</replaceable>;
|
||||
<command>startup-notify-rate</command> <replaceable>integer</replaceable>;
|
||||
<command>statistics-file</command> <replaceable>quoted_string</replaceable>;
|
||||
<command>synth-from-dnssec</command> <replaceable>boolean</replaceable>;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
<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-records</command> <replaceable>integer</replaceable>;
|
||||
<command>max-zone-ttl</command> ( unlimited | <replaceable>ttlval</replaceable> );
|
||||
<command>max-zone-ttl</command> ( unlimited | <replaceable>duration</replaceable> );
|
||||
<command>zone-statistics</command> ( full | terse | none | <replaceable>boolean</replaceable> );
|
||||
};
|
||||
</programlisting>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
<command>dnskey-sig-validity</command> <replaceable>integer</replaceable>;
|
||||
<command>dnssec-dnskey-kskonly</command> <replaceable>boolean</replaceable>;
|
||||
<command>dnssec-loadkeys-interval</command> <replaceable>integer</replaceable>;
|
||||
<command>dnssec-policy</command> <replaceable>string</replaceable>;
|
||||
<command>dnssec-update-mode</command> ( maintain | no-resign );
|
||||
<command>file</command> <replaceable>quoted_string</replaceable>;
|
||||
<command>forward</command> ( first | only );
|
||||
|
|
|
|||
226
doc/design/dnssec-policy
Normal file
226
doc/design/dnssec-policy
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
|
||||
See COPYRIGHT in the source root or http://isc.org/copyright.html for terms.
|
||||
|
||||
# DNSSEC Key and Signing Policy
|
||||
|
||||
A DNSSEC key and signing policy (KASP) defines a DNSSEC policy that can be
|
||||
applied to one or more zones.
|
||||
|
||||
For some background information, see:
|
||||
|
||||
https://www.ietf.org/archive/id/draft-mekking-dnsop-kasp-00.txt
|
||||
|
||||
# DNSSEC in BIND 9
|
||||
|
||||
DNSSEC is first implemented in BIND 9. Many adaptations have been made since
|
||||
then. A lot of configuration knobs were added. One aim with introducing KASP
|
||||
configuration is that all these configuration options are grouped together,
|
||||
making the named configuration more intuitive when it comes to DNSSEC, and
|
||||
making it easier to turn on DNSSEC for zones. Instead of configuring many
|
||||
different options per zone, you would be able to do the following:
|
||||
|
||||
```
|
||||
zone "example.com." {
|
||||
...
|
||||
dnssec-policy "_default";
|
||||
};
|
||||
```
|
||||
|
||||
## Existing DNSSEC configuration options
|
||||
|
||||
### Signing
|
||||
|
||||
The following configuration options exist nowadays for `named` to maintain
|
||||
DNSSEC signed zones. These will no longer work if an explicit DNSSEC policy
|
||||
is set for a zone.
|
||||
|
||||
1. `auto-dnssec`: When setting a DNSSEC policy for a zone instead, the
|
||||
behavior will be as if `auto-dnssec` was set to `maintain`.
|
||||
|
||||
1. `dnskey-sig-validity`: This option will be replaced in favor of the KASP
|
||||
configuration value `signatures-validity-dnskey`.
|
||||
|
||||
1. `dnssec-dnskey-kskonly`: This option will be removed and the key
|
||||
configuration from the policy will be used to determine what RRsets will be
|
||||
signed with which keys (Keys will have a role "KSK" and/or "ZSK").
|
||||
|
||||
1. `dnssec-loadkeys-interval`: This option will determine how the period that
|
||||
BIND 9 will check its key repository (default once per hour) to see if
|
||||
there are new keys added or if existing keys metadata has changed. This
|
||||
option might go away because the entity that performs DNSSEC maintenance
|
||||
knows exactly when the next step needs to happen. We can set the interval
|
||||
accordingly. This does mean that whenever a new key is added or deprecated
|
||||
manually, the interval needs to be set to now. Alternatively, we keep this
|
||||
option and only pick up new keys when at a certain interval.
|
||||
|
||||
1. `dnssec-secure-to-insecure`: This option allows a dynamic zone to
|
||||
transition from secure to insecure. This seems to be a safety check
|
||||
when named is not responsible for signing. This will likely go away
|
||||
because explicitly removing the dnssec-policy will be the same signal
|
||||
to (safely) make the zone insecure.
|
||||
|
||||
1. `dnssec-update-mode`: This option determines how DNSSEC signed dynamic
|
||||
zones are updated. Default is `maintain` and it is unclear how it is
|
||||
different from `auto-dnssec`. With KASP, the behavior will be as if
|
||||
the `dnssec-update-mode` was set to `maintain`. If you want DNSSEC
|
||||
maintenance to be done outside `named`, you should not configure a
|
||||
`dnssec-policy` for that zone.
|
||||
|
||||
1. `inline-signing`: When set to "yes", this option will sign transferred
|
||||
unsigned zones, and unsigned zone from file. This is also no longer needed
|
||||
when KASP is introduced because when setting a `dnssec-policy` for a
|
||||
secondary zone or a zone with zone file, this indicates that
|
||||
`inline-signing` is desired.
|
||||
|
||||
1. `max-zone-ttl`: This will cap all TTLs in a zone file to the specified
|
||||
value. Although this option may be used for non-DNSSEC zones, it is really
|
||||
only useful for DNSSEC-signed zones because when performing key rollovers
|
||||
the timing depends on the largest TTL in the zone. The value set in the
|
||||
`dnssec-policy` statement will override the existing `max-zone-ttl` value.
|
||||
|
||||
1. `sig-signing-nodes`: This specifies the number of nodes to be examined
|
||||
in a quantum when signing a zone with a new DNSKEY. This presumable is
|
||||
to avoid keeping the database connection open for a long time. With the
|
||||
current database approach this probably needs to stay.
|
||||
|
||||
1. `sig-signing-signatures`: This specifies a threshold number of how many
|
||||
signatures will be generated in a quantum. Similar to `sig-signing-nodes`.
|
||||
|
||||
1. `sig-signing-type`: Internal record type number, used to track zone
|
||||
signing process. This likely will go away in favor of a new method.
|
||||
|
||||
1. `sig-validity-interval`: Specifies the number of days a signature is valid.
|
||||
The second optional value is the refresh interval. Thos option will
|
||||
be replaced by KASP configuration values "signatures-validity" and
|
||||
"signatures-refresh".
|
||||
|
||||
1. `update-check-ksk`: When set to "no", KSK will also sign non-DNSKEY RRsets.
|
||||
This option will go away and key roles will be used to determine what
|
||||
keys sign which RRsets (A KSK that should sign all RRsets will have both
|
||||
the KSK and ZSK role and is referred to as a CSK).
|
||||
|
||||
Other DNSSEC related configuration options that are not related to the policy
|
||||
are likely to stay:
|
||||
|
||||
1. `key-directory`: This is where the DNSKEY key files can be found.
|
||||
|
||||
1. `serial-update-method`: This is used for dynamic zones to determne how
|
||||
the SOA SERIAL should be updated. There will likely be a separate
|
||||
configuration option for the serial update method when resigning a zone.
|
||||
|
||||
|
||||
# KASP Configuration
|
||||
|
||||
The KASP Configuration may look something like the example configuration
|
||||
below. This includes all options as described in the KASP draft, but we may
|
||||
decide that some options are not required.
|
||||
|
||||
```
|
||||
dnssec-policy "nsec3" {
|
||||
|
||||
description "policy for zones that require zone walking mitigation";
|
||||
|
||||
// Signatures
|
||||
signatures-refresh P3D;
|
||||
signatures-validity P14D;
|
||||
signatures-validity-dnskey P14D;
|
||||
|
||||
// Denial of existence
|
||||
denial-type nsec3;
|
||||
nsec3-param ttl 0 hash algorithm 1 iterations 5 optout;
|
||||
nsec3-salt length 8 resalt P100D;
|
||||
|
||||
// Keys
|
||||
dnskey-ttl 3600;
|
||||
publish-safety PT3600S;
|
||||
retire-safety PT3600S;
|
||||
share-keys no;
|
||||
purge-keys-after P14D;
|
||||
|
||||
keys {
|
||||
ksk key-directory P5Y ECDSAP256SHA256;
|
||||
zsk key-directory P30D ECDSAP256SHA256;
|
||||
csk key-directory PT0S 8 2048;
|
||||
};
|
||||
|
||||
// Parent synchronization
|
||||
cds yes;
|
||||
cdnskey yes;
|
||||
check-ds { 127.0.0.53; };
|
||||
check-ds-interval PT3600S;
|
||||
|
||||
// Zone properties
|
||||
zone-propagation-delay PT3600S;
|
||||
zone-registration-delay PT3600S;
|
||||
zone-soa-ttl 3600;
|
||||
zone-soa-minimum 3600;
|
||||
zone-soa-serial-update-method unixtime;
|
||||
zone-max-ttl 24h;
|
||||
|
||||
// Parent properties
|
||||
parent-propagation-delay PT24H;
|
||||
parent-ds-ttl 3600;
|
||||
parent-soa-ttl 3600;
|
||||
parent-soa-minimum 3600;
|
||||
};
|
||||
```
|
||||
|
||||
# KASP design
|
||||
|
||||
## dnssec-policy versus dnssec-keymgr
|
||||
|
||||
Key management in BIND 9 is currently implemented with a Python script
|
||||
called `dnssec-keymgr`. It uses the DNSSEC tools for manipulating DNSSEC key
|
||||
metadata.
|
||||
|
||||
With `dnssec-policy` configured in `named.conf` you no longer need to manually
|
||||
call `dnssec-keymgr` or the tools it wraps around, `dnssec-keygen` and
|
||||
`dnssec-settime` (although it is still possible to use them). The policy in
|
||||
`named.conf` will make `named` create keys when necessary and set the key
|
||||
timings accordingly.
|
||||
|
||||
## Key roles
|
||||
|
||||
BIND 9.14 allows sign your zones with a Zone Signing Key (ZSK) and a
|
||||
Key Signing Key (KSK). If you provide only one key, the zone will be signed
|
||||
with just one key (effectively acting as a Combined Signing Key (CSK). If
|
||||
one of the keys is offline, BIND 9 will temporarily change the key usage: A
|
||||
KSK may sign DNSKEY unrelated RRsets.
|
||||
|
||||
With BIND 9.14, ZSKs by default sign the complete zone, except when
|
||||
`dnssec-dnskey-kskonly` and `update-check-ksk` are both set to `yes`.
|
||||
|
||||
KASP introduces key roles making key usage more explicit, without depending
|
||||
on state of the keys or additional configuration values. A key that has the
|
||||
KSK role will always sign only DNSKEY related RRsets, and a key with a ZSK role
|
||||
will always sign only DNSKEY unrelated RRsets. A key can have both roles, which
|
||||
is referred to as a CSK. Below is an example configuration for the three types
|
||||
of keys:
|
||||
```
|
||||
keys {
|
||||
ksk key-directory lifetime P5Y algorithm ECDSAP256SHA256;
|
||||
zsk key-directory lifetime P30D algorithm ECDSAP256SHA256;
|
||||
csk key-directory lifetime PT0S algorithm 8 2048;
|
||||
};
|
||||
```
|
||||
|
||||
## NSEC3
|
||||
|
||||
Currently if you want to sign your zone with NSEC3 you can do so by introducing
|
||||
an NSEC3PARAM record via Dynamic Update. This is no longer necessary with
|
||||
`dnssec-policy` as you can configure NSEC3 usage in `named.conf`.
|
||||
|
||||
## Changing policies
|
||||
|
||||
You can change a zone's policy by referring to a different `dnssec-policy`
|
||||
or by changing the `dnssec-policy` itself. After a reload of the configuration
|
||||
key timings may be adjusted. This may trigger a key rollover (for example if
|
||||
the key lifetimes have been shortened, or if other key properties have changed.
|
||||
|
||||
## Key state machines
|
||||
|
||||
Rollover correctness are guaranteed by key state machines. See for more
|
||||
information:
|
||||
|
||||
https://nlnetlabs.nl/downloads/publications/satin2012-Schaeffer.pdf
|
||||
|
|
@ -23,6 +23,7 @@ zone <string> [ <class> ] {
|
|||
dnskey-sig-validity <integer>;
|
||||
dnssec-dnskey-kskonly <boolean>;
|
||||
dnssec-loadkeys-interval <integer>;
|
||||
dnssec-policy <string>;
|
||||
dnssec-secure-to-insecure <boolean>;
|
||||
dnssec-update-mode ( maintain | no-resign );
|
||||
file <quoted_string>;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,22 @@ dnssec-keys { <string> ( static-key |
|
|||
initial-key ) <integer> <integer> <integer>
|
||||
<quoted_string>; ... }; // may occur multiple times
|
||||
|
||||
dnssec-policy <string> {
|
||||
dnskey-ttl <ttlval>;
|
||||
keys { ( csk | ksk | zsk ) key-directory lifetime <duration> algorithm <integer>
|
||||
[ <integer> ]; ... };
|
||||
parent-ds-ttl <duration>;
|
||||
parent-propagation-delay <duration>;
|
||||
parent-registration-delay <duration>;
|
||||
publish-safety <duration>;
|
||||
retire-safety <duration>;
|
||||
signatures-refresh <duration>;
|
||||
signatures-validity <duration>;
|
||||
signatures-validity-dnskey <duration>;
|
||||
zone-max-ttl <duration>;
|
||||
zone-propagation-delay <duration>;
|
||||
}; // may occur multiple times
|
||||
|
||||
dyndb <string> <quoted_string> {
|
||||
<unspecified-text> }; // may occur multiple times
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ zone <string> [ <class> ] {
|
|||
dnskey-sig-validity <integer>;
|
||||
dnssec-dnskey-kskonly <boolean>;
|
||||
dnssec-loadkeys-interval <integer>;
|
||||
dnssec-policy <string>;
|
||||
dnssec-update-mode ( maintain | no-resign );
|
||||
file <quoted_string>;
|
||||
forward ( first | only );
|
||||
|
|
|
|||
|
|
@ -842,6 +842,21 @@ check_name(const char *str) {
|
|||
return (dns_name_fromstring(dns_fixedname_name(&fixed), str, 0, NULL));
|
||||
}
|
||||
|
||||
static bool
|
||||
kasp_name_allowed(const cfg_listelt_t *element)
|
||||
{
|
||||
const char* name = cfg_obj_asstring(cfg_tuple_get(
|
||||
cfg_listelt_value(element), "name"));
|
||||
|
||||
if (strcmp("none", name) == 0) {
|
||||
return false;
|
||||
}
|
||||
if (strcmp("default", name) == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
||||
optlevel_t optlevel)
|
||||
|
|
@ -856,6 +871,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
|||
const char *str;
|
||||
isc_buffer_t b;
|
||||
uint32_t lifetime = 3600;
|
||||
bool has_dnssecpolicy = false;
|
||||
const char *ccalg = "siphash24";
|
||||
|
||||
/*
|
||||
|
|
@ -929,7 +945,11 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
|||
(void)cfg_map_get(options, intervals[i].name, &obj);
|
||||
if (obj == NULL)
|
||||
continue;
|
||||
val = cfg_obj_asuint32(obj);
|
||||
if (cfg_obj_isduration(obj)) {
|
||||
val = cfg_obj_asduration(obj);
|
||||
} else {
|
||||
val = cfg_obj_asuint32(obj);
|
||||
}
|
||||
if (val > intervals[i].max) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"%s '%u' is out of range (0..%u)",
|
||||
|
|
@ -944,6 +964,56 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check dnssec-policy.
|
||||
*/
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(options, "dnssec-policy", &obj);
|
||||
if (obj != NULL) {
|
||||
bool bad_kasp = false;
|
||||
bool bad_name = false;
|
||||
if (optlevel != optlevel_config && !cfg_obj_isstring(obj)) {
|
||||
bad_kasp = true;
|
||||
} else if (optlevel == optlevel_config) {
|
||||
if (cfg_obj_islist(obj)) {
|
||||
for (element = cfg_list_first(obj);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
if (!cfg_obj_istuple(
|
||||
cfg_listelt_value(element)))
|
||||
{
|
||||
bad_kasp = true;
|
||||
}
|
||||
if (!kasp_name_allowed(element)) {
|
||||
bad_name = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bad_kasp) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"dnssec-policy may only be configured at "
|
||||
"the top level, please use name reference "
|
||||
"at the zone level");
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (bad_name) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"dnssec-policy name may not be 'none' or "
|
||||
"'default' (which is the built-in policy)");
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
has_dnssecpolicy = true;
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
cfg_map_get(options, "max-rsa-exponent-size", &obj);
|
||||
if (obj != NULL) {
|
||||
|
|
@ -992,6 +1062,13 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
|||
result = ISC_R_RANGE;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_dnssecpolicy) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"sig-validity-interval: cannot be "
|
||||
"configured if dnssec-policy is also set");
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
|
|
@ -1008,6 +1085,12 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
|||
result = ISC_R_RANGE;
|
||||
}
|
||||
|
||||
if (has_dnssecpolicy) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"dnskey-sig-validity: cannot be "
|
||||
"configured if dnssec-policy is also set");
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
|
|
@ -1113,8 +1196,9 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
|||
if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS)
|
||||
result = tresult;
|
||||
}
|
||||
if (symtab != NULL)
|
||||
if (symtab != NULL) {
|
||||
isc_symtab_destroy(&symtab);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1176,7 +1260,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
|||
obj = NULL;
|
||||
(void)cfg_map_get(options, "nta-lifetime", &obj);
|
||||
if (obj != NULL) {
|
||||
lifetime = cfg_obj_asuint32(obj);
|
||||
lifetime = cfg_obj_asduration(obj);
|
||||
if (lifetime > 604800) { /* 7 days */
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"'nta-lifetime' cannot exceed one week");
|
||||
|
|
@ -1193,7 +1277,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
|||
obj = NULL;
|
||||
(void)cfg_map_get(options, "nta-recheck", &obj);
|
||||
if (obj != NULL) {
|
||||
uint32_t recheck = cfg_obj_asuint32(obj);
|
||||
uint32_t recheck = cfg_obj_asduration(obj);
|
||||
if (recheck > 604800) { /* 7 days */
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"'nta-recheck' cannot exceed one week");
|
||||
|
|
@ -1271,7 +1355,11 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
|||
if (obj == NULL)
|
||||
continue;
|
||||
|
||||
value = cfg_obj_asuint32(obj);
|
||||
if (cfg_obj_isduration(obj)) {
|
||||
value = cfg_obj_asduration(obj);
|
||||
} else {
|
||||
value = cfg_obj_asuint32(obj);
|
||||
}
|
||||
if (value < fstrm[i].min ||
|
||||
(fstrm[i].max != 0U && value > fstrm[i].max)) {
|
||||
if (fstrm[i].max != 0U)
|
||||
|
|
@ -1850,6 +1938,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
bool dlz;
|
||||
dns_masterformat_t masterformat;
|
||||
bool ddns = false;
|
||||
bool has_dnssecpolicy = false;
|
||||
const void *clauses = NULL;
|
||||
const char *option = NULL;
|
||||
static const char *acls[] = {
|
||||
|
|
@ -2062,6 +2151,45 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
if (check_nonzero(zoptions, logctx) != ISC_R_SUCCESS)
|
||||
result = ISC_R_FAILURE;
|
||||
|
||||
/*
|
||||
* Check if a dnssec-policy is set.
|
||||
*/
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(zoptions, "dnssec-policy", &obj);
|
||||
if (obj != NULL) {
|
||||
const cfg_obj_t *kasps = NULL;
|
||||
const char* kaspname = cfg_obj_asstring(obj);
|
||||
|
||||
if (strcmp(kaspname, "default") == 0) {
|
||||
has_dnssecpolicy = true;
|
||||
} else if (strcmp(kaspname, "none") == 0) {
|
||||
has_dnssecpolicy = false;
|
||||
} else {
|
||||
(void)cfg_map_get(config, "dnssec-policy", &kasps);
|
||||
for (element = cfg_list_first(kasps); element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
const char* kn = cfg_obj_asstring(
|
||||
cfg_tuple_get(cfg_listelt_value(element),
|
||||
"name"));
|
||||
if (strcmp(kaspname, kn) == 0) {
|
||||
has_dnssecpolicy = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_dnssecpolicy) {
|
||||
cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
|
||||
"zone '%s': option "
|
||||
"'dnssec-policy %s' has no "
|
||||
"matching dnssec-policy config",
|
||||
znamestr, kaspname);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check validity of the zone options.
|
||||
*/
|
||||
|
|
@ -2248,19 +2376,36 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
if (res1 == ISC_R_SUCCESS)
|
||||
signing = cfg_obj_asboolean(obj);
|
||||
|
||||
if (signing && has_dnssecpolicy) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"inline-signing: cannot be configured if "
|
||||
"dnssec-policy is also set");
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
arg = "off";
|
||||
res3 = cfg_map_get(zoptions, "auto-dnssec", &obj);
|
||||
if (res3 == ISC_R_SUCCESS)
|
||||
if (res3 == ISC_R_SUCCESS) {
|
||||
arg = cfg_obj_asstring(obj);
|
||||
if (strcasecmp(arg, "off") != 0 && !ddns && !signing) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"'auto-dnssec %s;' requires%s "
|
||||
"inline-signing to be configured for "
|
||||
"the zone", arg,
|
||||
(ztype == CFG_ZONE_MASTER) ?
|
||||
" dynamic DNS or" : "");
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
if (strcasecmp(arg, "off") != 0) {
|
||||
if (!ddns && !signing) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"'auto-dnssec %s;' requires%s "
|
||||
"inline-signing to be configured "
|
||||
"for the zone", arg,
|
||||
(ztype == CFG_ZONE_MASTER) ?
|
||||
" dynamic DNS or" : "");
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
if (has_dnssecpolicy) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"'auto-dnssec %s;' cannot be "
|
||||
"configured if dnssec-policy is "
|
||||
"also set", arg);
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
|
|
@ -2285,6 +2430,21 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
"inline-signing when used in slave zone");
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
if (res1 == ISC_R_SUCCESS && has_dnssecpolicy) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"dnssec-dnskey-kskonly: cannot be "
|
||||
"configured if dnssec-policy is also set");
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
res1 = cfg_map_get(zoptions, "dnssec-secure-to-insecure", &obj);
|
||||
if (res1 == ISC_R_SUCCESS && has_dnssecpolicy) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"dnssec-secure-to-insecure: cannot be "
|
||||
"configured if dnssec-policy is also set");
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
res1 = cfg_map_get(zoptions, "dnssec-loadkeys-interval", &obj);
|
||||
|
|
@ -2307,6 +2467,21 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
"inline-signing when used in slave zone");
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
if (res1 == ISC_R_SUCCESS && has_dnssecpolicy) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"update-check-ksk: cannot be configured "
|
||||
"if dnssec-policy is also set");
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
res1 = cfg_map_get(zoptions, "dnssec-update-mode", &obj);
|
||||
if (res1 == ISC_R_SUCCESS && has_dnssecpolicy) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"dnssec-update-mode: cannot be configured "
|
||||
"if dnssec-policy is also set");
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ DNSOBJS = acl.@O@ adb.@O@ badcache.@O@ byaddr.@O@ \
|
|||
db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \
|
||||
dlz.@O@ dns64.@O@ dnsrps.@O@ dnssec.@O@ ds.@O@ dyndb.@O@ \
|
||||
ecs.@O@ fixedname.@O@ forward.@O@ \
|
||||
ipkeylist.@O@ iptable.@O@ journal.@O@ keydata.@O@ \
|
||||
keytable.@O@ lib.@O@ log.@O@ lookup.@O@ \
|
||||
ipkeylist.@O@ iptable.@O@ journal.@O@ kasp.@O@ keydata.@O@ \
|
||||
keymgr.@O@ keytable.@O@ lib.@O@ log.@O@ lookup.@O@ \
|
||||
master.@O@ masterdump.@O@ message.@O@ \
|
||||
name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ nta.@O@ \
|
||||
order.@O@ peer.@O@ portlist.@O@ private.@O@ \
|
||||
|
|
@ -100,9 +100,9 @@ DNSSRCS = acl.c adb.c badcache. byaddr.c \
|
|||
cache.c callbacks.c clientinfo.c compress.c \
|
||||
db.c dbiterator.c dbtable.c diff.c dispatch.c \
|
||||
dlz.c dns64.c dnsrps.c dnssec.c ds.c dyndb.c \
|
||||
ecs.c fixedname.c forward.c \
|
||||
ipkeylist.c iptable.c journal.c keydata.c keytable.c lib.c \
|
||||
log.c lookup.c master.c masterdump.c message.c \
|
||||
ecs.c fixedname.c forward.c ipkeylist.c iptable.c \
|
||||
journal.c kasp.c keydata.c keymgr.c keytable.c \
|
||||
lib.c log.c lookup.c master.c masterdump.c message.c \
|
||||
name.c ncache.c nsec.c nsec3.c nta.c \
|
||||
order.c peer.c portlist.c \
|
||||
rbt.c rbtdb.c rcode.c rdata.c rdatalist.c \
|
||||
|
|
|
|||
283
lib/dns/dnssec.c
283
lib/dns/dnssec.c
|
|
@ -29,6 +29,7 @@
|
|||
#include <dns/diff.h>
|
||||
#include <dns/dnssec.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/kasp.h>
|
||||
#include <dns/keyvalues.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/message.h>
|
||||
|
|
@ -582,52 +583,51 @@ cleanup_struct:
|
|||
bool
|
||||
dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now) {
|
||||
isc_result_t result;
|
||||
isc_stdtime_t publish, active, revoke, inactive, deltime;
|
||||
bool pubset = false, actset = false;
|
||||
bool revset = false, inactset = false;
|
||||
bool delset = false;
|
||||
isc_stdtime_t publish, active, revoke, remove;
|
||||
bool hint_publish, hint_zsign, hint_ksign, hint_revoke, hint_remove;
|
||||
int major, minor;
|
||||
bool ksk = false, zsk = false;
|
||||
isc_result_t ret;
|
||||
|
||||
/* Is this an old-style key? */
|
||||
result = dst_key_getprivateformat(key, &major, &minor);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
/* Is this a KSK? */
|
||||
ret = dst_key_getbool(key, DST_BOOL_KSK, &ksk);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
ksk = ((dst_key_flags(key) & DNS_KEYFLAG_KSK) != 0);
|
||||
}
|
||||
ret = dst_key_getbool(key, DST_BOOL_ZSK, &zsk);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
zsk = ((dst_key_flags(key) & DNS_KEYFLAG_KSK) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Smart signing started with key format 1.3; prior to that, all
|
||||
* keys are assumed active
|
||||
* keys are assumed active.
|
||||
*/
|
||||
if (major == 1 && minor <= 2)
|
||||
return (true);
|
||||
|
||||
result = dst_key_gettime(key, DST_TIME_PUBLISH, &publish);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
pubset = true;
|
||||
hint_publish = dst_key_is_published(key, now, &publish);
|
||||
hint_zsign = dst_key_is_signing(key, DST_BOOL_ZSK, now, &active);
|
||||
hint_ksign = dst_key_is_signing(key, DST_BOOL_KSK, now, &active);
|
||||
hint_revoke = dst_key_is_revoked(key, now, &revoke);
|
||||
hint_remove = dst_key_is_removed(key, now, &remove);
|
||||
|
||||
result = dst_key_gettime(key, DST_TIME_ACTIVATE, &active);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
actset = true;
|
||||
|
||||
result = dst_key_gettime(key, DST_TIME_REVOKE, &revoke);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
revset = true;
|
||||
|
||||
result = dst_key_gettime(key, DST_TIME_INACTIVE, &inactive);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
inactset = true;
|
||||
|
||||
result = dst_key_gettime(key, DST_TIME_DELETE, &deltime);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
delset = true;
|
||||
|
||||
if ((inactset && inactive <= now) || (delset && deltime <= now))
|
||||
if (hint_remove) {
|
||||
return (false);
|
||||
|
||||
if (revset && revoke <= now && pubset && publish <= now)
|
||||
}
|
||||
if (hint_publish && hint_revoke) {
|
||||
return (true);
|
||||
|
||||
if (actset && active <= now)
|
||||
}
|
||||
if (hint_zsign && zsk) {
|
||||
return (true);
|
||||
|
||||
}
|
||||
if (hint_ksign && ksk) {
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
|
@ -635,7 +635,10 @@ dns_dnssec_keyactive(dst_key_t *key, isc_stdtime_t now) {
|
|||
* Indicate whether a key is scheduled to to have CDS/CDNSKEY records
|
||||
* published now.
|
||||
*
|
||||
* Returns true iff.
|
||||
* Returns true if.
|
||||
* - kasp says the DS record should be published (e.g. the DS state is in
|
||||
* RUMOURED or OMNIPRESENT state).
|
||||
* Or:
|
||||
* - SyncPublish is set and in the past, AND
|
||||
* - SyncDelete is unset or in the future
|
||||
*/
|
||||
|
|
@ -643,6 +646,7 @@ static bool
|
|||
syncpublish(dst_key_t *key, isc_stdtime_t now) {
|
||||
isc_result_t result;
|
||||
isc_stdtime_t when;
|
||||
dst_key_state_t state;
|
||||
int major, minor;
|
||||
|
||||
/*
|
||||
|
|
@ -654,18 +658,29 @@ syncpublish(dst_key_t *key, isc_stdtime_t now) {
|
|||
/*
|
||||
* Smart signing started with key format 1.3
|
||||
*/
|
||||
if (major == 1 && minor <= 2)
|
||||
if (major == 1 && minor <= 2) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
/* Check kasp state first. */
|
||||
result = dst_key_getstate(key, DST_KEY_DS, &state);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
return (state == DST_KEY_STATE_RUMOURED ||
|
||||
state == DST_KEY_STATE_OMNIPRESENT);
|
||||
}
|
||||
|
||||
/* If no kasp state, check timings. */
|
||||
result = dst_key_gettime(key, DST_TIME_SYNCPUBLISH, &when);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (false);
|
||||
|
||||
}
|
||||
result = dst_key_gettime(key, DST_TIME_SYNCDELETE, &when);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (true);
|
||||
if (when <= now)
|
||||
}
|
||||
if (when <= now) {
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
|
@ -673,12 +688,17 @@ syncpublish(dst_key_t *key, isc_stdtime_t now) {
|
|||
* Indicate whether a key is scheduled to to have CDS/CDNSKEY records
|
||||
* deleted now.
|
||||
*
|
||||
* Returns true iff. SyncDelete is set and in the past.
|
||||
* Returns true if:
|
||||
* - kasp says the DS record should be unpublished (e.g. the DS state is in
|
||||
* UNRETENTIVE or HIDDEN state).
|
||||
* Or:
|
||||
* - SyncDelete is set and in the past.
|
||||
*/
|
||||
static bool
|
||||
syncdelete(dst_key_t *key, isc_stdtime_t now) {
|
||||
isc_result_t result;
|
||||
isc_stdtime_t when;
|
||||
dst_key_state_t state;
|
||||
int major, minor;
|
||||
|
||||
/*
|
||||
|
|
@ -690,14 +710,25 @@ syncdelete(dst_key_t *key, isc_stdtime_t now) {
|
|||
/*
|
||||
* Smart signing started with key format 1.3.
|
||||
*/
|
||||
if (major == 1 && minor <= 2)
|
||||
if (major == 1 && minor <= 2) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
/* Check kasp state first. */
|
||||
result = dst_key_getstate(key, DST_KEY_DS, &state);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
return (state == DST_KEY_STATE_UNRETENTIVE ||
|
||||
state == DST_KEY_STATE_HIDDEN);
|
||||
}
|
||||
|
||||
/* If no kasp state, check timings. */
|
||||
result = dst_key_gettime(key, DST_TIME_SYNCDELETE, &when);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (false);
|
||||
if (when <= now)
|
||||
}
|
||||
if (when <= now) {
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
|
@ -742,7 +773,8 @@ dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver,
|
|||
result = dst_key_fromfile(dst_key_name(pubkey),
|
||||
dst_key_id(pubkey),
|
||||
dst_key_alg(pubkey),
|
||||
DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
|
||||
DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|
|
||||
DST_TYPE_STATE,
|
||||
directory,
|
||||
mctx, &keys[count]);
|
||||
|
||||
|
|
@ -761,7 +793,8 @@ dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver,
|
|||
dst_key_id(pubkey),
|
||||
dst_key_alg(pubkey),
|
||||
DST_TYPE_PUBLIC|
|
||||
DST_TYPE_PRIVATE,
|
||||
DST_TYPE_PRIVATE|
|
||||
DST_TYPE_STATE,
|
||||
directory,
|
||||
mctx, &keys[count]);
|
||||
if (result == ISC_R_SUCCESS &&
|
||||
|
|
@ -784,8 +817,9 @@ dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver,
|
|||
result2 = dst_key_getfilename(dst_key_name(pubkey),
|
||||
dst_key_id(pubkey),
|
||||
dst_key_alg(pubkey),
|
||||
(DST_TYPE_PUBLIC |
|
||||
DST_TYPE_PRIVATE),
|
||||
(DST_TYPE_PUBLIC|
|
||||
DST_TYPE_PRIVATE|
|
||||
DST_TYPE_STATE),
|
||||
directory, mctx,
|
||||
&buf);
|
||||
if (result2 != ISC_R_SUCCESS) {
|
||||
|
|
@ -1219,6 +1253,7 @@ dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey,
|
|||
dk->force_sign = false;
|
||||
dk->hint_publish = false;
|
||||
dk->hint_sign = false;
|
||||
dk->hint_revoke = false;
|
||||
dk->hint_remove = false;
|
||||
dk->first_sign = false;
|
||||
dk->is_active = false;
|
||||
|
|
@ -1227,7 +1262,14 @@ dns_dnsseckey_create(isc_mem_t *mctx, dst_key_t **dstkey,
|
|||
dk->index = 0;
|
||||
|
||||
/* KSK or ZSK? */
|
||||
dk->ksk = ((dst_key_flags(dk->key) & DNS_KEYFLAG_KSK) != 0);
|
||||
result = dst_key_getbool(dk->key, DST_BOOL_KSK, &dk->ksk);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dk->ksk = ((dst_key_flags(dk->key) & DNS_KEYFLAG_KSK) != 0);
|
||||
}
|
||||
result = dst_key_getbool(dk->key, DST_BOOL_ZSK, &dk->zsk);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dk->zsk = ((dst_key_flags(dk->key) & DNS_KEYFLAG_KSK) == 0);
|
||||
}
|
||||
|
||||
/* Is this an old-style key? */
|
||||
result = dst_key_getprivateformat(dk->key, &major, &minor);
|
||||
|
|
@ -1253,80 +1295,48 @@ dns_dnsseckey_destroy(isc_mem_t *mctx, dns_dnsseckey_t **dkp) {
|
|||
*dkp = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
get_hints(dns_dnsseckey_t *key, isc_stdtime_t now) {
|
||||
isc_result_t result;
|
||||
isc_stdtime_t publish, active, revoke, inactive, deltime;
|
||||
bool pubset = false, actset = false;
|
||||
bool revset = false, inactset = false;
|
||||
bool delset = false;
|
||||
void
|
||||
dns_dnssec_get_hints(dns_dnsseckey_t *key, isc_stdtime_t now) {
|
||||
isc_stdtime_t publish = 0, active = 0, revoke = 0, remove = 0;
|
||||
|
||||
REQUIRE(key != NULL && key->key != NULL);
|
||||
|
||||
result = dst_key_gettime(key->key, DST_TIME_PUBLISH, &publish);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
pubset = true;
|
||||
key->hint_publish = dst_key_is_published(key->key, now, &publish);
|
||||
key->hint_sign = dst_key_is_signing(key->key, DST_BOOL_ZSK, now,
|
||||
&active);
|
||||
key->hint_revoke = dst_key_is_revoked(key->key, now, &revoke);
|
||||
key->hint_remove = dst_key_is_removed(key->key, now, &remove);
|
||||
|
||||
result = dst_key_gettime(key->key, DST_TIME_ACTIVATE, &active);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
actset = true;
|
||||
|
||||
result = dst_key_gettime(key->key, DST_TIME_REVOKE, &revoke);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
revset = true;
|
||||
|
||||
result = dst_key_gettime(key->key, DST_TIME_INACTIVE, &inactive);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
inactset = true;
|
||||
|
||||
result = dst_key_gettime(key->key, DST_TIME_DELETE, &deltime);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
delset = true;
|
||||
|
||||
/* Metadata says publish (but possibly not activate) */
|
||||
if (pubset && publish <= now)
|
||||
/*
|
||||
* Activation date is set (maybe in the future), but publication date
|
||||
* isn't. Most likely the user wants to publish now and activate later.
|
||||
* Most likely because this is true for most rollovers, except for:
|
||||
* 1. The unpopular ZSK Double-RRSIG method.
|
||||
* 2. When introducing a new algorithm.
|
||||
* These two cases are rare enough that we will set hint_publish
|
||||
* anyway when hint_sign is set, because BIND 9 natively does not
|
||||
* support the ZSK Double-RRSIG method, and when introducing a new
|
||||
* algorihtm, we strive to publish its signatures and DNSKEY records
|
||||
* at the same time.
|
||||
*/
|
||||
if (key->hint_sign && publish == 0) {
|
||||
key->hint_publish = true;
|
||||
|
||||
/* Metadata says activate (so we must also publish) */
|
||||
if (actset && active <= now) {
|
||||
key->hint_sign = true;
|
||||
|
||||
/* Only publish if publish time has already passed. */
|
||||
if (pubset && publish <= now)
|
||||
key->hint_publish = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Activation date is set (maybe in the future), but
|
||||
* publication date isn't. Most likely the user wants to
|
||||
* publish now and activate later.
|
||||
* If activation date is in the future, make note of how far off.
|
||||
*/
|
||||
if (actset && !pubset)
|
||||
key->hint_publish = true;
|
||||
|
||||
/*
|
||||
* If activation date is in the future, make note of how far off
|
||||
*/
|
||||
if (key->hint_publish && actset && active > now) {
|
||||
if (key->hint_publish && active > now) {
|
||||
key->prepublish = active - now;
|
||||
}
|
||||
|
||||
/*
|
||||
* Key has been marked inactive: we can continue publishing,
|
||||
* but don't sign.
|
||||
*/
|
||||
if (key->hint_publish && inactset && inactive <= now) {
|
||||
key->hint_sign = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Metadata says revoke. If the key is published,
|
||||
* we *have to* sign with it per RFC5011--even if it was
|
||||
* not active before.
|
||||
* Metadata says revoke. If the key is published, we *have to* sign
|
||||
* with it per RFC5011 -- even if it was not active before.
|
||||
*
|
||||
* If it hasn't already been done, we should also revoke it now.
|
||||
*/
|
||||
if (key->hint_publish && (revset && revoke <= now)) {
|
||||
if (key->hint_publish && key->hint_revoke) {
|
||||
uint32_t flags;
|
||||
key->hint_sign = true;
|
||||
flags = dst_key_flags(key->key);
|
||||
|
|
@ -1337,17 +1347,17 @@ get_hints(dns_dnsseckey_t *key, isc_stdtime_t now) {
|
|||
}
|
||||
|
||||
/*
|
||||
* Metadata says delete, so don't publish this key or sign with it.
|
||||
* Metadata says delete, so don't publish this key or sign with it
|
||||
* (note that signatures of a removed key may still be reused).
|
||||
*/
|
||||
if (delset && deltime <= now) {
|
||||
if (key->hint_remove) {
|
||||
key->hint_publish = false;
|
||||
key->hint_sign = false;
|
||||
key->hint_remove = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*%
|
||||
* Get a list of DNSSEC keys from the key repository
|
||||
* Get a list of DNSSEC keys from the key repository.
|
||||
*/
|
||||
isc_result_t
|
||||
dns_dnssec_findmatchingkeys(const dns_name_t *origin, const char *directory,
|
||||
|
|
@ -1416,10 +1426,10 @@ dns_dnssec_findmatchingkeys(const dns_name_t *origin, const char *directory,
|
|||
continue;
|
||||
|
||||
dstkey = NULL;
|
||||
result = dst_key_fromnamedfile(dir.entry.name,
|
||||
directory,
|
||||
result = dst_key_fromnamedfile(dir.entry.name, directory,
|
||||
DST_TYPE_PUBLIC |
|
||||
DST_TYPE_PRIVATE,
|
||||
DST_TYPE_PRIVATE |
|
||||
DST_TYPE_STATE,
|
||||
mctx, &dstkey);
|
||||
|
||||
switch (alg) {
|
||||
|
|
@ -1447,7 +1457,7 @@ dns_dnssec_findmatchingkeys(const dns_name_t *origin, const char *directory,
|
|||
|
||||
RETERR(dns_dnsseckey_create(mctx, &dstkey, &key));
|
||||
key->source = dns_keysource_repository;
|
||||
get_hints(key, now);
|
||||
dns_dnssec_get_hints(key, now);
|
||||
|
||||
if (key->legacy) {
|
||||
dns_dnsseckey_destroy(mctx, &key);
|
||||
|
|
@ -1638,7 +1648,8 @@ dns_dnssec_keylistfromrdataset(const dns_name_t *origin,
|
|||
result = dst_key_fromfile(dst_key_name(pubkey),
|
||||
dst_key_id(pubkey),
|
||||
dst_key_alg(pubkey),
|
||||
DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
|
||||
(DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|
|
||||
DST_TYPE_STATE),
|
||||
directory, mctx, &privkey);
|
||||
|
||||
/*
|
||||
|
|
@ -1655,8 +1666,9 @@ dns_dnssec_keylistfromrdataset(const dns_name_t *origin,
|
|||
result = dst_key_fromfile(dst_key_name(pubkey),
|
||||
dst_key_id(pubkey),
|
||||
dst_key_alg(pubkey),
|
||||
DST_TYPE_PUBLIC|
|
||||
DST_TYPE_PRIVATE,
|
||||
(DST_TYPE_PUBLIC|
|
||||
DST_TYPE_PRIVATE|
|
||||
DST_TYPE_STATE),
|
||||
directory,
|
||||
mctx, &privkey);
|
||||
if (result == ISC_R_SUCCESS &&
|
||||
|
|
@ -1680,7 +1692,8 @@ dns_dnssec_keylistfromrdataset(const dns_name_t *origin,
|
|||
dst_key_id(pubkey),
|
||||
dst_key_alg(pubkey),
|
||||
(DST_TYPE_PUBLIC |
|
||||
DST_TYPE_PRIVATE),
|
||||
DST_TYPE_PRIVATE|
|
||||
DST_TYPE_STATE),
|
||||
directory, mctx,
|
||||
&buf);
|
||||
if (result2 != ISC_R_SUCCESS) {
|
||||
|
|
@ -1800,7 +1813,7 @@ delrdata(dns_rdata_t *rdata, dns_diff_t *diff, const dns_name_t *origin,
|
|||
|
||||
static isc_result_t
|
||||
publish_key(dns_diff_t *diff, dns_dnsseckey_t *key, const dns_name_t *origin,
|
||||
dns_ttl_t ttl, isc_mem_t *mctx, bool allzsk,
|
||||
dns_ttl_t ttl, isc_mem_t *mctx,
|
||||
void (*report)(const char *, ...))
|
||||
{
|
||||
isc_result_t result;
|
||||
|
|
@ -1813,7 +1826,7 @@ publish_key(dns_diff_t *diff, dns_dnsseckey_t *key, const dns_name_t *origin,
|
|||
dst_key_format(key->key, keystr, sizeof(keystr));
|
||||
|
||||
report("Fetching %s (%s) from key %s.\n",
|
||||
keystr, key->ksk ? (allzsk ? "KSK/ZSK" : "KSK") : "ZSK",
|
||||
keystr, key->ksk ? (key->zsk ? "CSK" : "KSK") : "ZSK",
|
||||
key->source == dns_keysource_user ? "file" : "repository");
|
||||
|
||||
if (key->prepublish && ttl > key->prepublish) {
|
||||
|
|
@ -2023,8 +2036,7 @@ dns_dnssec_syncupdate(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *rmkeys,
|
|||
isc_result_t
|
||||
dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
||||
dns_dnsseckeylist_t *removed, const dns_name_t *origin,
|
||||
dns_ttl_t hint_ttl, dns_diff_t *diff,
|
||||
bool allzsk, isc_mem_t *mctx,
|
||||
dns_ttl_t hint_ttl, dns_diff_t *diff, isc_mem_t *mctx,
|
||||
void (*report)(const char *, ...))
|
||||
{
|
||||
isc_result_t result;
|
||||
|
|
@ -2047,8 +2059,8 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||
if (key->source == dns_keysource_user &&
|
||||
(key->hint_publish || key->force_publish))
|
||||
{
|
||||
RETERR(publish_key(diff, key, origin, ttl,
|
||||
mctx, allzsk, report));
|
||||
RETERR(publish_key(diff, key, origin, ttl, mctx,
|
||||
report));
|
||||
}
|
||||
if (key->source == dns_keysource_zoneapex) {
|
||||
ttl = dst_key_getttl(key->key);
|
||||
|
|
@ -2125,14 +2137,14 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||
(key1->hint_publish || key1->force_publish))
|
||||
{
|
||||
RETERR(publish_key(diff, key1, origin, ttl,
|
||||
mctx, allzsk, report));
|
||||
mctx, report));
|
||||
isc_log_write(dns_lctx,
|
||||
DNS_LOGCATEGORY_DNSSEC,
|
||||
DNS_LOGMODULE_DNSSEC,
|
||||
ISC_LOG_INFO,
|
||||
"DNSKEY %s (%s) is now published",
|
||||
keystr1, key1->ksk ?
|
||||
(allzsk ? "KSK/ZSK" : "KSK") :
|
||||
(key1->zsk ? "CSK" : "KSK") :
|
||||
"ZSK");
|
||||
if (key1->hint_sign || key1->force_sign) {
|
||||
key1->first_sign = true;
|
||||
|
|
@ -2143,7 +2155,7 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||
"DNSKEY %s (%s) is now "
|
||||
"active",
|
||||
keystr1, key1->ksk ?
|
||||
(allzsk ? "KSK/ZSK" :
|
||||
(key1->zsk ? "CSK" :
|
||||
"KSK") : "ZSK");
|
||||
}
|
||||
}
|
||||
|
|
@ -2154,6 +2166,9 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||
/* Printable version of key2 (the old key, if any) */
|
||||
dst_key_format(key2->key, keystr2, sizeof(keystr2));
|
||||
|
||||
/* Copy key metadata. */
|
||||
dst_key_copy_metadata(key2->key, key1->key);
|
||||
|
||||
/* Match found: remove or update it as needed */
|
||||
if (key1->hint_remove) {
|
||||
RETERR(remove_key(diff, key2, origin, ttl, mctx,
|
||||
|
|
@ -2167,8 +2182,8 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||
DNS_LOGMODULE_DNSSEC,
|
||||
ISC_LOG_INFO,
|
||||
"DNSKEY %s (%s) is now deleted",
|
||||
keystr2, key2->ksk ? (allzsk ?
|
||||
"KSK/ZSK" : "KSK") : "ZSK");
|
||||
keystr2, key2->ksk ? (key2->zsk ?
|
||||
"CSK" : "KSK") : "ZSK");
|
||||
} else {
|
||||
dns_dnsseckey_destroy(mctx, &key2);
|
||||
}
|
||||
|
|
@ -2192,15 +2207,15 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||
ISC_LOG_INFO,
|
||||
"DNSKEY %s (%s) is now revoked; "
|
||||
"new ID is %05d",
|
||||
keystr2, key2->ksk ? (allzsk ?
|
||||
"KSK/ZSK" : "KSK") : "ZSK",
|
||||
keystr2, key2->ksk ? (key2->zsk ?
|
||||
"CSK" : "KSK") : "ZSK",
|
||||
dst_key_id(key1->key));
|
||||
} else {
|
||||
dns_dnsseckey_destroy(mctx, &key2);
|
||||
}
|
||||
|
||||
RETERR(publish_key(diff, key1, origin, ttl,
|
||||
mctx, allzsk, report));
|
||||
RETERR(publish_key(diff, key1, origin, ttl, mctx,
|
||||
report));
|
||||
ISC_LIST_UNLINK(*newkeys, key1, link);
|
||||
ISC_LIST_APPEND(*keys, key1, link);
|
||||
|
||||
|
|
@ -2224,8 +2239,8 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||
DNS_LOGMODULE_DNSSEC,
|
||||
ISC_LOG_INFO,
|
||||
"DNSKEY %s (%s) is now active",
|
||||
keystr1, key1->ksk ? (allzsk ?
|
||||
"KSK/ZSK" : "KSK") : "ZSK");
|
||||
keystr1, key1->ksk ? (key1->zsk ?
|
||||
"CSK" : "KSK") : "ZSK");
|
||||
} else if (key2->is_active &&
|
||||
!key1->hint_sign && !key1->force_sign)
|
||||
{
|
||||
|
|
@ -2234,8 +2249,8 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||
DNS_LOGMODULE_DNSSEC,
|
||||
ISC_LOG_INFO,
|
||||
"DNSKEY %s (%s) is now inactive",
|
||||
keystr1, key1->ksk ? (allzsk ?
|
||||
"KSK/ZSK" : "KSK") : "ZSK");
|
||||
keystr1, key1->ksk ? (key1->zsk ?
|
||||
"CSK" : "KSK") : "ZSK");
|
||||
}
|
||||
|
||||
key2->hint_sign = key1->hint_sign;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -107,11 +107,18 @@ struct dst_key {
|
|||
} keydata; /*%< pointer to key in crypto pkg fmt */
|
||||
|
||||
isc_stdtime_t times[DST_MAX_TIMES + 1]; /*%< timing metadata */
|
||||
bool timeset[DST_MAX_TIMES + 1]; /*%< data set? */
|
||||
isc_stdtime_t nums[DST_MAX_NUMERIC + 1]; /*%< numeric metadata */
|
||||
bool numset[DST_MAX_NUMERIC + 1]; /*%< data set? */
|
||||
bool inactive; /*%< private key not present as it is
|
||||
inactive */
|
||||
bool timeset[DST_MAX_TIMES + 1]; /*%< data set? */
|
||||
|
||||
uint32_t nums[DST_MAX_NUMERIC + 1]; /*%< numeric metadata */
|
||||
bool numset[DST_MAX_NUMERIC + 1]; /*%< data set? */
|
||||
|
||||
bool bools[DST_MAX_BOOLEAN + 1]; /*%< boolean metadata */
|
||||
bool boolset[DST_MAX_BOOLEAN + 1]; /*%< data set? */
|
||||
|
||||
dst_key_state_t keystates[DST_MAX_KEYSTATES + 1]; /*%< key states */
|
||||
bool keystateset[DST_MAX_KEYSTATES + 1]; /*%< data set? */
|
||||
|
||||
bool inactive; /*%< private key not present as it is inactive */
|
||||
bool external; /*%< external key */
|
||||
|
||||
int fmt_major; /*%< private key format, major version */
|
||||
|
|
|
|||
|
|
@ -61,7 +61,11 @@ static const char *timetags[TIMING_NTAGS] = {
|
|||
"Delete:",
|
||||
"DSPublish:",
|
||||
"SyncPublish:",
|
||||
"SyncDelete:"
|
||||
"SyncDelete:",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
#define NUMERIC_NTAGS (DST_MAX_NUMERIC + 1)
|
||||
|
|
@ -69,7 +73,8 @@ static const char *numerictags[NUMERIC_NTAGS] = {
|
|||
"Predecessor:",
|
||||
"Successor:",
|
||||
"MaxTTL:",
|
||||
"RollPeriod:"
|
||||
"RollPeriod:",
|
||||
NULL
|
||||
};
|
||||
|
||||
struct parse_map {
|
||||
|
|
@ -734,7 +739,9 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
|
|||
result = dst_key_getnum(key, i, &value);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
continue;
|
||||
fprintf(fp, "%s %u\n", numerictags[i], value);
|
||||
if (numerictags[i] != NULL) {
|
||||
fprintf(fp, "%s %u\n", numerictags[i], value);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < TIMING_NTAGS; i++) {
|
||||
result = dst_key_gettime(key, i, &when);
|
||||
|
|
@ -750,8 +757,10 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
|
|||
|
||||
isc_buffer_usedregion(&b, &r);
|
||||
|
||||
fprintf(fp, "%s %.*s\n", timetags[i], (int)r.length,
|
||||
r.base);
|
||||
if (timetags[i] != NULL) {
|
||||
fprintf(fp, "%s %.*s\n", timetags[i],
|
||||
(int)r.length, r.base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,12 +53,14 @@ struct dns_dnsseckey {
|
|||
bool force_publish; /*% publish regardless of metadata */
|
||||
bool hint_sign; /*% metadata says to sign with this key */
|
||||
bool force_sign; /*% sign with key regardless of metadata */
|
||||
bool hint_revoke; /*% metadata says revoke key */
|
||||
bool hint_remove; /*% metadata says *don't* publish */
|
||||
bool is_active; /*% key is already active */
|
||||
bool first_sign; /*% key is newly becoming active */
|
||||
unsigned int prepublish; /*% how long until active? */
|
||||
dns_keysource_t source; /*% how the key was found */
|
||||
bool ksk; /*% this is a key-signing key */
|
||||
bool zsk; /*% this is a zone-signing key */
|
||||
bool legacy; /*% this is old-style key with no
|
||||
metadata (possibly generated by
|
||||
an older version of BIND9) and
|
||||
|
|
@ -267,6 +269,16 @@ dns_dnsseckey_destroy(isc_mem_t *mctx, dns_dnsseckey_t **dkp);
|
|||
*\li '*dkp' is NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_dnssec_get_hints(dns_dnsseckey_t *key, isc_stdtime_t now);
|
||||
/*%<
|
||||
* Get hints on DNSSEC key whether this key can be published
|
||||
* and/or is active. Timing metadata is compared to 'now'.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'key' is a pointer to a DNSSEC key and is not NULL.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_dnssec_findmatchingkeys(const dns_name_t *origin, const char *directory,
|
||||
isc_stdtime_t now, isc_mem_t *mctx,
|
||||
|
|
@ -312,8 +324,8 @@ dns_dnssec_keylistfromrdataset(const dns_name_t *origin,
|
|||
isc_result_t
|
||||
dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
||||
dns_dnsseckeylist_t *removed, const dns_name_t *origin,
|
||||
dns_ttl_t hint_ttl, dns_diff_t *diff, bool allzsk,
|
||||
isc_mem_t *mctx, void (*report)(const char *, ...));
|
||||
dns_ttl_t hint_ttl, dns_diff_t *diff, isc_mem_t *mctx,
|
||||
void (*report)(const char *, ...));
|
||||
/*%<
|
||||
* Update the list of keys in 'keys' with new key information in 'newkeys'.
|
||||
*
|
||||
|
|
@ -328,9 +340,6 @@ dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys,
|
|||
* copy the key into that list; otherwise destroy it.
|
||||
* - Otherwise, make sure keys has current metadata.
|
||||
*
|
||||
* If 'allzsk' is true, we are allowing KSK-flagged keys to be used as
|
||||
* ZSKs.
|
||||
*
|
||||
* 'hint_ttl' is the TTL to use for the DNSKEY RRset if there is no
|
||||
* existing RRset, and if none of the keys to be added has a default TTL
|
||||
* (in which case we would use the shortest one). If the TTL is longer
|
||||
|
|
|
|||
635
lib/dns/include/dns/kasp.h
Normal file
635
lib/dns/include/dns/kasp.h
Normal file
|
|
@ -0,0 +1,635 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef DNS_KASP_H
|
||||
#define DNS_KASP_H 1
|
||||
|
||||
/*****
|
||||
***** Module Info
|
||||
*****/
|
||||
|
||||
/*! \file dns/kasp.h
|
||||
* \brief
|
||||
* DNSSEC Key and Signing Policy (KASP)
|
||||
*
|
||||
* A "kasp" is a DNSSEC policy, that determines how a zone should be
|
||||
* signed and maintained.
|
||||
*/
|
||||
|
||||
#include <isc/lang.h>
|
||||
#include <isc/magic.h>
|
||||
#include <isc/mutex.h>
|
||||
#include <isc/refcount.h>
|
||||
|
||||
#include <dns/types.h>
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
/* Stores a KASP key */
|
||||
struct dns_kasp_key {
|
||||
isc_mem_t* mctx;
|
||||
|
||||
/* Locked by themselves. */
|
||||
isc_refcount_t references;
|
||||
|
||||
/* Under owner's locking control. */
|
||||
ISC_LINK(struct dns_kasp_key) link;
|
||||
|
||||
/* Configuration */
|
||||
uint32_t lifetime;
|
||||
uint32_t algorithm;
|
||||
int length;
|
||||
uint8_t role;
|
||||
};
|
||||
|
||||
/* Stores a DNSSEC policy */
|
||||
struct dns_kasp {
|
||||
unsigned int magic;
|
||||
isc_mem_t* mctx;
|
||||
char* name;
|
||||
|
||||
/* Internals. */
|
||||
isc_mutex_t lock;
|
||||
bool frozen;
|
||||
|
||||
/* Locked by themselves. */
|
||||
isc_refcount_t references;
|
||||
|
||||
/* Under owner's locking control. */
|
||||
ISC_LINK(struct dns_kasp) link;
|
||||
|
||||
/* Configuration: signatures */
|
||||
uint32_t signatures_refresh;
|
||||
uint32_t signatures_validity;
|
||||
uint32_t signatures_validity_dnskey;
|
||||
|
||||
/* Configuration: Keys */
|
||||
dns_kasp_keylist_t keys;
|
||||
dns_ttl_t dnskey_ttl;
|
||||
|
||||
/* Configuration: Timings */
|
||||
uint32_t publish_safety;
|
||||
uint32_t retire_safety;
|
||||
|
||||
/* Zone settings */
|
||||
dns_ttl_t zone_max_ttl;
|
||||
uint32_t zone_propagation_delay;
|
||||
|
||||
/* Parent settings */
|
||||
dns_ttl_t parent_ds_ttl;
|
||||
uint32_t parent_propagation_delay;
|
||||
uint32_t parent_registration_delay;
|
||||
|
||||
// TODO: The rest of the KASP configuration
|
||||
};
|
||||
|
||||
#define DNS_KASP_MAGIC ISC_MAGIC('K','A','S','P')
|
||||
#define DNS_KASP_VALID(kasp) ISC_MAGIC_VALID(kasp, DNS_KASP_MAGIC)
|
||||
|
||||
/* Defaults */
|
||||
#define DNS_KASP_SIG_REFRESH (86400*5)
|
||||
#define DNS_KASP_SIG_VALIDITY (86400*14)
|
||||
#define DNS_KASP_SIG_VALIDITY_DNSKEY (86400*14)
|
||||
#define DNS_KASP_KEY_TTL (3600)
|
||||
#define DNS_KASP_DS_TTL (3600)
|
||||
#define DNS_KASP_PUBLISH_SAFETY (300)
|
||||
#define DNS_KASP_RETIRE_SAFETY (300)
|
||||
#define DNS_KASP_ZONE_MAXTTL (86400)
|
||||
#define DNS_KASP_ZONE_PROPDELAY (300)
|
||||
#define DNS_KASP_PARENT_PROPDELAY (3600)
|
||||
#define DNS_KASP_PARENT_REGDELAY (86400)
|
||||
|
||||
/* Key roles */
|
||||
#define DNS_KASP_KEY_ROLE_KSK 0x01
|
||||
#define DNS_KASP_KEY_ROLE_ZSK 0x02
|
||||
|
||||
isc_result_t
|
||||
dns_kasp_create(isc_mem_t *mctx, const char* name, dns_kasp_t **kaspp);
|
||||
/*%<
|
||||
* Create a KASP.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'mctx' is a valid memory context.
|
||||
*
|
||||
*\li 'name' is a valid C string.
|
||||
*
|
||||
*\li kaspp != NULL && *kaspp == NULL
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_NOMEMORY
|
||||
*
|
||||
*\li Other errors are possible.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_attach(dns_kasp_t *source, dns_kasp_t **targetp);
|
||||
/*%<
|
||||
* Attach '*targetp' to 'source'.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'source' is a valid, frozen kasp.
|
||||
*
|
||||
*\li 'targetp' points to a NULL dns_kasp_t *.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li *targetp is attached to source.
|
||||
*
|
||||
*\li While *targetp is attached, the kasp will not shut down.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_detach(dns_kasp_t **kaspp);
|
||||
/*%<
|
||||
* Detach KASP.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kaspp' points to a valid dns_kasp_t *
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li *kaspp is NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_freeze(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Freeze kasp. No changes can be made to kasp configuration while frozen.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, unfrozen kasp.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li 'kasp' is frozen.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_thaw(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Thaw kasp.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li 'kasp' is no longer frozen.
|
||||
*/
|
||||
|
||||
const char*
|
||||
dns_kasp_getname(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get kasp name.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li name of 'kasp'.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_kasp_signdelay(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get the delay that is needed to ensure that all existing RRsets have been
|
||||
* re-signed with a successor key. This is the signature validity minus the
|
||||
* signature refresh time (that indicates how far before signature expiry an
|
||||
* RRSIG should be refreshed).
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li signature refresh interval.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_kasp_sigrefresh(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get signature refresh interval.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li signature refresh interval.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_setsigrefresh(dns_kasp_t *kasp, uint32_t value);
|
||||
/*%<
|
||||
* Set signature refresh interval.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, thawed kasp.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_kasp_sigvalidity(dns_kasp_t *kasp);
|
||||
uint32_t
|
||||
dns_kasp_sigvalidity_dnskey(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get signature validity.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li signature validity.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_setsigvalidity(dns_kasp_t *kasp, uint32_t value);
|
||||
void
|
||||
dns_kasp_setsigvalidity_dnskey(dns_kasp_t *kasp, uint32_t value);
|
||||
/*%<
|
||||
* Set signature validity.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, thawed kasp.
|
||||
*/
|
||||
|
||||
dns_ttl_t
|
||||
dns_kasp_dnskeyttl(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get DNSKEY TTL.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li DNSKEY TTL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_setdnskeyttl(dns_kasp_t *kasp, dns_ttl_t ttl);
|
||||
/*%<
|
||||
* Set DNSKEY TTL.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, thawed kasp.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_kasp_publishsafety(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get publish safety interval.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Publish safety interval.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_setpublishsafety(dns_kasp_t *kasp, uint32_t value);
|
||||
/*%<
|
||||
* Set publish safety interval.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, thawed kasp.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_kasp_retiresafety(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get retire safety interval.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Retire safety interval.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_setretiresafety(dns_kasp_t *kasp, uint32_t value);
|
||||
/*%<
|
||||
* Set retire safety interval.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, thawed kasp.
|
||||
*/
|
||||
|
||||
dns_ttl_t
|
||||
dns_kasp_zonemaxttl(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get maximum zone TTL.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Maximum zone TTL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_setzonemaxttl(dns_kasp_t *kasp, dns_ttl_t ttl);
|
||||
/*%<
|
||||
* Set maximum zone TTL.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, thawed kasp.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_kasp_zonepropagationdelay(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get zone propagation delay.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Zone propagation delay.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_setzonepropagationdelay(dns_kasp_t *kasp, uint32_t value);
|
||||
/*%<
|
||||
* Set zone propagation delay.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, thawed kasp.
|
||||
*/
|
||||
|
||||
dns_ttl_t
|
||||
dns_kasp_dsttl(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get DS TTL (should match that of the parent DS record).
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Expected parent DS TTL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_setdsttl(dns_kasp_t *kasp, dns_ttl_t ttl);
|
||||
/*%<
|
||||
* Set DS TTL.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, thawed kasp.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_kasp_parentpropagationdelay(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get parent zone propagation delay.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Parent zone propagation delay.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_setparentpropagationdelay(dns_kasp_t *kasp, uint32_t value);
|
||||
/*%<
|
||||
* Set parent propagation delay.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, thawed kasp.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_kasp_parentregistrationdelay(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get parent registration delay for submitting new DS.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Parent registration delay.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_setparentregistrationdelay(dns_kasp_t *kasp, uint32_t value);
|
||||
/*%<
|
||||
* Set parent registration delay.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, thawed kasp.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_kasplist_find(dns_kasplist_t *list, const char *name, dns_kasp_t **kaspp);
|
||||
/*%<
|
||||
* Search for a kasp with name 'name' in 'list'.
|
||||
* If found, '*kaspp' is (strongly) attached to it.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kaspp' points to a NULL dns_kasp_t *.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS A matching kasp was found.
|
||||
*\li #ISC_R_NOTFOUND No matching kasp was found.
|
||||
*/
|
||||
|
||||
dns_kasp_keylist_t
|
||||
dns_kasp_keys(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Get the list of kasp keys.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, frozen kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_NOMEMORY
|
||||
*
|
||||
*\li Other errors are possible.
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_kasp_keylist_empty(dns_kasp_t *kasp);
|
||||
/*%<
|
||||
* Check if the keylist is empty.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid kasp.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li true if the keylist is empty, false otherwise.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_addkey(dns_kasp_t *kasp, dns_kasp_key_t *key);
|
||||
/*%<
|
||||
* Add a key.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid, thawed kasp.
|
||||
*\li 'key' is not NULL.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_kasp_key_create(dns_kasp_t *kasp, dns_kasp_key_t **keyp);
|
||||
/*%<
|
||||
* Create a key inside a KASP.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'kasp' is a valid kasp.
|
||||
*
|
||||
*\li keyp != NULL && *keyp == NULL
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_NOMEMORY
|
||||
*
|
||||
*\li Other errors are possible.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_kasp_key_destroy(dns_kasp_key_t* key);
|
||||
/*%<
|
||||
* Destroy a KASP key.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li key != NULL
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_kasp_key_algorithm(dns_kasp_key_t *key);
|
||||
/*%<
|
||||
* Get the key algorithm.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li key != NULL
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Key algorithm.
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
dns_kasp_key_size(dns_kasp_key_t *key);
|
||||
/*%<
|
||||
* Get the key size.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li key != NULL
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Configured key size, or default key size for key algorithm if no size
|
||||
* configured.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
dns_kasp_key_lifetime(dns_kasp_key_t *key);
|
||||
/*%<
|
||||
* The lifetime of this key (how long may this key be active?)
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li key != NULL
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Lifetime of key.
|
||||
*
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_kasp_key_ksk(dns_kasp_key_t *key);
|
||||
/*%<
|
||||
* Does this key act as a KSK?
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li key != NULL
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li True, if the key role has DNS_KASP_KEY_ROLE_KSK set.
|
||||
*\li False, otherwise.
|
||||
*
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_kasp_key_zsk(dns_kasp_key_t *key);
|
||||
/*%<
|
||||
* Does this key act as a ZSK?
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li key != NULL
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li True, if the key role has DNS_KASP_KEY_ROLE_ZSK set.
|
||||
*\li False, otherwise.
|
||||
*
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_KASP_H */
|
||||
57
lib/dns/include/dns/keymgr.h
Normal file
57
lib/dns/include/dns/keymgr.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DNS_KEYMGR_H
|
||||
#define DNS_KEYMGR_H 1
|
||||
|
||||
/*! \file dns/keymgr.h */
|
||||
|
||||
#include <isc/lang.h>
|
||||
#include <isc/stdtime.h>
|
||||
|
||||
#include <dns/types.h>
|
||||
|
||||
#include <dst/dst.h>
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
isc_result_t
|
||||
dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
|
||||
const char *directory, isc_mem_t *mctx,
|
||||
dns_dnsseckeylist_t *keyring, dns_kasp_t *kasp,
|
||||
isc_stdtime_t now, isc_stdtime_t *nexttime);
|
||||
/*%<
|
||||
* Manage keys in 'keylist' and update timing data according to 'kasp' policy.
|
||||
* Create new keys for 'origin' if necessary in 'directory'. Append all such
|
||||
* keys, along with use hints gleaned from their metadata, onto 'keylist'.
|
||||
*
|
||||
* Update key states and store changes back to disk. Store when to run next
|
||||
* in 'nexttime'.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'origin' is a valid FQDN.
|
||||
*\li 'mctx' is a valid memory context.
|
||||
*\li 'keyring' is not NULL.
|
||||
*\li 'kasp' is not NULL.
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li any error returned by dst_key_generate(), isc_dir_open(),
|
||||
* dst_key_to_file(), or dns_dnsseckey_create().
|
||||
*
|
||||
* Ensures:
|
||||
*\li On error, keypool is unchanged
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_KEYMGR_H */
|
||||
|
|
@ -91,6 +91,10 @@ typedef struct dns_fwdtable dns_fwdtable_t;
|
|||
typedef struct dns_geoip_databases dns_geoip_databases_t;
|
||||
typedef struct dns_iptable dns_iptable_t;
|
||||
typedef uint32_t dns_iterations_t;
|
||||
typedef struct dns_kasp dns_kasp_t;
|
||||
typedef ISC_LIST(dns_kasp_t) dns_kasplist_t;
|
||||
typedef struct dns_kasp_key dns_kasp_key_t;
|
||||
typedef ISC_LIST(dns_kasp_key_t) dns_kasp_keylist_t;
|
||||
typedef uint16_t dns_keyflags_t;
|
||||
typedef struct dns_keynode dns_keynode_t;
|
||||
typedef ISC_LIST(dns_keynode_t) dns_keynodelist_t;
|
||||
|
|
|
|||
|
|
@ -665,6 +665,24 @@ dns_zone_unload(dns_zone_t *zone);
|
|||
*\li 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
dns_kasp_t*
|
||||
dns_zone_getkasp(dns_zone_t *zone);
|
||||
/*%<
|
||||
* Returns the current kasp.
|
||||
*
|
||||
* Require:
|
||||
*\li 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t* kasp);
|
||||
/*%<
|
||||
* Set kasp for zone. If a kasp is already set, it will be detached.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option,
|
||||
bool value);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,38 @@ ISC_LANG_BEGINDECLS
|
|||
typedef struct dst_key dst_key_t;
|
||||
typedef struct dst_context dst_context_t;
|
||||
|
||||
/*%
|
||||
* Key states for the DNSSEC records related to a key: DNSKEY, RRSIG (ksk),
|
||||
* RRSIG (zsk), and DS.
|
||||
*
|
||||
* DST_KEY_STATE_HIDDEN: Records of this type are not published in zone.
|
||||
* This may be because the key parts were never
|
||||
* introduced in the zone, or because the key has
|
||||
* retired and has no records of this type left in
|
||||
* the zone.
|
||||
* DST_KEY_STATE_RUMOURED: Records of this type are published in zone, but
|
||||
* not long enough to ensure all resolvers know
|
||||
* about it.
|
||||
* DST_KEY_STATE_OMNIPRESENT: Records of this type are published in zone long
|
||||
* enough so that all resolvers that know about
|
||||
* these records, no longer have outdated data.
|
||||
* DST_KEY_STATE_UNRETENTIVE: Records of this type have been removed from the
|
||||
* zone, but there may be resolvers that still have
|
||||
* have predecessor records cached. Note that RRSIG
|
||||
* records in this state may actually still be in the
|
||||
* zone because they are reused, but retired RRSIG
|
||||
* records will never be refreshed: A successor key
|
||||
* is used to create signatures.
|
||||
* DST_KEY_STATE_NA: The state is not applicable for this record type.
|
||||
*/
|
||||
typedef enum dst_key_state {
|
||||
DST_KEY_STATE_HIDDEN = 0,
|
||||
DST_KEY_STATE_RUMOURED = 1,
|
||||
DST_KEY_STATE_OMNIPRESENT = 2,
|
||||
DST_KEY_STATE_UNRETENTIVE = 3,
|
||||
DST_KEY_STATE_NA = 4
|
||||
} dst_key_state_t;
|
||||
|
||||
/* DST algorithm codes */
|
||||
#define DST_ALG_UNKNOWN 0
|
||||
#define DST_ALG_RSA 1 /* Used for parsing RSASHA1, RSASHA256 and RSASHA512 */
|
||||
|
|
@ -85,6 +117,7 @@ typedef struct dst_context dst_context_t;
|
|||
#define DST_TYPE_KEY 0x1000000 /* KEY key */
|
||||
#define DST_TYPE_PRIVATE 0x2000000
|
||||
#define DST_TYPE_PUBLIC 0x4000000
|
||||
#define DST_TYPE_STATE 0x8000000
|
||||
|
||||
/* Key timing metadata definitions */
|
||||
#define DST_TIME_CREATED 0
|
||||
|
|
@ -96,14 +129,32 @@ typedef struct dst_context dst_context_t;
|
|||
#define DST_TIME_DSPUBLISH 6
|
||||
#define DST_TIME_SYNCPUBLISH 7
|
||||
#define DST_TIME_SYNCDELETE 8
|
||||
#define DST_MAX_TIMES 8
|
||||
#define DST_TIME_DNSKEY 9
|
||||
#define DST_TIME_ZRRSIG 10
|
||||
#define DST_TIME_KRRSIG 11
|
||||
#define DST_TIME_DS 12
|
||||
#define DST_MAX_TIMES 12
|
||||
|
||||
/* Numeric metadata definitions */
|
||||
#define DST_NUM_PREDECESSOR 0
|
||||
#define DST_NUM_SUCCESSOR 1
|
||||
#define DST_NUM_MAXTTL 2
|
||||
#define DST_NUM_ROLLPERIOD 3
|
||||
#define DST_MAX_NUMERIC 3
|
||||
#define DST_NUM_LIFETIME 4
|
||||
#define DST_MAX_NUMERIC 4
|
||||
|
||||
/* Boolean metadata definitions */
|
||||
#define DST_BOOL_KSK 0
|
||||
#define DST_BOOL_ZSK 1
|
||||
#define DST_MAX_BOOLEAN 1
|
||||
|
||||
/* Key state metadata definitions */
|
||||
#define DST_KEY_DNSKEY 0
|
||||
#define DST_KEY_ZRRSIG 1
|
||||
#define DST_KEY_KRRSIG 2
|
||||
#define DST_KEY_DS 3
|
||||
#define DST_KEY_GOAL 4
|
||||
#define DST_MAX_KEYSTATES 4
|
||||
|
||||
/*
|
||||
* Current format version number of the private key parser.
|
||||
|
|
@ -310,16 +361,17 @@ dst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type,
|
|||
const char *directory, isc_mem_t *mctx, dst_key_t **keyp);
|
||||
/*%<
|
||||
* Reads a key from permanent storage. The key can either be a public or
|
||||
* private key, and is specified by name, algorithm, and id. If a private key
|
||||
* is specified, the public key must also be present. If directory is NULL,
|
||||
* the current directory is assumed.
|
||||
* private key, or a key state. It specified by name, algorithm, and id. If
|
||||
* a private key or key state is specified, the public key must also be
|
||||
* present. If directory is NULL, the current directory is assumed.
|
||||
*
|
||||
* Requires:
|
||||
* \li "name" is a valid absolute dns name.
|
||||
* \li "id" is a valid key tag identifier.
|
||||
* \li "alg" is a supported key algorithm.
|
||||
* \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union.
|
||||
* DST_TYPE_KEY look for a KEY record otherwise DNSKEY
|
||||
* \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE or the bitwise union.
|
||||
* DST_TYPE_KEY look for a KEY record otherwise DNSKEY.
|
||||
* DST_TYPE_STATE to also read the key state.
|
||||
* \li "mctx" is a valid memory context.
|
||||
* \li "keyp" is not NULL and "*keyp" is NULL.
|
||||
*
|
||||
|
|
@ -336,8 +388,8 @@ dst_key_fromnamedfile(const char *filename, const char *dirname,
|
|||
int type, isc_mem_t *mctx, dst_key_t **keyp);
|
||||
/*%<
|
||||
* Reads a key from permanent storage. The key can either be a public or
|
||||
* key, and is specified by filename. If a private key is specified, the
|
||||
* public key must also be present.
|
||||
* private key, or a key stae. It is specified by filename. If a private key
|
||||
* or key state is specified, the public key must also be present.
|
||||
*
|
||||
* If 'dirname' is not NULL, and 'filename' is a relative path,
|
||||
* then the file is looked up relative to the given directory.
|
||||
|
|
@ -345,8 +397,9 @@ dst_key_fromnamedfile(const char *filename, const char *dirname,
|
|||
*
|
||||
* Requires:
|
||||
* \li "filename" is not NULL
|
||||
* \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union
|
||||
* DST_TYPE_KEY look for a KEY record otherwise DNSKEY
|
||||
* \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union.
|
||||
* DST_TYPE_KEY look for a KEY record otherwise DNSKEY.
|
||||
* DST_TYPE_STATE to also read the key state.
|
||||
* \li "mctx" is a valid memory context
|
||||
* \li "keyp" is not NULL and "*keyp" is NULL.
|
||||
*
|
||||
|
|
@ -366,9 +419,9 @@ dst_key_read_public(const char *filename, int type,
|
|||
* Reads a public key from permanent storage. The key must be a public key.
|
||||
*
|
||||
* Requires:
|
||||
* \li "filename" is not NULL
|
||||
* \li "type" is DST_TYPE_KEY look for a KEY record otherwise DNSKEY
|
||||
* \li "mctx" is a valid memory context
|
||||
* \li "filename" is not NULL.
|
||||
* \li "type" is DST_TYPE_KEY look for a KEY record otherwise DNSKEY.
|
||||
* \li "mctx" is a valid memory context.
|
||||
* \li "keyp" is not NULL and "*keyp" is NULL.
|
||||
*
|
||||
* Returns:
|
||||
|
|
@ -381,6 +434,22 @@ dst_key_read_public(const char *filename, int type,
|
|||
* \li If successful, *keyp will contain a valid key.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dst_key_read_state(const char *filename, isc_mem_t *mctx, dst_key_t **keyp);
|
||||
/*%<
|
||||
* Reads a key state from permanent storage.
|
||||
*
|
||||
* Requires:
|
||||
* \li "filename" is not NULL.
|
||||
* \li "mctx" is a valid memory context.
|
||||
* \li "keyp" is not NULL and "*keyp" is NULL.
|
||||
*
|
||||
* Returns:
|
||||
* \li ISC_R_SUCCESS
|
||||
* \li ISC_R_UNEXPECTEDTOKEN if the file can not be parsed as a public key
|
||||
* \li any other result indicates failure
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dst_key_tofile(const dst_key_t *key, int type, const char *directory);
|
||||
/*%<
|
||||
|
|
@ -811,6 +880,37 @@ dst_key_setflags(dst_key_t *key, uint32_t flags);
|
|||
* "key" is a valid key.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dst_key_getbool(const dst_key_t *key, int type, bool *valuep);
|
||||
/*%<
|
||||
* Get a member of the boolean metadata array and place it in '*valuep'.
|
||||
*
|
||||
* Requires:
|
||||
* "key" is a valid key.
|
||||
* "type" is no larger than DST_MAX_BOOLEAN
|
||||
* "valuep" is not null.
|
||||
*/
|
||||
|
||||
void
|
||||
dst_key_setbool(dst_key_t *key, int type, bool value);
|
||||
/*%<
|
||||
* Set a member of the boolean metadata array.
|
||||
*
|
||||
* Requires:
|
||||
* "key" is a valid key.
|
||||
* "type" is no larger than DST_MAX_BOOLEAN
|
||||
*/
|
||||
|
||||
void
|
||||
dst_key_unsetbool(dst_key_t *key, int type);
|
||||
/*%<
|
||||
* Flag a member of the boolean metadata array as "not set".
|
||||
*
|
||||
* Requires:
|
||||
* "key" is a valid key.
|
||||
* "type" is no larger than DST_MAX_BOOLEAN
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dst_key_getnum(const dst_key_t *key, int type, uint32_t *valuep);
|
||||
/*%<
|
||||
|
|
@ -819,7 +919,7 @@ dst_key_getnum(const dst_key_t *key, int type, uint32_t *valuep);
|
|||
* Requires:
|
||||
* "key" is a valid key.
|
||||
* "type" is no larger than DST_MAX_NUMERIC
|
||||
* "timep" is not null.
|
||||
* "valuep" is not null.
|
||||
*/
|
||||
|
||||
void
|
||||
|
|
@ -873,6 +973,38 @@ dst_key_unsettime(dst_key_t *key, int type);
|
|||
* "type" is no larger than DST_MAX_TIMES
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dst_key_getstate(const dst_key_t *key, int type, dst_key_state_t *statep);
|
||||
/*%<
|
||||
* Get a member of the keystate metadata array and place it in '*statep'.
|
||||
*
|
||||
* Requires:
|
||||
* "key" is a valid key.
|
||||
* "type" is no larger than DST_MAX_KEYSTATES
|
||||
* "statep" is not null.
|
||||
*/
|
||||
|
||||
void
|
||||
dst_key_setstate(dst_key_t *key, int type, dst_key_state_t state);
|
||||
/*%<
|
||||
* Set a member of the keystate metadata array.
|
||||
*
|
||||
* Requires:
|
||||
* "key" is a valid key.
|
||||
* "state" is a valid state.
|
||||
* "type" is no larger than DST_MAX_KEYSTATES
|
||||
*/
|
||||
|
||||
void
|
||||
dst_key_unsetstate(dst_key_t *key, int type);
|
||||
/*%<
|
||||
* Flag a member of the keystate metadata array as "not set".
|
||||
*
|
||||
* Requires:
|
||||
* "key" is a valid key.
|
||||
* "type" is no larger than DST_MAX_KEYSTATES
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dst_key_getprivateformat(const dst_key_t *key, int *majorp, int *minorp);
|
||||
/*%<
|
||||
|
|
@ -961,9 +1093,88 @@ dst_key_setinactive(dst_key_t *key, bool inactive);
|
|||
|
||||
void
|
||||
dst_key_setexternal(dst_key_t *key, bool value);
|
||||
/*%<
|
||||
* Set key external state.
|
||||
*
|
||||
* Requires:
|
||||
* 'key' to be valid.
|
||||
*/
|
||||
|
||||
bool
|
||||
dst_key_isexternal(dst_key_t *key);
|
||||
/*%<
|
||||
* Check if this is an external key.
|
||||
*
|
||||
* Requires:
|
||||
* 'key' to be valid.
|
||||
*/
|
||||
|
||||
bool
|
||||
dst_key_is_unused(dst_key_t *key);
|
||||
/*%<
|
||||
* Check if this key is unused.
|
||||
*
|
||||
* Requires:
|
||||
* 'key' to be valid.
|
||||
*/
|
||||
|
||||
bool
|
||||
dst_key_is_published(dst_key_t *key, isc_stdtime_t now, isc_stdtime_t *publish);
|
||||
/*%<
|
||||
* Check if it is safe to publish this key (e.g. put the DNSKEY in the zone).
|
||||
*
|
||||
* Requires:
|
||||
* 'key' to be valid.
|
||||
*/
|
||||
|
||||
bool
|
||||
dst_key_is_active(dst_key_t *key, isc_stdtime_t now);
|
||||
/*%<
|
||||
* Check if this key is active. This means that it is creating RRSIG records
|
||||
* (ZSK), or that it is used to create a chain of trust (KSK), or both (CSK).
|
||||
*
|
||||
* Requires:
|
||||
* 'key' to be valid.
|
||||
*/
|
||||
|
||||
bool
|
||||
dst_key_is_signing(dst_key_t *key, int role, isc_stdtime_t now,
|
||||
isc_stdtime_t *active);
|
||||
/*%<
|
||||
* Check if it is safe to use this key for signing, given the role.
|
||||
*
|
||||
* Requires:
|
||||
* 'key' to be valid.
|
||||
*/
|
||||
|
||||
bool
|
||||
dst_key_is_revoked(dst_key_t *key, isc_stdtime_t now, isc_stdtime_t *revoke);
|
||||
/*%<
|
||||
* Check if this key is revoked.
|
||||
*
|
||||
* Requires:
|
||||
* 'key' to be valid.
|
||||
*/
|
||||
|
||||
bool
|
||||
dst_key_is_removed(dst_key_t *key, isc_stdtime_t now, isc_stdtime_t *remove);
|
||||
/*%<
|
||||
* Check if this key is removed from the zone (e.g. the DNSKEY record should
|
||||
* no longer be in the zone).
|
||||
*
|
||||
* Requires:
|
||||
* 'key' to be valid.
|
||||
*/
|
||||
|
||||
void
|
||||
dst_key_copy_metadata(dst_key_t *to, dst_key_t *from);
|
||||
/*%<
|
||||
* Copy key metadata from one key to another.
|
||||
*
|
||||
* Requires:
|
||||
* 'to' and 'from' to be valid.
|
||||
*/
|
||||
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
|
|
|
|||
442
lib/dns/kasp.c
Normal file
442
lib/dns/kasp.c
Normal file
|
|
@ -0,0 +1,442 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <isc/file.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/log.h>
|
||||
#include <dns/kasp.h>
|
||||
#include <dns/keyvalues.h>
|
||||
|
||||
isc_result_t
|
||||
dns_kasp_create(isc_mem_t *mctx, const char *name, dns_kasp_t **kaspp)
|
||||
{
|
||||
dns_kasp_t *kasp;
|
||||
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(kaspp != NULL && *kaspp == NULL);
|
||||
|
||||
kasp = isc_mem_get(mctx, sizeof(*kasp));
|
||||
kasp->mctx = NULL;
|
||||
isc_mem_attach(mctx, &kasp->mctx);
|
||||
|
||||
kasp->name = isc_mem_strdup(mctx, name);
|
||||
isc_mutex_init(&kasp->lock);
|
||||
kasp->frozen = false;
|
||||
|
||||
isc_refcount_init(&kasp->references, 1);
|
||||
|
||||
ISC_LINK_INIT(kasp, link);
|
||||
|
||||
kasp->signatures_refresh = DNS_KASP_SIG_REFRESH;
|
||||
kasp->signatures_validity = DNS_KASP_SIG_VALIDITY;
|
||||
kasp->signatures_validity_dnskey = DNS_KASP_SIG_VALIDITY_DNSKEY;
|
||||
|
||||
ISC_LIST_INIT(kasp->keys);
|
||||
|
||||
kasp->dnskey_ttl = DNS_KASP_KEY_TTL;
|
||||
kasp->publish_safety = DNS_KASP_PUBLISH_SAFETY;
|
||||
kasp->retire_safety = DNS_KASP_RETIRE_SAFETY;
|
||||
|
||||
kasp->zone_max_ttl = DNS_KASP_ZONE_MAXTTL;
|
||||
kasp->zone_propagation_delay = DNS_KASP_ZONE_PROPDELAY;
|
||||
|
||||
kasp->parent_ds_ttl = DNS_KASP_DS_TTL;
|
||||
kasp->parent_propagation_delay = DNS_KASP_PARENT_PROPDELAY;
|
||||
kasp->parent_registration_delay = DNS_KASP_PARENT_REGDELAY;
|
||||
|
||||
// TODO: The rest of the KASP configuration
|
||||
|
||||
kasp->magic = DNS_KASP_MAGIC;
|
||||
*kaspp = kasp;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_attach(dns_kasp_t *source, dns_kasp_t **targetp) {
|
||||
REQUIRE(DNS_KASP_VALID(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
isc_refcount_increment(&source->references);
|
||||
*targetp = source;
|
||||
}
|
||||
|
||||
static inline void
|
||||
destroy(dns_kasp_t *kasp) {
|
||||
dns_kasp_key_t *key;
|
||||
dns_kasp_key_t *key_next;
|
||||
|
||||
ISC_INSIST(!ISC_LINK_LINKED(kasp, link));
|
||||
|
||||
for (key = ISC_LIST_HEAD(kasp->keys); key != NULL; key = key_next) {
|
||||
key_next = ISC_LIST_NEXT(key, link);
|
||||
ISC_LIST_UNLINK(kasp->keys, key, link);
|
||||
dns_kasp_key_destroy(key);
|
||||
}
|
||||
ISC_INSIST(ISC_LIST_EMPTY(kasp->keys));
|
||||
|
||||
isc_mem_free(kasp->mctx, kasp->name);
|
||||
isc_mem_putanddetach(&kasp->mctx, kasp, sizeof(*kasp));
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_detach(dns_kasp_t **kaspp) {
|
||||
REQUIRE(kaspp != NULL && DNS_KASP_VALID(*kaspp));
|
||||
dns_kasp_t *kasp = *kaspp;
|
||||
*kaspp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&kasp->references) == 1) {
|
||||
destroy(kasp);
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
dns_kasp_getname(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
return (kasp->name);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_freeze(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
kasp->frozen = true;
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_thaw(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
kasp->frozen = false;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_kasp_signdelay(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->signatures_validity - kasp->signatures_refresh);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_kasp_sigrefresh(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->signatures_refresh);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_setsigrefresh(dns_kasp_t *kasp, uint32_t value) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
kasp->signatures_refresh = value;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_kasp_sigvalidity(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->signatures_validity);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_setsigvalidity(dns_kasp_t *kasp, uint32_t value) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
kasp->signatures_validity = value;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_kasp_sigvalidity_dnskey(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->signatures_validity_dnskey);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_setsigvalidity_dnskey(dns_kasp_t *kasp, uint32_t value) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
kasp->signatures_validity = value;
|
||||
}
|
||||
|
||||
dns_ttl_t
|
||||
dns_kasp_dnskeyttl(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->dnskey_ttl);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_setdnskeyttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
kasp->dnskey_ttl = ttl;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_kasp_publishsafety(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->publish_safety);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_setpublishsafety(dns_kasp_t *kasp, uint32_t value) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
kasp->publish_safety = value;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_kasp_retiresafety(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->retire_safety);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_setretiresafety(dns_kasp_t *kasp, uint32_t value) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
kasp->retire_safety = value;
|
||||
}
|
||||
|
||||
dns_ttl_t
|
||||
dns_kasp_zonemaxttl(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->zone_max_ttl);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_setzonemaxttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
kasp->zone_max_ttl = ttl;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_kasp_zonepropagationdelay(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->zone_propagation_delay);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_setzonepropagationdelay(dns_kasp_t *kasp, uint32_t value) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
kasp->zone_propagation_delay = value;
|
||||
}
|
||||
|
||||
dns_ttl_t
|
||||
dns_kasp_dsttl(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->parent_ds_ttl);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_setdsttl(dns_kasp_t *kasp, dns_ttl_t ttl) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
kasp->parent_ds_ttl = ttl;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_kasp_parentpropagationdelay(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->parent_propagation_delay);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_setparentpropagationdelay(dns_kasp_t *kasp, uint32_t value) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
kasp->parent_propagation_delay = value;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_kasp_parentregistrationdelay(dns_kasp_t *kasp) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->parent_registration_delay);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_setparentregistrationdelay(dns_kasp_t *kasp, uint32_t value) {
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
kasp->parent_registration_delay = value;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_kasplist_find(dns_kasplist_t *list, const char *name, dns_kasp_t **kaspp)
|
||||
{
|
||||
dns_kasp_t *kasp = NULL;
|
||||
|
||||
REQUIRE(kaspp != NULL && *kaspp == NULL);
|
||||
|
||||
if (list == NULL) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
INSIST(list != NULL);
|
||||
|
||||
for (kasp = ISC_LIST_HEAD(*list); kasp != NULL;
|
||||
kasp = ISC_LIST_NEXT(kasp, link))
|
||||
{
|
||||
if (strcmp(kasp->name, name) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (kasp == NULL) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
dns_kasp_attach(kasp, kaspp);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
dns_kasp_keylist_t
|
||||
dns_kasp_keys(dns_kasp_t *kasp)
|
||||
{
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(kasp->frozen);
|
||||
return (kasp->keys);
|
||||
}
|
||||
|
||||
bool
|
||||
dns_kasp_keylist_empty(dns_kasp_t *kasp)
|
||||
{
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
return (ISC_LIST_EMPTY(kasp->keys));
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_addkey(dns_kasp_t *kasp, dns_kasp_key_t *key)
|
||||
{
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(!kasp->frozen);
|
||||
REQUIRE(key != NULL);
|
||||
|
||||
ISC_LIST_APPEND(kasp->keys, key, link);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_kasp_key_create(dns_kasp_t *kasp, dns_kasp_key_t **keyp)
|
||||
{
|
||||
dns_kasp_key_t *key;
|
||||
|
||||
REQUIRE(DNS_KASP_VALID(kasp));
|
||||
REQUIRE(keyp != NULL && *keyp == NULL);
|
||||
|
||||
key = isc_mem_get(kasp->mctx, sizeof(*key));
|
||||
key->mctx = NULL;
|
||||
isc_mem_attach(kasp->mctx, &key->mctx);
|
||||
|
||||
ISC_LINK_INIT(key, link);
|
||||
|
||||
key->lifetime = 0;
|
||||
key->algorithm = 0;
|
||||
key->length = -1;
|
||||
key->role = 0;
|
||||
*keyp = key;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
dns_kasp_key_destroy(dns_kasp_key_t* key)
|
||||
{
|
||||
REQUIRE(key != NULL);
|
||||
isc_mem_putanddetach(&key->mctx, key, sizeof(*key));
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_kasp_key_algorithm(dns_kasp_key_t *key) {
|
||||
|
||||
REQUIRE(key != NULL);
|
||||
return (key->algorithm);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
dns_kasp_key_size(dns_kasp_key_t *key) {
|
||||
unsigned int size = 0;
|
||||
unsigned int min = 0;
|
||||
|
||||
REQUIRE(key != NULL);
|
||||
|
||||
switch (key->algorithm) {
|
||||
case DNS_KEYALG_RSASHA1:
|
||||
case DNS_KEYALG_NSEC3RSASHA1:
|
||||
case DNS_KEYALG_RSASHA256:
|
||||
case DNS_KEYALG_RSASHA512:
|
||||
min = DNS_KEYALG_RSASHA512 ? 1024 : 512;
|
||||
if (key->length > -1) {
|
||||
size = (unsigned int) key->length;
|
||||
if (size < min) {
|
||||
size = min;
|
||||
}
|
||||
if (size > 4096) {
|
||||
size = 4096;
|
||||
}
|
||||
} else if (key->role & DNS_KASP_KEY_ROLE_KSK) {
|
||||
size = 2048;
|
||||
} else {
|
||||
size = 1024;
|
||||
}
|
||||
break;
|
||||
case DNS_KEYALG_ECDSA256:
|
||||
size = 256;
|
||||
break;
|
||||
case DNS_KEYALG_ECDSA384:
|
||||
size = 384;
|
||||
break;
|
||||
case DNS_KEYALG_ED25519:
|
||||
size = 32;
|
||||
break;
|
||||
case DNS_KEYALG_ED448:
|
||||
size = 57;
|
||||
break;
|
||||
default:
|
||||
/* unsupported */
|
||||
break;
|
||||
}
|
||||
return (size);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dns_kasp_key_lifetime(dns_kasp_key_t *key) {
|
||||
|
||||
REQUIRE(key != NULL);
|
||||
return (key->lifetime);
|
||||
}
|
||||
|
||||
bool
|
||||
dns_kasp_key_ksk(dns_kasp_key_t *key) {
|
||||
|
||||
REQUIRE(key != NULL);
|
||||
return (key->role & DNS_KASP_KEY_ROLE_KSK);
|
||||
}
|
||||
|
||||
bool
|
||||
dns_kasp_key_zsk(dns_kasp_key_t *key) {
|
||||
|
||||
REQUIRE(key != NULL);
|
||||
return (key->role & DNS_KASP_KEY_ROLE_ZSK);
|
||||
}
|
||||
1573
lib/dns/keymgr.c
Normal file
1573
lib/dns/keymgr.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -35,6 +35,7 @@
|
|||
#include <dns/events.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/journal.h>
|
||||
#include <dns/kasp.h>
|
||||
#include <dns/keyvalues.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/message.h>
|
||||
|
|
@ -1076,6 +1077,7 @@ add_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
|
|||
{
|
||||
isc_result_t result;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_kasp_t *kasp = dns_zone_getkasp(zone);
|
||||
dns_rdataset_t rdataset;
|
||||
dns_rdata_t sig_rdata = DNS_RDATA_INIT;
|
||||
dns_stats_t* dnssecsignstats = dns_zone_getdnssecsignstats(zone);
|
||||
|
|
@ -1085,6 +1087,11 @@ add_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
|
|||
bool added_sig = false;
|
||||
isc_mem_t *mctx = diff->mctx;
|
||||
|
||||
if (kasp != NULL) {
|
||||
check_ksk = false;
|
||||
keyset_kskonly = true;
|
||||
}
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
isc_buffer_init(&buffer, data, sizeof(data));
|
||||
|
||||
|
|
@ -1155,7 +1162,63 @@ add_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
|
|||
}
|
||||
}
|
||||
|
||||
if (both) {
|
||||
if (kasp != NULL) {
|
||||
/*
|
||||
* A dnssec-policy is found. Check what RRsets this
|
||||
* key should sign.
|
||||
*/
|
||||
isc_stdtime_t when;
|
||||
isc_result_t kresult;
|
||||
bool ksk = false;
|
||||
bool zsk = false;
|
||||
|
||||
kresult = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk);
|
||||
if (kresult != ISC_R_SUCCESS) {
|
||||
if (KSK(keys[i])) {
|
||||
ksk = true;
|
||||
}
|
||||
}
|
||||
kresult = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk);
|
||||
if (kresult != ISC_R_SUCCESS) {
|
||||
if (!KSK(keys[i])) {
|
||||
zsk = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == dns_rdatatype_dnskey ||
|
||||
type == dns_rdatatype_cdnskey ||
|
||||
type == dns_rdatatype_cds)
|
||||
{
|
||||
/*
|
||||
* DNSKEY RRset is signed with KSK.
|
||||
* CDS and CDNSKEY RRsets too (RFC 7344, 4.1).
|
||||
*/
|
||||
if (!ksk) {
|
||||
continue;
|
||||
}
|
||||
} else if (!zsk) {
|
||||
/*
|
||||
* Other RRsets are signed with ZSK.
|
||||
*/
|
||||
continue;
|
||||
} else if (zsk && !dst_key_is_signing(keys[i],
|
||||
DST_BOOL_ZSK,
|
||||
inception,
|
||||
&when)) {
|
||||
/*
|
||||
* This key is not active for zone-signing.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this key is revoked, it may only sign the
|
||||
* DNSKEY RRset.
|
||||
*/
|
||||
if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
|
||||
continue;
|
||||
}
|
||||
} else if (both) {
|
||||
/*
|
||||
* CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1).
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -316,6 +316,7 @@ dns_dns64_next
|
|||
dns_dns64_unlink
|
||||
dns_dnssec_findmatchingkeys
|
||||
dns_dnssec_findzonekeys
|
||||
dns_dnssec_get_hints
|
||||
dns_dnssec_keyactive
|
||||
dns_dnssec_keyfromrdata
|
||||
dns_dnssec_keylistfromrdataset
|
||||
|
|
@ -413,9 +414,50 @@ dns_journal_rollforward
|
|||
dns_journal_set_sourceserial
|
||||
dns_journal_write_transaction
|
||||
dns_journal_writediff
|
||||
dns_kasp_addkey
|
||||
dns_kasp_attach
|
||||
dns_kasp_create
|
||||
dns_kasp_detach
|
||||
dns_kasp_dnskeyttl
|
||||
dns_kasp_dsttl
|
||||
dns_kasp_freeze
|
||||
dns_kasp_getname
|
||||
dns_kasp_key_algorithm
|
||||
dns_kasp_key_create
|
||||
dns_kasp_key_destroy
|
||||
dns_kasp_key_ksk
|
||||
dns_kasp_key_lifetime
|
||||
dns_kasp_key_size
|
||||
dns_kasp_key_zsk
|
||||
dns_kasp_keylist_empty
|
||||
dns_kasp_keys
|
||||
dns_kasp_parentpropagationdelay
|
||||
dns_kasp_parentregistrationdelay
|
||||
dns_kasp_publishsafety
|
||||
dns_kasp_retiresafety
|
||||
dns_kasp_setdnskeyttl
|
||||
dns_kasp_setdsttl
|
||||
dns_kasp_setparentpropagationdelay
|
||||
dns_kasp_setparentregistrationdelay
|
||||
dns_kasp_setpublishsafety
|
||||
dns_kasp_setretiresafety
|
||||
dns_kasp_setsigrefresh
|
||||
dns_kasp_setsigvalidity
|
||||
dns_kasp_setsigvalidity_dnskey
|
||||
dns_kasp_setzonemaxttl
|
||||
dns_kasp_setzonepropagationdelay
|
||||
dns_kasp_signdelay
|
||||
dns_kasp_sigrefresh
|
||||
dns_kasp_sigvalidity
|
||||
dns_kasp_sigvalidity_dnskey
|
||||
dns_kasp_thaw
|
||||
dns_kasp_zonemaxttl
|
||||
dns_kasp_zonepropagationdelay
|
||||
dns_kasplist_find
|
||||
dns_keydata_fromdnskey
|
||||
dns_keydata_todnskey
|
||||
dns_keyflags_fromtext
|
||||
dns_keymgr_run
|
||||
dns_keynode_attach
|
||||
dns_keynode_create
|
||||
dns_keynode_detach
|
||||
|
|
@ -1154,6 +1196,7 @@ dns_zone_getidleout
|
|||
dns_zone_getincludes
|
||||
dns_zone_getjournal
|
||||
dns_zone_getjournalsize
|
||||
dns_zone_getkasp
|
||||
dns_zone_getkeydirectory
|
||||
dns_zone_getkeyopts
|
||||
dns_zone_getkeyvalidityinterval
|
||||
|
|
@ -1255,6 +1298,7 @@ dns_zone_setidleout
|
|||
dns_zone_setisself
|
||||
dns_zone_setjournal
|
||||
dns_zone_setjournalsize
|
||||
dns_zone_setkasp
|
||||
dns_zone_setkeydirectory
|
||||
dns_zone_setkeyopt
|
||||
dns_zone_setkeyvalidityinterval
|
||||
|
|
@ -1375,6 +1419,7 @@ dst_key_attach
|
|||
dst_key_buildfilename
|
||||
dst_key_buildinternal
|
||||
dst_key_class
|
||||
dst_key_copy_metadata
|
||||
dst_key_compare
|
||||
dst_key_computesecret
|
||||
dst_key_dump
|
||||
|
|
@ -1389,13 +1434,21 @@ dst_key_fromlabel
|
|||
dst_key_fromnamedfile
|
||||
dst_key_generate
|
||||
dst_key_getbits
|
||||
dst_key_getbool
|
||||
dst_key_getfilename
|
||||
dst_key_getgssctx
|
||||
dst_key_getnum
|
||||
dst_key_getprivateformat
|
||||
dst_key_getstate
|
||||
dst_key_gettime
|
||||
dst_key_getttl
|
||||
dst_key_id
|
||||
dst_key_is_active
|
||||
dst_key_is_published
|
||||
dst_key_is_removed
|
||||
dst_key_is_revoked
|
||||
dst_key_is_signing
|
||||
dst_key_is_unused
|
||||
dst_key_inactive
|
||||
dst_key_isexternal
|
||||
dst_key_isnullkey
|
||||
|
|
@ -1407,15 +1460,18 @@ dst_key_privatefrombuffer
|
|||
dst_key_proto
|
||||
dst_key_pubcompare
|
||||
dst_key_read_public
|
||||
dst_key_read_state
|
||||
dst_key_restore
|
||||
dst_key_rid
|
||||
dst_key_secretsize
|
||||
dst_key_setbits
|
||||
dst_key_setbool
|
||||
dst_key_setexternal
|
||||
dst_key_setflags
|
||||
dst_key_setinactive
|
||||
dst_key_setnum
|
||||
dst_key_setprivateformat
|
||||
dst_key_setstate
|
||||
dst_key_settime
|
||||
dst_key_setttl
|
||||
dst_key_sigsize
|
||||
|
|
@ -1424,7 +1480,9 @@ dst_key_tkeytoken
|
|||
dst_key_tobuffer
|
||||
dst_key_todns
|
||||
dst_key_tofile
|
||||
dst_key_unsetbool
|
||||
dst_key_unsetnum
|
||||
dst_key_unsetstate
|
||||
dst_key_unsettime
|
||||
dst_lib_destroy
|
||||
dst_lib_init
|
||||
|
|
|
|||
|
|
@ -116,9 +116,15 @@
|
|||
<ClCompile Include="..\journal.c">
|
||||
<Filter>Library Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\kasp.c">
|
||||
<Filter>Library Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\keydata.c">
|
||||
<Filter>Library Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\keymgr.c">
|
||||
<Filter>Library Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\keytable.c">
|
||||
<Filter>Library Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -449,12 +455,18 @@
|
|||
<ClInclude Include="..\include\dns\journal.h">
|
||||
<Filter>Library Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\dns\kasp.h">
|
||||
<Filter>Library Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\dns\keydata.h">
|
||||
<Filter>Library Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\dns\keyflags.h">
|
||||
<Filter>Library Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\dns\keymgr.h">
|
||||
<Filter>Library Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\dns\keytable.h">
|
||||
<Filter>Library Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -150,7 +150,9 @@
|
|||
<ClCompile Include="..\ipkeylist.c" />
|
||||
<ClCompile Include="..\iptable.c" />
|
||||
<ClCompile Include="..\journal.c" />
|
||||
<ClCompile Include="..\kasp.c" />
|
||||
<ClCompile Include="..\key.c" />
|
||||
<ClCompile Include="..\keymgr.c" />
|
||||
<ClCompile Include="..\keydata.c" />
|
||||
<ClCompile Include="..\keytable.c" />
|
||||
<ClCompile Include="..\lib.c" />
|
||||
|
|
@ -265,8 +267,10 @@
|
|||
<ClInclude Include="..\include\dns\ipkeylist.h" />
|
||||
<ClInclude Include="..\include\dns\iptable.h" />
|
||||
<ClInclude Include="..\include\dns\journal.h" />
|
||||
<ClInclude Include="..\include\dns\kasp.h" />
|
||||
<ClInclude Include="..\include\dns\keydata.h" />
|
||||
<ClInclude Include="..\include\dns\keyflags.h" />
|
||||
<ClInclude Include="..\include\dns\keymgr.h" />
|
||||
<ClInclude Include="..\include\dns\keytable.h" />
|
||||
<ClInclude Include="..\include\dns\keyvalues.h" />
|
||||
<ClInclude Include="..\include\dns\lib.h" />
|
||||
|
|
|
|||
472
lib/dns/zone.c
472
lib/dns/zone.c
|
|
@ -45,7 +45,9 @@
|
|||
#include <dns/dnssec.h>
|
||||
#include <dns/events.h>
|
||||
#include <dns/journal.h>
|
||||
#include <dns/kasp.h>
|
||||
#include <dns/keydata.h>
|
||||
#include <dns/keymgr.h>
|
||||
#include <dns/keytable.h>
|
||||
#include <dns/keyvalues.h>
|
||||
#include <dns/log.h>
|
||||
|
|
@ -303,6 +305,7 @@ struct dns_zone {
|
|||
uint32_t sigresigninginterval;
|
||||
dns_view_t *view;
|
||||
dns_view_t *prev_view;
|
||||
dns_kasp_t *kasp;
|
||||
dns_checkmxfunc_t checkmx;
|
||||
dns_checksrvfunc_t checksrv;
|
||||
dns_checknsfunc_t checkns;
|
||||
|
|
@ -1014,6 +1017,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
|||
zone->sigvalidityinterval = 30 * 24 * 3600;
|
||||
zone->keyvalidityinterval = 0;
|
||||
zone->sigresigninginterval = 7 * 24 * 3600;
|
||||
zone->kasp = NULL;
|
||||
zone->view = NULL;
|
||||
zone->prev_view = NULL;
|
||||
zone->checkmx = NULL;
|
||||
|
|
@ -1184,6 +1188,9 @@ zone_free(dns_zone_t *zone) {
|
|||
isc_mem_free(zone->mctx, zone->keydirectory);
|
||||
}
|
||||
zone->keydirectory = NULL;
|
||||
if (zone->kasp != NULL) {
|
||||
dns_kasp_detach(&zone->kasp);
|
||||
}
|
||||
zone->journalsize = -1;
|
||||
if (zone->journal != NULL) {
|
||||
isc_mem_free(zone->mctx, zone->journal);
|
||||
|
|
@ -1880,7 +1887,7 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
|
|||
isc_time_t now;
|
||||
isc_time_t loadtime;
|
||||
dns_db_t *db = NULL;
|
||||
bool rbt, hasraw;
|
||||
bool rbt, hasraw, is_dynamic;
|
||||
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
|
|
@ -1945,11 +1952,13 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if (zone->db != NULL && dns_zone_isdynamic(zone, false)) {
|
||||
is_dynamic = dns_zone_isdynamic(zone, false) ||
|
||||
dns_zone_getkasp(zone) != NULL;
|
||||
if (zone->db != NULL && is_dynamic) {
|
||||
/*
|
||||
* This is a slave, stub, or dynamically updated
|
||||
* zone being reloaded. Do nothing - the database
|
||||
* we already have is guaranteed to be up-to-date.
|
||||
* This is a slave, stub, dynamically updated, or kasp enabled
|
||||
* zone being reloaded. Do nothing - the database we already
|
||||
* have is guaranteed to be up-to-date.
|
||||
*/
|
||||
if (zone->type == dns_zone_master && !hasraw)
|
||||
result = DNS_R_DYNAMIC;
|
||||
|
|
@ -3647,8 +3656,9 @@ set_resigntime(dns_zone_t *zone) {
|
|||
dns_db_t *db = NULL;
|
||||
|
||||
/* We only re-sign zones that can be dynamically updated */
|
||||
if (zone->update_disabled)
|
||||
if (zone->update_disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inline_secure(zone) && (zone->type != dns_zone_master ||
|
||||
(zone->ssutable == NULL &&
|
||||
|
|
@ -3674,10 +3684,11 @@ set_resigntime(dns_zone_t *zone) {
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
resign = rdataset.resign - zone->sigresigninginterval;
|
||||
resign = rdataset.resign - dns_zone_getsigresigninginterval(zone);
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
nanosecs = isc_random_uniform(1000000000);
|
||||
isc_time_set(&zone->resigntime, resign, nanosecs);
|
||||
|
||||
cleanup:
|
||||
dns_db_detach(&db);
|
||||
return;
|
||||
|
|
@ -3694,6 +3705,7 @@ check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
|
|||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
bool dynamic = (zone->type == dns_zone_master)
|
||||
? dns_zone_isdynamic(zone, false) : false;
|
||||
dynamic = dynamic || dns_zone_getkasp(zone);
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
result = dns_db_findnode(db, &zone->origin, false, &node);
|
||||
|
|
@ -4500,6 +4512,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||
bool had_db = false;
|
||||
unsigned int options;
|
||||
dns_include_t *inc;
|
||||
bool is_dynamic = false;
|
||||
|
||||
INSIST(LOCKED_ZONE(zone));
|
||||
if (inline_raw(zone)) {
|
||||
|
|
@ -4640,7 +4653,9 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||
* journal file if it isn't, as we wouldn't be able to apply
|
||||
* updates otherwise.
|
||||
*/
|
||||
if (zone->journal != NULL && dns_zone_isdynamic(zone, true) &&
|
||||
is_dynamic = dns_zone_isdynamic(zone, true) ||
|
||||
dns_zone_getkasp(zone) != NULL;
|
||||
if (zone->journal != NULL && is_dynamic &&
|
||||
! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS))
|
||||
{
|
||||
uint32_t jserial;
|
||||
|
|
@ -4812,7 +4827,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||
|
||||
if (zone->type == dns_zone_master &&
|
||||
(zone->update_acl != NULL || zone->ssutable != NULL) &&
|
||||
zone->sigresigninginterval < (3 * refresh) &&
|
||||
dns_zone_getsigresigninginterval(zone) < (3 * refresh) &&
|
||||
dns_db_issecure(db))
|
||||
{
|
||||
dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
|
||||
|
|
@ -4944,10 +4959,11 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||
resume_addnsec3chain(zone);
|
||||
}
|
||||
|
||||
is_dynamic = dns_zone_isdynamic(zone, false) ||
|
||||
dns_zone_getkasp(zone) != NULL;
|
||||
if (zone->type == dns_zone_master &&
|
||||
!DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
|
||||
dns_zone_isdynamic(zone, false) &&
|
||||
dns_db_issecure(db))
|
||||
is_dynamic && dns_db_issecure(db))
|
||||
{
|
||||
dns_name_t *name;
|
||||
dns_fixedname_t fixed;
|
||||
|
|
@ -4970,7 +4986,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||
"next resign: %s/%s "
|
||||
"in %d seconds", namebuf, typebuf,
|
||||
next.resign - timenow -
|
||||
zone->sigresigninginterval);
|
||||
dns_zone_getsigresigninginterval(zone));
|
||||
dns_rdataset_disassociate(&next);
|
||||
} else {
|
||||
dnssec_log(zone, ISC_LOG_WARNING,
|
||||
|
|
@ -5007,7 +5023,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||
zone->nincludes++;
|
||||
}
|
||||
|
||||
if (! dns_db_ispersistent(db)) {
|
||||
if (!dns_db_ispersistent(db)) {
|
||||
dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
|
||||
ISC_LOG_INFO, "loaded serial %u%s", serial,
|
||||
dns_db_issecure(db) ? " (DNSSEC signed)" : "");
|
||||
|
|
@ -5063,7 +5079,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||
} else if (zone->type == dns_zone_master ||
|
||||
zone->type == dns_zone_redirect)
|
||||
{
|
||||
if (! (inline_secure(zone) && result == ISC_R_FILENOTFOUND)) {
|
||||
if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) {
|
||||
dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
|
||||
ISC_LOG_ERROR,
|
||||
"not loaded due to errors.");
|
||||
|
|
@ -5537,6 +5553,29 @@ dns_zone_setflag(dns_zone_t *zone, unsigned int flags, bool value) {
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t* kasp)
|
||||
{
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
LOCK_ZONE(zone);
|
||||
if (zone->kasp != NULL) {
|
||||
dns_kasp_t* oldkasp = zone->kasp;
|
||||
zone->kasp = NULL;
|
||||
dns_kasp_detach(&oldkasp);
|
||||
}
|
||||
zone->kasp = kasp;
|
||||
UNLOCK_ZONE(zone);
|
||||
}
|
||||
|
||||
dns_kasp_t*
|
||||
dns_zone_getkasp(dns_zone_t *zone)
|
||||
{
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
return (zone->kasp);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option,
|
||||
bool value)
|
||||
|
|
@ -6231,22 +6270,41 @@ delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
|
|||
bool *warn)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
isc_result_t ret;
|
||||
bool have_ksk = false, have_zsk = false;
|
||||
bool have_pksk = false, have_pzsk = false;
|
||||
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
if (rrsig_ptr->algorithm != dst_key_alg(keys[i]))
|
||||
bool ksk, zsk;
|
||||
|
||||
if (have_pksk && have_ksk && have_pzsk && have_zsk) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) {
|
||||
continue;
|
||||
if (dst_key_isprivate(keys[i])) {
|
||||
if (KSK(keys[i]))
|
||||
have_ksk = have_pksk = true;
|
||||
else
|
||||
have_zsk = have_pzsk = true;
|
||||
} else {
|
||||
if (KSK(keys[i]))
|
||||
have_ksk = true;
|
||||
else
|
||||
have_zsk = true;
|
||||
}
|
||||
|
||||
ret = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
ksk = KSK(keys[i]);
|
||||
}
|
||||
ret = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
zsk = !KSK(keys[i]);
|
||||
}
|
||||
|
||||
if (ksk) {
|
||||
have_ksk = true;
|
||||
if (dst_key_isprivate(keys[i])) {
|
||||
have_pksk = true;
|
||||
}
|
||||
}
|
||||
if (zsk) {
|
||||
have_zsk = true;
|
||||
if (dst_key_isprivate(keys[i])) {
|
||||
have_pzsk = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6325,7 +6383,9 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
|||
result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
if (type != dns_rdatatype_dnskey) {
|
||||
if (type != dns_rdatatype_dnskey &&
|
||||
type != dns_rdatatype_cds &&
|
||||
type != dns_rdatatype_cdnskey) {
|
||||
bool warn = false, deleted = false;
|
||||
if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
|
||||
result = update_one_rr(db, ver, zonediff->diff,
|
||||
|
|
@ -6380,7 +6440,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
|||
}
|
||||
|
||||
/*
|
||||
* RRSIG(DNSKEY) requires special processing.
|
||||
* KSK RRSIGs requires special processing.
|
||||
*/
|
||||
found = false;
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
|
|
@ -6388,7 +6448,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
|||
rrsig.keyid == dst_key_id(keys[i])) {
|
||||
found = true;
|
||||
/*
|
||||
* Mark offline RRSIG(DNSKEY).
|
||||
* Mark offline DNSKEY.
|
||||
* We want the earliest offline expire time
|
||||
* iff there is a new offline signature.
|
||||
*/
|
||||
|
|
@ -6465,6 +6525,7 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
|||
{
|
||||
isc_result_t result;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_kasp_t *kasp = dns_zone_getkasp(zone);
|
||||
dns_stats_t* dnssecsignstats;
|
||||
dns_stats_t* dnssecrefreshstats;
|
||||
dns_rdataset_t rdataset;
|
||||
|
|
@ -6473,6 +6534,11 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
|||
isc_buffer_t buffer;
|
||||
unsigned int i, j;
|
||||
|
||||
if (kasp != NULL) {
|
||||
check_ksk = false;
|
||||
keyset_kskonly = true;
|
||||
}
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
isc_buffer_init(&buffer, data, sizeof(data));
|
||||
|
||||
|
|
@ -6546,7 +6612,61 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
|||
}
|
||||
}
|
||||
|
||||
if (both) {
|
||||
if (kasp != NULL) {
|
||||
/*
|
||||
* A dnssec-policy is found. Check what RRsets this
|
||||
* key should sign.
|
||||
*/
|
||||
isc_result_t kresult;
|
||||
isc_stdtime_t when;
|
||||
bool ksk = false;
|
||||
bool zsk = false;
|
||||
|
||||
kresult = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk);
|
||||
if (kresult != ISC_R_SUCCESS) {
|
||||
if (KSK(keys[i])) {
|
||||
ksk = true;
|
||||
}
|
||||
}
|
||||
kresult = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk);
|
||||
if (kresult != ISC_R_SUCCESS) {
|
||||
if (!KSK(keys[i])) {
|
||||
zsk = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == dns_rdatatype_dnskey ||
|
||||
type == dns_rdatatype_cdnskey ||
|
||||
type == dns_rdatatype_cds)
|
||||
{
|
||||
/*
|
||||
* DNSKEY RRset is signed with KSK.
|
||||
* CDS and CDNSKEY RRsets too (RFC 7344, 4.1).
|
||||
*/
|
||||
if (!ksk) {
|
||||
continue;
|
||||
}
|
||||
} else if (!zsk) {
|
||||
/*
|
||||
* Other RRsets are signed with ZSK.
|
||||
*/
|
||||
continue;
|
||||
} else if (!dst_key_is_signing(keys[i], DST_BOOL_ZSK,
|
||||
inception, &when)) {
|
||||
/*
|
||||
* This key is not active for zone-signing.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this key is revoked, it may only sign the
|
||||
* DNSKEY RRset.
|
||||
*/
|
||||
if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
|
||||
continue;
|
||||
}
|
||||
} else if (both) {
|
||||
/*
|
||||
* CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1).
|
||||
*/
|
||||
|
|
@ -6659,7 +6779,7 @@ zone_resigninc(dns_zone_t *zone) {
|
|||
goto failure;
|
||||
}
|
||||
|
||||
sigvalidityinterval = zone->sigvalidityinterval;
|
||||
sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
|
||||
inception = now - 3600; /* Allow for clock skew. */
|
||||
soaexpire = now + sigvalidityinterval;
|
||||
expiryinterval = dns_zone_getsigresigninginterval(zone);
|
||||
|
|
@ -6706,7 +6826,8 @@ zone_resigninc(dns_zone_t *zone) {
|
|||
|
||||
i = 0;
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
resign = rdataset.resign - zone->sigresigninginterval;
|
||||
resign = rdataset.resign -
|
||||
dns_zone_getsigresigninginterval(zone);
|
||||
covers = rdataset.covers;
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
|
||||
|
|
@ -6878,13 +6999,16 @@ next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
|
|||
}
|
||||
|
||||
static bool
|
||||
signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
dns_rdatatype_t type, dst_key_t *key)
|
||||
signed_with_good_key(dns_zone_t* zone, dns_db_t *db, dns_dbnode_t *node,
|
||||
dns_dbversion_t *version, dns_rdatatype_t type,
|
||||
dst_key_t *key)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_rdataset_t rdataset;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_rrsig_t rrsig;
|
||||
int count = 0;
|
||||
dns_kasp_t *kasp = dns_zone_getkasp(zone);
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
|
||||
|
|
@ -6904,8 +7028,46 @@ signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
|||
dns_rdataset_disassociate(&rdataset);
|
||||
return (true);
|
||||
}
|
||||
if (rrsig.algorithm == dst_key_alg(key)) {
|
||||
count++;
|
||||
}
|
||||
dns_rdata_reset(&rdata);
|
||||
}
|
||||
|
||||
if (kasp) {
|
||||
dns_kasp_key_t* kkey;
|
||||
int zsk_count = 0;
|
||||
bool approved;
|
||||
|
||||
for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL;
|
||||
kkey = ISC_LIST_NEXT(kkey, link))
|
||||
{
|
||||
if (dns_kasp_key_algorithm(kkey) != dst_key_alg(key)) {
|
||||
continue;
|
||||
}
|
||||
if (dns_kasp_key_zsk(kkey)) {
|
||||
zsk_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == dns_rdatatype_dnskey ||
|
||||
type == dns_rdatatype_cdnskey || type == dns_rdatatype_cds)
|
||||
{
|
||||
/*
|
||||
* CDS and CDNSKEY are signed with KSK like DNSKEY.
|
||||
* (RFC 7344, section 4.1 specifies that they must
|
||||
* be signed with a key in the current DS RRset,
|
||||
* which would only include KSK's.)
|
||||
*/
|
||||
approved = false;
|
||||
} else {
|
||||
approved = (zsk_count == count);
|
||||
}
|
||||
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
return (approved);
|
||||
}
|
||||
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
return (false);
|
||||
}
|
||||
|
|
@ -6988,11 +7150,12 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
|
|||
dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
bool build_nsec3, bool build_nsec, dst_key_t *key,
|
||||
isc_stdtime_t inception, isc_stdtime_t expire,
|
||||
unsigned int minimum, bool is_ksk,
|
||||
unsigned int minimum, bool is_ksk, bool is_zsk,
|
||||
bool keyset_kskonly, bool is_bottom_of_zone,
|
||||
dns_diff_t *diff, int32_t *signatures, isc_mem_t *mctx)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_kasp_t *kasp = dns_zone_getkasp(zone);
|
||||
dns_rdatasetiter_t *iterator = NULL;
|
||||
dns_rdataset_t rdataset;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
|
|
@ -7060,6 +7223,8 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
|
|||
}
|
||||
result = dns_rdatasetiter_first(iterator);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
isc_stdtime_t when;
|
||||
|
||||
dns_rdatasetiter_current(iterator, &rdataset);
|
||||
if (rdataset.type == dns_rdatatype_soa ||
|
||||
rdataset.type == dns_rdatatype_rrsig)
|
||||
|
|
@ -7079,18 +7244,26 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
|
|||
if (!is_ksk && keyset_kskonly) {
|
||||
goto next_rdataset;
|
||||
}
|
||||
} else if (is_ksk) {
|
||||
} else if (!is_zsk) {
|
||||
goto next_rdataset;
|
||||
} else if (is_zsk && !dst_key_is_signing(key, DST_BOOL_ZSK,
|
||||
inception, &when)) {
|
||||
/* Only applies to dnssec-policy. */
|
||||
if (kasp != NULL) {
|
||||
goto next_rdataset;
|
||||
}
|
||||
}
|
||||
|
||||
if (seen_ns && !seen_soa &&
|
||||
rdataset.type != dns_rdatatype_ds &&
|
||||
rdataset.type != dns_rdatatype_nsec)
|
||||
{
|
||||
goto next_rdataset;
|
||||
}
|
||||
if (signed_with_key(db, node, version, rdataset.type, key)) {
|
||||
if (signed_with_good_key(zone, db, node, version, rdataset.type, key)) {
|
||||
goto next_rdataset;
|
||||
}
|
||||
|
||||
/* Calculate the signature, creating a RRSIG RDATA. */
|
||||
isc_buffer_clear(&buffer);
|
||||
CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
|
||||
|
|
@ -8680,13 +8853,14 @@ zone_sign(dns_zone_t *zone) {
|
|||
dns__zonediff_t zonediff;
|
||||
dns_fixedname_t fixed;
|
||||
dns_fixedname_t nextfixed;
|
||||
dns_kasp_t *kasp;
|
||||
dns_name_t *name, *nextname;
|
||||
dns_rdataset_t rdataset;
|
||||
dns_signing_t *signing, *nextsigning;
|
||||
dns_signinglist_t cleanup;
|
||||
dst_key_t *zone_keys[DNS_MAXZONEKEYS];
|
||||
int32_t signatures;
|
||||
bool check_ksk, keyset_kskonly, is_ksk;
|
||||
bool check_ksk, keyset_kskonly, is_ksk, is_zsk;
|
||||
bool with_ksk, with_zsk;
|
||||
bool commit = false;
|
||||
bool is_bottom_of_zone;
|
||||
|
|
@ -8747,6 +8921,8 @@ zone_sign(dns_zone_t *zone) {
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
kasp = dns_zone_getkasp(zone);
|
||||
|
||||
sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
|
||||
inception = now - 3600; /* Allow for clock skew. */
|
||||
soaexpire = now + sigvalidityinterval;
|
||||
|
|
@ -8783,8 +8959,10 @@ zone_sign(dns_zone_t *zone) {
|
|||
signing = ISC_LIST_HEAD(zone->signing);
|
||||
first = true;
|
||||
|
||||
check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
|
||||
keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
|
||||
check_ksk = (kasp != NULL) ? false :
|
||||
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
|
||||
keyset_kskonly = (kasp != NULL) ? true :
|
||||
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
|
||||
|
||||
/* Determine which type of chain to build */
|
||||
CHECK(dns_private_chains(db, version, zone->privatetype,
|
||||
|
|
@ -8802,7 +8980,7 @@ zone_sign(dns_zone_t *zone) {
|
|||
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||
if (signing->done || signing->db != zone->db) {
|
||||
/*
|
||||
* The zone has been reloaded. We will have
|
||||
* The zone has been reloaded. We will have to
|
||||
* created new signings as part of the reload
|
||||
* process so we can destroy this one.
|
||||
*/
|
||||
|
|
@ -8830,8 +9008,15 @@ zone_sign(dns_zone_t *zone) {
|
|||
if (ALG(zone_keys[i]) == signing->algorithm &&
|
||||
dst_key_id(zone_keys[i]) == signing->keyid)
|
||||
{
|
||||
if (KSK(zone_keys[i]))
|
||||
bool ksk = false;
|
||||
isc_result_t ret = dst_key_getbool(
|
||||
zone_keys[i], DST_BOOL_KSK, &ksk);
|
||||
if (ret != ISC_R_SUCCESS) {
|
||||
ksk = KSK(zone_keys[i]);
|
||||
}
|
||||
if (ksk) {
|
||||
dst_key_free(&zone_keys[i]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
zone_keys[j] = zone_keys[i];
|
||||
|
|
@ -8962,10 +9147,39 @@ zone_sign(dns_zone_t *zone) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (both || REVOKE(zone_keys[i])) {
|
||||
if (kasp != NULL) {
|
||||
/*
|
||||
* A dnssec-policy is found. Check what
|
||||
* RRsets this key can sign.
|
||||
*/
|
||||
isc_result_t kresult;
|
||||
is_ksk = false;
|
||||
kresult = dst_key_getbool(zone_keys[i],
|
||||
DST_BOOL_KSK,
|
||||
&is_ksk);
|
||||
if (kresult != ISC_R_SUCCESS) {
|
||||
if (KSK(zone_keys[i])) {
|
||||
is_ksk = true;
|
||||
}
|
||||
}
|
||||
|
||||
is_zsk = false;
|
||||
kresult = dst_key_getbool(zone_keys[i],
|
||||
DST_BOOL_ZSK,
|
||||
&is_zsk);
|
||||
if (kresult != ISC_R_SUCCESS) {
|
||||
if (!KSK(zone_keys[i])) {
|
||||
is_zsk = true;
|
||||
}
|
||||
}
|
||||
/* Treat as if we have both KSK and ZSK. */
|
||||
both = true;
|
||||
} else if (both || REVOKE(zone_keys[i])) {
|
||||
is_ksk = KSK(zone_keys[i]);
|
||||
is_zsk = !KSK(zone_keys[i]);
|
||||
} else {
|
||||
is_ksk = false;
|
||||
is_zsk = true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -8973,7 +9187,7 @@ zone_sign(dns_zone_t *zone) {
|
|||
* the RRset is still signed at least once by a
|
||||
* KSK and a ZSK.
|
||||
*/
|
||||
if (signing->deleteit && !is_ksk && with_zsk) {
|
||||
if (signing->deleteit && is_zsk && with_zsk) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -8984,7 +9198,7 @@ zone_sign(dns_zone_t *zone) {
|
|||
CHECK(sign_a_node(db, zone, name, node, version,
|
||||
build_nsec3, build_nsec,
|
||||
zone_keys[i], inception, expire,
|
||||
zone->minimum, is_ksk,
|
||||
zone->minimum, is_ksk, is_zsk,
|
||||
(both && keyset_kskonly),
|
||||
is_bottom_of_zone, zonediff.diff,
|
||||
&signatures, zone->mctx));
|
||||
|
|
@ -8995,10 +9209,10 @@ zone_sign(dns_zone_t *zone) {
|
|||
if (!signing->deleteit) {
|
||||
break;
|
||||
}
|
||||
if (!is_ksk) {
|
||||
if (is_zsk) {
|
||||
with_zsk = true;
|
||||
}
|
||||
if (KSK(zone_keys[i])) {
|
||||
if (is_ksk) {
|
||||
with_ksk = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -15317,8 +15531,14 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
|||
rdataset.type == dns_rdatatype_nsec3 ||
|
||||
rdataset.type == dns_rdatatype_dnskey ||
|
||||
rdataset.type == dns_rdatatype_nsec3param) {
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
continue;
|
||||
/*
|
||||
* Allow DNSSEC records with dnssec-policy.
|
||||
* WMM: Perhaps add config option for it.
|
||||
*/
|
||||
if (dns_zone_getkasp(zone) == NULL) {
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (rdataset.type == dns_rdatatype_soa &&
|
||||
have_oldserial) {
|
||||
|
|
@ -18150,6 +18370,57 @@ add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
|
|||
return (result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* See if dns__zone_updatesigs() will update signature for RRset 'rrtype' at
|
||||
* the apex, and if not tickle them and cause to sign so that newly activated
|
||||
* keys are used.
|
||||
*/
|
||||
static isc_result_t
|
||||
tickle_apex_rrset(dns_rdatatype_t rrtype, dns_zone_t *zone, dns_db_t *db,
|
||||
dns_dbversion_t *ver, isc_stdtime_t now, dns_diff_t *diff,
|
||||
dns__zonediff_t *zonediff, dst_key_t **keys,
|
||||
unsigned int nkeys, isc_stdtime_t inception,
|
||||
isc_stdtime_t keyexpire, bool check_ksk, bool keyset_kskonly)
|
||||
{
|
||||
dns_difftuple_t *tuple;
|
||||
isc_result_t result;
|
||||
|
||||
for (tuple = ISC_LIST_HEAD(diff->tuples);
|
||||
tuple != NULL;
|
||||
tuple = ISC_LIST_NEXT(tuple, link))
|
||||
{
|
||||
if (tuple->rdata.type == rrtype &&
|
||||
dns_name_equal(&tuple->name, &zone->origin))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tuple == NULL) {
|
||||
result = del_sigs(zone, db, ver, &zone->origin, rrtype,
|
||||
zonediff, keys, nkeys, now, false);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dnssec_log(zone, ISC_LOG_ERROR,
|
||||
"sign_apex:del_sigs -> %s",
|
||||
dns_result_totext(result));
|
||||
return (result);
|
||||
}
|
||||
result = add_sigs(db, ver, &zone->origin, zone, rrtype,
|
||||
zonediff->diff, keys, nkeys, zone->mctx,
|
||||
inception, keyexpire, check_ksk,
|
||||
keyset_kskonly);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dnssec_log(zone, ISC_LOG_ERROR,
|
||||
"sign_apex:add_sigs -> %s",
|
||||
dns_result_totext(result));
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
|
||||
isc_stdtime_t now, dns_diff_t *diff, dns__zonediff_t *zonediff)
|
||||
|
|
@ -18159,7 +18430,6 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
|
|||
bool check_ksk, keyset_kskonly;
|
||||
dst_key_t *zone_keys[DNS_MAXZONEKEYS];
|
||||
unsigned int nkeys = 0, i;
|
||||
dns_difftuple_t *tuple;
|
||||
|
||||
result = dns__zone_findkeys(zone, db, ver, now, zone->mctx,
|
||||
DNS_MAXZONEKEYS, zone_keys, &nkeys);
|
||||
|
|
@ -18184,40 +18454,27 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
|
|||
keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
|
||||
|
||||
/*
|
||||
* See if dns__zone_updatesigs() will update DNSKEY signature and if
|
||||
* not cause them to sign so that newly activated keys are used.
|
||||
* See if dns__zone_updatesigs() will update DNSKEY/CDS/CDNSKEY
|
||||
* signature and if not cause them to sign so that newly activated
|
||||
* keys are used.
|
||||
*/
|
||||
for (tuple = ISC_LIST_HEAD(diff->tuples);
|
||||
tuple != NULL;
|
||||
tuple = ISC_LIST_NEXT(tuple, link))
|
||||
{
|
||||
if (tuple->rdata.type == dns_rdatatype_dnskey &&
|
||||
dns_name_equal(&tuple->name, &zone->origin))
|
||||
{
|
||||
break;
|
||||
}
|
||||
result = tickle_apex_rrset(dns_rdatatype_dnskey, zone, db, ver, now,
|
||||
diff, zonediff, zone_keys, nkeys, inception,
|
||||
keyexpire, check_ksk, keyset_kskonly);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (tuple == NULL) {
|
||||
result = del_sigs(zone, db, ver, &zone->origin,
|
||||
dns_rdatatype_dnskey, zonediff,
|
||||
zone_keys, nkeys, now, false);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dnssec_log(zone, ISC_LOG_ERROR,
|
||||
"sign_apex:del_sigs -> %s",
|
||||
dns_result_totext(result));
|
||||
goto failure;
|
||||
}
|
||||
result = add_sigs(db, ver, &zone->origin, zone,
|
||||
dns_rdatatype_dnskey, zonediff->diff,
|
||||
zone_keys, nkeys, zone->mctx, inception,
|
||||
keyexpire, check_ksk, keyset_kskonly);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dnssec_log(zone, ISC_LOG_ERROR,
|
||||
"sign_apex:add_sigs -> %s",
|
||||
dns_result_totext(result));
|
||||
goto failure;
|
||||
}
|
||||
result = tickle_apex_rrset(dns_rdatatype_cds, zone, db, ver, now,
|
||||
diff, zonediff, zone_keys, nkeys, inception,
|
||||
keyexpire, check_ksk, keyset_kskonly);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
result = tickle_apex_rrset(dns_rdatatype_cdnskey, zone, db, ver, now,
|
||||
diff, zonediff, zone_keys, nkeys, inception,
|
||||
keyexpire, check_ksk, keyset_kskonly);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
result = dns__zone_updatesigs(diff, db, ver, zone_keys, nkeys, zone,
|
||||
|
|
@ -18394,6 +18651,7 @@ zone_rekey(dns_zone_t *zone) {
|
|||
dns_dnsseckeylist_t dnskeys, keys, rmkeys;
|
||||
dns_dnsseckey_t *key = NULL;
|
||||
dns_diff_t diff, _sig_diff;
|
||||
dns_kasp_t *kasp;
|
||||
dns__zonediff_t zonediff;
|
||||
bool commit = false, newactive = false;
|
||||
bool newalg = false;
|
||||
|
|
@ -18401,7 +18659,7 @@ zone_rekey(dns_zone_t *zone) {
|
|||
dns_ttl_t ttl = 3600;
|
||||
const char *dir = NULL;
|
||||
isc_mem_t *mctx = NULL;
|
||||
isc_stdtime_t now;
|
||||
isc_stdtime_t now, nexttime = 0;
|
||||
isc_time_t timenow;
|
||||
isc_interval_t ival;
|
||||
char timebuf[80];
|
||||
|
|
@ -18470,17 +18728,34 @@ zone_rekey(dns_zone_t *zone) {
|
|||
* True when called from "rndc sign". Indicates the zone should be
|
||||
* fully signed now.
|
||||
*/
|
||||
kasp = dns_zone_getkasp(zone);
|
||||
fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN);
|
||||
|
||||
result = dns_dnssec_findmatchingkeys(&zone->origin, dir, now, mctx,
|
||||
&keys);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dnssec_log(zone, ISC_LOG_DEBUG(1),
|
||||
"zone_rekey:dns_dnssec_findmatchingkeys failed: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
|
||||
if (kasp && (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND)) {
|
||||
ttl = dns_kasp_dnskeyttl(kasp);
|
||||
|
||||
result = dns_keymgr_run(&zone->origin, zone->rdclass, dir,
|
||||
mctx, &keys, kasp, now, &nexttime);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dnssec_log(zone, ISC_LOG_ERROR,
|
||||
"zone_rekey:dns_dnssec_keymgr failed: %s",
|
||||
isc_result_totext(result));
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
bool check_ksk;
|
||||
check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
|
||||
result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
|
||||
&zone->origin, ttl, &diff,
|
||||
!check_ksk, mctx,
|
||||
dnssec_report);
|
||||
mctx, dnssec_report);
|
||||
/*
|
||||
* Keys couldn't be updated for some reason;
|
||||
* try again later.
|
||||
|
|
@ -18531,7 +18806,7 @@ zone_rekey(dns_zone_t *zone) {
|
|||
/*
|
||||
* This isn't a new algorithm; clear
|
||||
* first_sign so we won't sign the
|
||||
* whole zone with this key later
|
||||
* whole zone with this key later.
|
||||
*/
|
||||
key->first_sign = false;
|
||||
} else {
|
||||
|
|
@ -18698,12 +18973,30 @@ zone_rekey(dns_zone_t *zone) {
|
|||
|
||||
isc_time_settoepoch(&zone->refreshkeytime);
|
||||
|
||||
/*
|
||||
* If keymgr provided a next time, use the calculated next rekey time.
|
||||
*/
|
||||
if (kasp != NULL && nexttime > 0) {
|
||||
isc_time_t timenext;
|
||||
|
||||
LOCK_ZONE(zone);
|
||||
DNS_ZONE_TIME_ADD(&timenow, nexttime - now, &timenext);
|
||||
zone->refreshkeytime = timenext;
|
||||
UNLOCK_ZONE(zone);
|
||||
|
||||
zone_settimer(zone, &timenow);
|
||||
isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
|
||||
dnssec_log(zone, ISC_LOG_DEBUG(3),
|
||||
"next key event in %u seconds: %s",
|
||||
(nexttime - now), timebuf);
|
||||
dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
|
||||
}
|
||||
/*
|
||||
* If we're doing key maintenance, set the key refresh timer to
|
||||
* the next scheduled key event or to 'dnssec-loadkeys-interval'
|
||||
* seconds in the future, whichever is sooner.
|
||||
*/
|
||||
if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
|
||||
else if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
|
||||
isc_time_t timethen;
|
||||
isc_stdtime_t then;
|
||||
|
||||
|
|
@ -19889,7 +20182,8 @@ dns_zone_setserial(dns_zone_t *zone, uint32_t serial) {
|
|||
LOCK_ZONE(zone);
|
||||
|
||||
if (!inline_secure(zone)) {
|
||||
if (!dns_zone_isdynamic(zone, true)) {
|
||||
if (!dns_zone_isdynamic(zone, true) &&
|
||||
dns_zone_getkasp(zone) == NULL) {
|
||||
result = DNS_R_NOTDYNAMIC;
|
||||
goto failure;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,11 +35,11 @@ SUBDIRS = include
|
|||
TESTDIRS = @UNITTESTS@
|
||||
|
||||
# Alphabetically
|
||||
OBJS = aclconf.@O@ dnsconf.@O@ log.@O@ namedconf.@O@ \
|
||||
OBJS = aclconf.@O@ dnsconf.@O@ kaspconf.@O@ log.@O@ namedconf.@O@ \
|
||||
parser.@O@ version.@O@
|
||||
|
||||
# Alphabetically
|
||||
SRCS = aclconf.c dnsconf.c log.c namedconf.c \
|
||||
SRCS = aclconf.c dnsconf.c kaspconf.c log.c namedconf.c \
|
||||
parser.c version.c
|
||||
|
||||
TARGETS = timestamp
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <isc/formatcheck.h>
|
||||
#include <isc/lang.h>
|
||||
|
|
@ -331,6 +332,24 @@ cfg_obj_aspercentage(const cfg_obj_t *obj);
|
|||
* \li A 32-bit unsigned integer.
|
||||
*/
|
||||
|
||||
bool
|
||||
cfg_obj_isduration(const cfg_obj_t *obj);
|
||||
/*%<
|
||||
* Return true iff 'obj' is of duration type.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
cfg_obj_asduration(const cfg_obj_t *obj);
|
||||
/*%<
|
||||
* Returns the value of a configuration object of duration
|
||||
*
|
||||
* Requires:
|
||||
* \li 'obj' points to a valid configuration object of duration type.
|
||||
*
|
||||
* Returns:
|
||||
* \li A duration in seconds.
|
||||
*/
|
||||
|
||||
bool
|
||||
cfg_obj_isstring(const cfg_obj_t *obj);
|
||||
/*%<
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ typedef struct cfg_printer cfg_printer_t;
|
|||
typedef ISC_LIST(cfg_listelt_t) cfg_list_t;
|
||||
typedef struct cfg_map cfg_map_t;
|
||||
typedef struct cfg_rep cfg_rep_t;
|
||||
typedef struct cfg_duration cfg_duration_t;
|
||||
|
||||
#define CFG_DURATION_MAXLEN 64
|
||||
|
||||
/*
|
||||
* Function types for configuration object methods
|
||||
|
|
@ -154,6 +157,24 @@ struct cfg_netprefix {
|
|||
unsigned int prefixlen;
|
||||
};
|
||||
|
||||
/*%
|
||||
* A configuration object to store ISO 8601 durations.
|
||||
*/
|
||||
struct cfg_duration {
|
||||
/*
|
||||
* The duration is stored in multiple parts:
|
||||
* [0] Years
|
||||
* [1] Months
|
||||
* [2] Weeks
|
||||
* [3] Days
|
||||
* [4] Hours
|
||||
* [5] Minutes
|
||||
* [6] Seconds
|
||||
*/
|
||||
uint32_t parts[7];
|
||||
bool iso8601;
|
||||
};
|
||||
|
||||
/*%
|
||||
* A configuration data representation.
|
||||
*/
|
||||
|
|
@ -183,6 +204,7 @@ struct cfg_obj {
|
|||
isc_dscp_t dscp;
|
||||
} sockaddrdscp;
|
||||
cfg_netprefix_t netprefix;
|
||||
cfg_duration_t duration;
|
||||
} value;
|
||||
isc_refcount_t references; /*%< reference counter */
|
||||
const char * file;
|
||||
|
|
@ -290,6 +312,7 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_netprefix;
|
|||
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_void;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_fixedpoint;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_percentage;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_duration;
|
||||
/*@}*/
|
||||
|
||||
/*@{*/
|
||||
|
|
@ -320,6 +343,7 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token;
|
|||
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_unsupported;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_fixedpoint;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_percentage;
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_duration;
|
||||
/*@}*/
|
||||
|
||||
isc_result_t
|
||||
|
|
@ -504,6 +528,13 @@ cfg_parse_percentage(cfg_parser_t *pctx, const cfg_type_t *type,
|
|||
void
|
||||
cfg_print_percentage(cfg_printer_t *pctx, const cfg_obj_t *obj);
|
||||
|
||||
isc_result_t
|
||||
cfg_parse_duration(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
cfg_obj_t **ret);
|
||||
|
||||
void
|
||||
cfg_print_duration(cfg_printer_t *pctx, const cfg_obj_t *obj);
|
||||
|
||||
isc_result_t
|
||||
cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
|
||||
|
||||
|
|
|
|||
56
lib/isccfg/include/isccfg/kaspconf.h
Normal file
56
lib/isccfg/include/isccfg/kaspconf.h
Normal 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ISCCFG_KASPCONF_H
|
||||
#define ISCCFG_KASPCONF_H 1
|
||||
|
||||
#include <isc/lang.h>
|
||||
|
||||
#include <isccfg/cfg.h>
|
||||
|
||||
#include <dns/types.h>
|
||||
|
||||
/***
|
||||
*** Functions
|
||||
***/
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
isc_result_t
|
||||
cfg_kasp_fromconfig(const cfg_obj_t *config, isc_mem_t* mctx,
|
||||
dns_kasplist_t *kasplist, dns_kasp_t **kaspp);
|
||||
/*%<
|
||||
* Create and configure a KASP. If 'config' is NULL, the default configuration
|
||||
* is used. If a 'kasplist' is provided, a lookup happens and if a KASP
|
||||
* already exists with the same name, no new KASP is created, and no attach to
|
||||
* 'kaspp' happens.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'mctx' is a valid memory context.
|
||||
*
|
||||
*\li 'name' is a valid C string.
|
||||
*
|
||||
*\li kaspp != NULL && *kaspp == NULL
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS If creating and configuring the KASP succeeds.
|
||||
*\li #ISC_R_EXISTS If 'kasplist' already has a kasp structure with 'name'.
|
||||
*\li #ISC_R_NOMEMORY
|
||||
*
|
||||
*\li Other errors are possible.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* ISCCFG_KASPCONF_H */
|
||||
|
|
@ -49,4 +49,7 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_keyref;
|
|||
/*%< Zone options */
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_zoneopts;
|
||||
|
||||
/*%< DNSSEC Key and Signing Policy options */
|
||||
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_dnssecpolicyopts;
|
||||
|
||||
#endif /* ISCCFG_NAMEDCONF_H */
|
||||
|
|
|
|||
226
lib/isccfg/kaspconf.c
Normal file
226
lib/isccfg/kaspconf.c
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <isc/mem.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <isccfg/namedconf.h>
|
||||
#include <isccfg/cfg.h>
|
||||
#include <isccfg/kaspconf.h>
|
||||
|
||||
#include <dns/kasp.h>
|
||||
#include <dns/keyvalues.h>
|
||||
#include <dns/log.h>
|
||||
|
||||
|
||||
/*
|
||||
* Utility function for getting a configuration option.
|
||||
*/
|
||||
static isc_result_t
|
||||
confget(cfg_obj_t const * const *maps, const char *name, const cfg_obj_t **obj)
|
||||
{
|
||||
for (size_t i = 0;; i++) {
|
||||
if (maps[i] == NULL) {
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function for configuring durations.
|
||||
*/
|
||||
static uint32_t
|
||||
get_duration(const cfg_obj_t **maps, const char* option, uint32_t dfl)
|
||||
{
|
||||
const cfg_obj_t *obj;
|
||||
isc_result_t result;
|
||||
obj = NULL;
|
||||
|
||||
result = confget(maps, option, &obj);
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
return (dfl);
|
||||
}
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
return (cfg_obj_asduration(obj));
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new kasp key derived from configuration.
|
||||
*/
|
||||
static isc_result_t
|
||||
cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_kasp_key_t *key = NULL;
|
||||
|
||||
/* Create a new key reference. */
|
||||
result = dns_kasp_key_create(kasp, &key);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
if (config == NULL) {
|
||||
/* We are creating a key reference for the default kasp. */
|
||||
key->role |= DNS_KASP_KEY_ROLE_KSK | DNS_KASP_KEY_ROLE_ZSK;
|
||||
key->lifetime = 0;
|
||||
key->algorithm = DNS_KEYALG_ECDSA256;
|
||||
key->length = -1;
|
||||
} else {
|
||||
const char* rolestr;
|
||||
const cfg_obj_t* obj;
|
||||
|
||||
rolestr = cfg_obj_asstring(cfg_tuple_get(config, "role"));
|
||||
if (strcmp(rolestr, "ksk") == 0) {
|
||||
key->role |= DNS_KASP_KEY_ROLE_KSK;
|
||||
} else if (strcmp(rolestr, "zsk") == 0) {
|
||||
key->role |= DNS_KASP_KEY_ROLE_ZSK;
|
||||
} else if (strcmp(rolestr, "csk") == 0) {
|
||||
key->role |= DNS_KASP_KEY_ROLE_KSK;
|
||||
key->role |= DNS_KASP_KEY_ROLE_ZSK;
|
||||
}
|
||||
key->lifetime = cfg_obj_asduration(
|
||||
cfg_tuple_get(config, "lifetime"));
|
||||
key->algorithm = cfg_obj_asuint32(
|
||||
cfg_tuple_get(config, "algorithm"));
|
||||
obj = cfg_tuple_get(config, "length");
|
||||
if (cfg_obj_isuint32(obj)) {
|
||||
key->length = cfg_obj_asuint32(obj);
|
||||
}
|
||||
}
|
||||
dns_kasp_addkey(kasp, key);
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
cfg_kasp_fromconfig(const cfg_obj_t *config, isc_mem_t* mctx,
|
||||
dns_kasplist_t *kasplist, dns_kasp_t **kaspp)
|
||||
{
|
||||
isc_result_t result;
|
||||
const cfg_obj_t *maps[2];
|
||||
const cfg_obj_t *koptions = NULL;
|
||||
const cfg_obj_t *keys = NULL;
|
||||
const cfg_listelt_t *element = NULL;
|
||||
const char *kaspname = NULL;
|
||||
dns_kasp_t *kasp = NULL;
|
||||
int i = 0;
|
||||
|
||||
REQUIRE(kaspp != NULL && *kaspp == NULL);
|
||||
|
||||
kaspname = (config != NULL) ?
|
||||
cfg_obj_asstring(cfg_tuple_get(config, "name")) :
|
||||
"default";
|
||||
|
||||
REQUIRE(strcmp(kaspname, "none") != 0);
|
||||
|
||||
result = dns_kasplist_find(kasplist, kaspname, &kasp);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
return (ISC_R_EXISTS);
|
||||
}
|
||||
if (result != ISC_R_NOTFOUND) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* No kasp with configured name was found in list, create new one. */
|
||||
INSIST(kasp == NULL);
|
||||
result = dns_kasp_create(mctx, kaspname, &kasp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
INSIST(kasp != NULL);
|
||||
|
||||
/* Now configure. */
|
||||
INSIST(DNS_KASP_VALID(kasp));
|
||||
|
||||
if (config != NULL) {
|
||||
koptions = cfg_tuple_get(config, "options");
|
||||
maps[i++] = koptions;
|
||||
}
|
||||
maps[i] = NULL;
|
||||
|
||||
/* Configuration: Signatures */
|
||||
dns_kasp_setsigrefresh(kasp, get_duration(maps, "signatures-refresh",
|
||||
DNS_KASP_SIG_REFRESH));
|
||||
dns_kasp_setsigvalidity(kasp, get_duration(maps, "signatures-validity",
|
||||
DNS_KASP_SIG_VALIDITY));
|
||||
dns_kasp_setsigvalidity_dnskey(kasp, get_duration(maps,
|
||||
"signatures-validity-dnskey",
|
||||
DNS_KASP_SIG_VALIDITY_DNSKEY));
|
||||
|
||||
/* Configuration: Keys */
|
||||
dns_kasp_setdnskeyttl(kasp, get_duration(maps, "dnskey-ttl",
|
||||
DNS_KASP_KEY_TTL));
|
||||
dns_kasp_setpublishsafety(kasp, get_duration(maps, "publish-safety",
|
||||
DNS_KASP_PUBLISH_SAFETY));
|
||||
dns_kasp_setretiresafety(kasp, get_duration(maps, "retire-safety",
|
||||
DNS_KASP_RETIRE_SAFETY));
|
||||
|
||||
(void)confget(maps, "keys", &keys);
|
||||
if (keys == NULL) {
|
||||
result = cfg_kaspkey_fromconfig(NULL, kasp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
for (element = cfg_list_first(keys); element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
cfg_obj_t *kobj = cfg_listelt_value(element);
|
||||
result = cfg_kaspkey_fromconfig(kobj, kasp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
ISC_INSIST(!(dns_kasp_keylist_empty(kasp)));
|
||||
|
||||
/* Configuration: Zone settings */
|
||||
dns_kasp_setzonemaxttl(kasp, get_duration(maps, "zone-max-ttl",
|
||||
DNS_KASP_ZONE_MAXTTL));
|
||||
dns_kasp_setzonepropagationdelay(kasp, get_duration(maps,
|
||||
"zone-propagation-delay",
|
||||
DNS_KASP_ZONE_PROPDELAY));
|
||||
|
||||
/* Configuration: Parent settings */
|
||||
dns_kasp_setdsttl(kasp, get_duration(maps, "parent-ds-ttl",
|
||||
DNS_KASP_DS_TTL));
|
||||
dns_kasp_setparentpropagationdelay(kasp, get_duration(maps,
|
||||
"parent-propagation-delay",
|
||||
DNS_KASP_PARENT_PROPDELAY));
|
||||
dns_kasp_setparentregistrationdelay(kasp, get_duration(maps,
|
||||
"parent-registration-delay",
|
||||
DNS_KASP_PARENT_REGDELAY));
|
||||
|
||||
// TODO: Rest of the configuration
|
||||
|
||||
/* Append it to the list for future lookups. */
|
||||
ISC_LIST_APPEND(*kasplist, kasp, link);
|
||||
ISC_INSIST(!(ISC_LIST_EMPTY(*kasplist)));
|
||||
|
||||
/* Success: Attach the kasp to the pointer and return. */
|
||||
dns_kasp_attach(kasp, kaspp);
|
||||
/* Don't detach as kasp is on '*kasplist' */
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
|
||||
/* Something bad happened, detach (destroys kasp) and return error. */
|
||||
dns_kasp_detach(&kasp);
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <isc/lex.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/util.h>
|
||||
|
|
@ -82,6 +83,7 @@ static cfg_type_t cfg_type_controls_sockaddr;
|
|||
static cfg_type_t cfg_type_destinationlist;
|
||||
static cfg_type_t cfg_type_dialuptype;
|
||||
static cfg_type_t cfg_type_dlz;
|
||||
static cfg_type_t cfg_type_dnssecpolicy;
|
||||
static cfg_type_t cfg_type_dnstap;
|
||||
static cfg_type_t cfg_type_dnstapoutput;
|
||||
static cfg_type_t cfg_type_dyndb;
|
||||
|
|
@ -121,7 +123,6 @@ static cfg_type_t cfg_type_sizeval;
|
|||
static cfg_type_t cfg_type_sockaddr4wild;
|
||||
static cfg_type_t cfg_type_sockaddr6wild;
|
||||
static cfg_type_t cfg_type_statschannels;
|
||||
static cfg_type_t cfg_type_ttlval;
|
||||
static cfg_type_t cfg_type_view;
|
||||
static cfg_type_t cfg_type_viewopts;
|
||||
static cfg_type_t cfg_type_zone;
|
||||
|
|
@ -411,6 +412,20 @@ static cfg_type_t cfg_type_zone = {
|
|||
&cfg_rep_tuple, zone_fields
|
||||
};
|
||||
|
||||
/*%
|
||||
* A dnssec-policy statement.
|
||||
*/
|
||||
static cfg_tuplefielddef_t dnssecpolicy_fields[] = {
|
||||
{ "name", &cfg_type_astring, 0 },
|
||||
{ "options", &cfg_type_dnssecpolicyopts, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
static cfg_type_t cfg_type_dnssecpolicy = {
|
||||
"dnssec-policy", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
|
||||
&cfg_rep_tuple, dnssecpolicy_fields
|
||||
};
|
||||
|
||||
/*%
|
||||
* A "category" clause in the "logging" statement.
|
||||
*/
|
||||
|
|
@ -466,6 +481,55 @@ static cfg_type_t cfg_type_managedkey = {
|
|||
&cfg_rep_tuple, managedkey_fields
|
||||
};
|
||||
|
||||
/*%
|
||||
* DNSSEC key roles.
|
||||
*/
|
||||
static const char *dnsseckeyrole_enums[] = { "csk", "ksk", "zsk", NULL };
|
||||
static cfg_type_t cfg_type_dnsseckeyrole = {
|
||||
"dnssec-key-role", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
|
||||
&cfg_rep_string, &dnsseckeyrole_enums
|
||||
};
|
||||
|
||||
/*%
|
||||
* DNSSEC key storage types.
|
||||
*/
|
||||
static const char *dnsseckeystore_enums[] = { "key-directory", NULL };
|
||||
static cfg_type_t cfg_type_dnsseckeystore = {
|
||||
"dnssec-key-storage", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
|
||||
&cfg_rep_string, &dnsseckeystore_enums
|
||||
};
|
||||
|
||||
/*%
|
||||
* A dnssec key, as used in the "keys" statement in a "dnssec-policy".
|
||||
*/
|
||||
static keyword_type_t algorithm_kw = { "algorithm", &cfg_type_uint32 };
|
||||
static cfg_type_t cfg_type_algorithm = {
|
||||
"algorithm", parse_keyvalue, print_keyvalue,
|
||||
doc_keyvalue, &cfg_rep_uint32, &algorithm_kw
|
||||
};
|
||||
|
||||
static keyword_type_t lifetime_kw = { "lifetime", &cfg_type_duration };
|
||||
static cfg_type_t cfg_type_lifetime = {
|
||||
"lifetime", parse_keyvalue, print_keyvalue,
|
||||
doc_keyvalue, &cfg_rep_duration, &lifetime_kw
|
||||
};
|
||||
|
||||
static cfg_tuplefielddef_t kaspkey_fields[] = {
|
||||
{ "role", &cfg_type_dnsseckeyrole, 0 },
|
||||
{ "keystore-type", &cfg_type_dnsseckeystore, 0 },
|
||||
{ "lifetime", &cfg_type_lifetime, 0 },
|
||||
{ "algorithm", &cfg_type_algorithm, 0 },
|
||||
{ "length", &cfg_type_optional_uint32, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
static cfg_type_t cfg_type_kaspkey = {
|
||||
"kaspkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple,
|
||||
&cfg_rep_tuple, kaspkey_fields
|
||||
};
|
||||
|
||||
/*%
|
||||
* Wild class, type, name.
|
||||
*/
|
||||
static keyword_type_t wild_class_kw = { "class", &cfg_type_ustring };
|
||||
|
||||
static cfg_type_t cfg_type_optional_wild_class = {
|
||||
|
|
@ -638,6 +702,14 @@ static cfg_type_t cfg_type_dnsseckeys = {
|
|||
cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_managedkey
|
||||
};
|
||||
|
||||
/*%
|
||||
* A list of key entries, used in a DNSSEC Key and Signing Policy.
|
||||
*/
|
||||
static cfg_type_t cfg_type_kaspkeys = {
|
||||
"kaspkeys", cfg_parse_bracketed_list, cfg_print_bracketed_list,
|
||||
cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_kaspkey
|
||||
};
|
||||
|
||||
static const char *forwardtype_enums[] = { "first", "only", NULL };
|
||||
static cfg_type_t cfg_type_forwardtype = {
|
||||
"forwardtype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
|
||||
|
|
@ -963,6 +1035,7 @@ static cfg_clausedef_t
|
|||
namedconf_clauses[] = {
|
||||
{ "acl", &cfg_type_acl, CFG_CLAUSEFLAG_MULTI },
|
||||
{ "controls", &cfg_type_controls, CFG_CLAUSEFLAG_MULTI },
|
||||
{ "dnssec-policy", &cfg_type_dnssecpolicy, CFG_CLAUSEFLAG_MULTI },
|
||||
{ "logging", &cfg_type_logging, 0 },
|
||||
{ "lwres", &cfg_type_bracketed_text,
|
||||
CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_OBSOLETE },
|
||||
|
|
@ -1054,7 +1127,7 @@ options_clauses[] = {
|
|||
{ "fstrm-set-output-notify-threshold", &cfg_type_uint32, 0 },
|
||||
{ "fstrm-set-output-queue-model", &cfg_type_fstrm_model, 0 },
|
||||
{ "fstrm-set-output-queue-size", &cfg_type_uint32, 0 },
|
||||
{ "fstrm-set-reopen-interval", &cfg_type_ttlval, 0 },
|
||||
{ "fstrm-set-reopen-interval", &cfg_type_duration, 0 },
|
||||
#else
|
||||
{ "fstrm-set-buffer-hint", &cfg_type_uint32,
|
||||
CFG_CLAUSEFLAG_NOTCONFIGURED },
|
||||
|
|
@ -1068,7 +1141,7 @@ options_clauses[] = {
|
|||
CFG_CLAUSEFLAG_NOTCONFIGURED },
|
||||
{ "fstrm-set-output-queue-size", &cfg_type_uint32,
|
||||
CFG_CLAUSEFLAG_NOTCONFIGURED },
|
||||
{ "fstrm-set-reopen-interval", &cfg_type_ttlval,
|
||||
{ "fstrm-set-reopen-interval", &cfg_type_duration,
|
||||
CFG_CLAUSEFLAG_NOTCONFIGURED },
|
||||
#endif /* HAVE_DNSTAP */
|
||||
#if defined(HAVE_GEOIP2)
|
||||
|
|
@ -1083,7 +1156,7 @@ options_clauses[] = {
|
|||
{ "host-statistics", &cfg_type_boolean, CFG_CLAUSEFLAG_ANCIENT },
|
||||
{ "host-statistics-max", &cfg_type_uint32, CFG_CLAUSEFLAG_ANCIENT },
|
||||
{ "hostname", &cfg_type_qstringornone, 0 },
|
||||
{ "interface-interval", &cfg_type_ttlval, 0 },
|
||||
{ "interface-interval", &cfg_type_duration, 0 },
|
||||
{ "keep-response-order", &cfg_type_bracketed_aml, 0 },
|
||||
{ "listen-on", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
|
||||
{ "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
|
||||
|
|
@ -1611,8 +1684,8 @@ static cfg_tuplefielddef_t rpz_zone_fields[] = {
|
|||
{ "zone name", &cfg_type_rpz_zone, 0 },
|
||||
{ "add-soa", &cfg_type_boolean, 0 },
|
||||
{ "log", &cfg_type_boolean, 0 },
|
||||
{ "max-policy-ttl", &cfg_type_ttlval, 0 },
|
||||
{ "min-update-interval", &cfg_type_ttlval, 0 },
|
||||
{ "max-policy-ttl", &cfg_type_duration, 0 },
|
||||
{ "min-update-interval", &cfg_type_duration, 0 },
|
||||
{ "policy", &cfg_type_rpz_policy, 0 },
|
||||
{ "recursive-only", &cfg_type_boolean, 0 },
|
||||
{ "nsip-enable", &cfg_type_boolean, 0 },
|
||||
|
|
@ -1633,8 +1706,8 @@ static cfg_tuplefielddef_t rpz_fields[] = {
|
|||
{ "zone list", &cfg_type_rpz_list, 0 },
|
||||
{ "add-soa", &cfg_type_boolean, 0 },
|
||||
{ "break-dnssec", &cfg_type_boolean, 0 },
|
||||
{ "max-policy-ttl", &cfg_type_ttlval, 0 },
|
||||
{ "min-update-interval", &cfg_type_ttlval, 0 },
|
||||
{ "max-policy-ttl", &cfg_type_duration, 0 },
|
||||
{ "min-update-interval", &cfg_type_duration, 0 },
|
||||
{ "min-ns-dots", &cfg_type_uint32, 0 },
|
||||
{ "nsip-wait-recurse", &cfg_type_boolean, 0 },
|
||||
{ "qname-wait-recurse", &cfg_type_boolean, 0 },
|
||||
|
|
@ -1671,7 +1744,7 @@ static cfg_tuplefielddef_t catz_zone_fields[] = {
|
|||
{ "default-masters", &cfg_type_namesockaddrkeylist, 0 },
|
||||
{ "zone-directory", &cfg_type_qstring, 0 },
|
||||
{ "in-memory", &cfg_type_boolean, 0 },
|
||||
{ "min-update-interval", &cfg_type_ttlval, 0 },
|
||||
{ "min-update-interval", &cfg_type_duration, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
static cfg_type_t cfg_type_catz_tuple = {
|
||||
|
|
@ -1899,7 +1972,7 @@ view_clauses[] = {
|
|||
{ "filter-aaaa-on-v6", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
|
||||
{ "glue-cache", &cfg_type_boolean, 0 },
|
||||
{ "ixfr-from-differences", &cfg_type_ixfrdifftype, 0 },
|
||||
{ "lame-ttl", &cfg_type_ttlval, 0 },
|
||||
{ "lame-ttl", &cfg_type_duration, 0 },
|
||||
#ifdef HAVE_LMDB
|
||||
{ "lmdb-mapsize", &cfg_type_sizeval, 0 },
|
||||
#else
|
||||
|
|
@ -1907,16 +1980,16 @@ view_clauses[] = {
|
|||
#endif
|
||||
{ "max-acache-size", &cfg_type_sizenodefault, CFG_CLAUSEFLAG_OBSOLETE },
|
||||
{ "max-cache-size", &cfg_type_sizeorpercent, 0 },
|
||||
{ "max-cache-ttl", &cfg_type_ttlval, 0 },
|
||||
{ "max-cache-ttl", &cfg_type_duration, 0 },
|
||||
{ "max-clients-per-query", &cfg_type_uint32, 0 },
|
||||
{ "max-ncache-ttl", &cfg_type_ttlval, 0 },
|
||||
{ "max-ncache-ttl", &cfg_type_duration, 0 },
|
||||
{ "max-recursion-depth", &cfg_type_uint32, 0 },
|
||||
{ "max-recursion-queries", &cfg_type_uint32, 0 },
|
||||
{ "max-stale-ttl", &cfg_type_ttlval, 0 },
|
||||
{ "max-stale-ttl", &cfg_type_duration, 0 },
|
||||
{ "max-udp-size", &cfg_type_uint32, 0 },
|
||||
{ "message-compression", &cfg_type_boolean, 0 },
|
||||
{ "min-cache-ttl", &cfg_type_ttlval, 0 },
|
||||
{ "min-ncache-ttl", &cfg_type_ttlval, 0 },
|
||||
{ "min-cache-ttl", &cfg_type_duration, 0 },
|
||||
{ "min-ncache-ttl", &cfg_type_duration, 0 },
|
||||
{ "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_ANCIENT },
|
||||
{ "minimal-any", &cfg_type_boolean, 0 },
|
||||
{ "minimal-responses", &cfg_type_minimal, 0 },
|
||||
|
|
@ -1924,8 +1997,8 @@ view_clauses[] = {
|
|||
{ "no-case-compress", &cfg_type_bracketed_aml, 0 },
|
||||
{ "nocookie-udp-size", &cfg_type_uint32, 0 },
|
||||
{ "nosit-udp-size", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE },
|
||||
{ "nta-lifetime", &cfg_type_ttlval, 0 },
|
||||
{ "nta-recheck", &cfg_type_ttlval, 0 },
|
||||
{ "nta-lifetime", &cfg_type_duration, 0 },
|
||||
{ "nta-recheck", &cfg_type_duration, 0 },
|
||||
{ "nxdomain-redirect", &cfg_type_astring, 0 },
|
||||
{ "preferred-glue", &cfg_type_astring, 0 },
|
||||
{ "prefetch", &cfg_type_prefetch, 0 },
|
||||
|
|
@ -1955,10 +2028,10 @@ view_clauses[] = {
|
|||
{ "root-key-sentinel", &cfg_type_boolean, 0 },
|
||||
{ "rrset-order", &cfg_type_rrsetorder, 0 },
|
||||
{ "send-cookie", &cfg_type_boolean, 0 },
|
||||
{ "servfail-ttl", &cfg_type_ttlval, 0 },
|
||||
{ "servfail-ttl", &cfg_type_duration, 0 },
|
||||
{ "sortlist", &cfg_type_bracketed_aml, 0 },
|
||||
{ "stale-answer-enable", &cfg_type_boolean, 0 },
|
||||
{ "stale-answer-ttl", &cfg_type_ttlval, 0 },
|
||||
{ "stale-answer-ttl", &cfg_type_duration, 0 },
|
||||
{ "suppress-initial-notify", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI },
|
||||
{ "synth-from-dnssec", &cfg_type_boolean, 0 },
|
||||
{ "topology", &cfg_type_bracketed_aml, CFG_CLAUSEFLAG_ANCIENT },
|
||||
|
|
@ -1998,6 +2071,26 @@ static cfg_type_t cfg_type_validityinterval = {
|
|||
&cfg_rep_tuple, validityinterval_fields
|
||||
};
|
||||
|
||||
/*%
|
||||
* Clauses that can be found in a 'dnssec-policy' statement.
|
||||
*/
|
||||
static cfg_clausedef_t
|
||||
dnssecpolicy_clauses[] = {
|
||||
{ "dnskey-ttl", &cfg_type_duration, 0 },
|
||||
{ "keys", &cfg_type_kaspkeys, 0 },
|
||||
{ "publish-safety", &cfg_type_duration, 0 },
|
||||
{ "retire-safety", &cfg_type_duration, 0 },
|
||||
{ "signatures-refresh", &cfg_type_duration, 0 },
|
||||
{ "signatures-validity", &cfg_type_duration, 0 },
|
||||
{ "signatures-validity-dnskey", &cfg_type_duration, 0 },
|
||||
{ "zone-max-ttl", &cfg_type_duration, 0 },
|
||||
{ "zone-propagation-delay", &cfg_type_duration, 0 },
|
||||
{ "parent-ds-ttl", &cfg_type_duration, 0 },
|
||||
{ "parent-propagation-delay", &cfg_type_duration, 0 },
|
||||
{ "parent-registration-delay", &cfg_type_duration, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
/*%
|
||||
* Clauses that can be found in a 'zone' statement,
|
||||
* with defaults in the 'view' or 'options' statement.
|
||||
|
|
@ -2072,6 +2165,9 @@ zone_clauses[] = {
|
|||
{ "dnssec-loadkeys-interval", &cfg_type_uint32,
|
||||
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
|
||||
},
|
||||
{ "dnssec-policy", &cfg_type_astring,
|
||||
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
|
||||
},
|
||||
{ "dnssec-secure-to-insecure", &cfg_type_boolean,
|
||||
CFG_ZONE_MASTER
|
||||
},
|
||||
|
|
@ -2346,6 +2442,16 @@ LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_zoneopts = {
|
|||
"zoneopts", cfg_parse_map, cfg_print_map,
|
||||
cfg_doc_map, &cfg_rep_map, zone_clausesets };
|
||||
|
||||
/*% The "dnssec-policy" statement syntax. */
|
||||
static cfg_clausedef_t *
|
||||
dnssecpolicy_clausesets[] = {
|
||||
dnssecpolicy_clauses,
|
||||
NULL
|
||||
};
|
||||
LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_dnssecpolicyopts = {
|
||||
"dnssecpolicyopts", cfg_parse_map, cfg_print_map,
|
||||
cfg_doc_map, &cfg_rep_map, dnssecpolicy_clausesets };
|
||||
|
||||
/*% The "dynamically loadable zones" statement syntax. */
|
||||
|
||||
static cfg_clausedef_t
|
||||
|
|
@ -3761,54 +3867,14 @@ static cfg_type_t cfg_type_masterselement = {
|
|||
doc_masterselement, NULL, NULL
|
||||
};
|
||||
|
||||
static isc_result_t
|
||||
parse_ttlval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
isc_result_t result;
|
||||
cfg_obj_t *obj = NULL;
|
||||
uint32_t ttl;
|
||||
|
||||
UNUSED(type);
|
||||
|
||||
CHECK(cfg_gettoken(pctx, 0));
|
||||
if (pctx->token.type != isc_tokentype_string) {
|
||||
result = ISC_R_UNEXPECTEDTOKEN;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = dns_ttl_fromtext(&pctx->token.value.as_textregion, &ttl);
|
||||
if (result == ISC_R_RANGE ) {
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR, "TTL out of range ");
|
||||
return (result);
|
||||
} else if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
CHECK(cfg_create_obj(pctx, &cfg_type_uint32, &obj));
|
||||
obj->value.uint32 = ttl;
|
||||
*ret = obj;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR,
|
||||
"expected integer and optional unit");
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*%
|
||||
* A TTL value (number + optional unit).
|
||||
*/
|
||||
static cfg_type_t cfg_type_ttlval = {
|
||||
"ttlval", parse_ttlval, cfg_print_uint64, cfg_doc_terminal,
|
||||
&cfg_rep_uint64, NULL
|
||||
};
|
||||
|
||||
static isc_result_t
|
||||
parse_maxttl(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
return (cfg_parse_enum_or_other(pctx, type, &cfg_type_ttlval, ret));
|
||||
return (cfg_parse_enum_or_other(pctx, type, &cfg_type_duration, ret));
|
||||
}
|
||||
|
||||
static void
|
||||
doc_maxttl(cfg_printer_t *pctx, const cfg_type_t *type) {
|
||||
cfg_doc_enum_or_other(pctx, type, &cfg_type_ttlval);
|
||||
cfg_doc_enum_or_other(pctx, type, &cfg_type_duration);
|
||||
}
|
||||
|
||||
/*%
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
#include <isccfg/grammar.h>
|
||||
#include <isccfg/log.h>
|
||||
|
||||
#include <dns/ttl.h>
|
||||
|
||||
/* Shorthand */
|
||||
#define CAT CFG_LOGCATEGORY_CONFIG
|
||||
#define MOD CFG_LOGMODULE_PARSER
|
||||
|
|
@ -132,6 +134,7 @@ LIBISCCFG_EXTERNAL_DATA cfg_rep_t cfg_rep_fixedpoint =
|
|||
{ "fixedpoint", free_noop };
|
||||
LIBISCCFG_EXTERNAL_DATA cfg_rep_t cfg_rep_percentage =
|
||||
{ "percentage", free_noop };
|
||||
LIBISCCFG_EXTERNAL_DATA cfg_rep_t cfg_rep_duration = { "duration", free_noop };
|
||||
|
||||
/*
|
||||
* Configuration type definitions.
|
||||
|
|
@ -977,9 +980,353 @@ LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_uint64 = {
|
|||
&cfg_rep_uint64, NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Get the number of digits in a number.
|
||||
*/
|
||||
static size_t
|
||||
numlen(uint32_t num) {
|
||||
uint32_t period = num;
|
||||
size_t count = 0;
|
||||
|
||||
if (period == 0) {
|
||||
return 1;
|
||||
}
|
||||
while (period > 0) {
|
||||
count++;
|
||||
period /= 10;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
/*
|
||||
* duration
|
||||
*/
|
||||
void
|
||||
cfg_print_duration(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
||||
char buf[CFG_DURATION_MAXLEN];
|
||||
char *str;
|
||||
const char *indicators = "YMWDHMS";
|
||||
int count, i;
|
||||
int durationlen[7];
|
||||
cfg_duration_t duration;
|
||||
/*
|
||||
* D ? The duration has a date part.
|
||||
* T ? The duration has a time part.
|
||||
*/
|
||||
bool D = false, T = false;
|
||||
|
||||
REQUIRE(pctx != NULL);
|
||||
REQUIRE(obj != NULL);
|
||||
|
||||
duration = obj->value.duration;
|
||||
|
||||
/* If this is not an ISO 8601 duration, just print it as a number. */
|
||||
if (!duration.iso8601) {
|
||||
return (cfg_print_rawuint(pctx, duration.parts[6]));
|
||||
}
|
||||
|
||||
/* Calculate length of string. */
|
||||
buf[0] = 'P';
|
||||
buf[1] = '\0';
|
||||
str = &buf[1];
|
||||
count = 2;
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (duration.parts[i] > 0) {
|
||||
durationlen[i] = 1 + numlen(duration.parts[i]);
|
||||
if (i < 4) {
|
||||
D = true;
|
||||
} else {
|
||||
T = true;
|
||||
}
|
||||
} else {
|
||||
durationlen[i] = 0;
|
||||
}
|
||||
count += durationlen[i];
|
||||
}
|
||||
/*
|
||||
* Special case for seconds which is not taken into account in the
|
||||
* above for loop: Count the length of the seconds part if it is
|
||||
* non-zero, or if all the other parts are also zero. In the latter
|
||||
* case this function will print "PT0S".
|
||||
*/
|
||||
if (duration.parts[6] > 0 ||
|
||||
(!D && !duration.parts[4] && !duration.parts[5])) {
|
||||
durationlen[6] = 1 + numlen(duration.parts[6]);
|
||||
T = true;
|
||||
count += durationlen[6];
|
||||
}
|
||||
/* Add one character for the time indicator. */
|
||||
if (T) {
|
||||
count++;
|
||||
}
|
||||
INSIST(count < CFG_DURATION_MAXLEN);
|
||||
|
||||
/* Now print the duration. */
|
||||
for (i = 0; i < 6; i++) {
|
||||
/*
|
||||
* We don't check here if weeks and other time indicator are
|
||||
* used mutually exclusively.
|
||||
*/
|
||||
if (duration.parts[i] > 0) {
|
||||
snprintf(str, durationlen[i]+2, "%u%c",
|
||||
(uint32_t) duration.parts[i], indicators[i]);
|
||||
str += durationlen[i]+1;
|
||||
}
|
||||
if (i == 3 && T) {
|
||||
snprintf(str, 2, "T");
|
||||
str += 1;
|
||||
}
|
||||
|
||||
}
|
||||
/* Special case for seconds. */
|
||||
if (duration.parts[6] > 0 ||
|
||||
(!D && !duration.parts[4] && !duration.parts[3])) {
|
||||
snprintf(str, durationlen[6]+2, "%u%c",
|
||||
(uint32_t) duration.parts[6], indicators[6]);
|
||||
}
|
||||
cfg_print_chars(pctx, buf, strlen(buf));
|
||||
}
|
||||
|
||||
bool
|
||||
cfg_obj_isduration(const cfg_obj_t *obj) {
|
||||
REQUIRE(obj != NULL);
|
||||
return (obj->type->rep == &cfg_rep_duration);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
cfg_obj_asduration(const cfg_obj_t *obj) {
|
||||
REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_duration);
|
||||
uint32_t duration = 0;
|
||||
duration += obj->value.duration.parts[6]; // Seconds
|
||||
duration += obj->value.duration.parts[5]*60; // Minutes
|
||||
duration += obj->value.duration.parts[4]*3600; // Hours
|
||||
duration += obj->value.duration.parts[3]*86400; // Days
|
||||
duration += obj->value.duration.parts[2]*86400*7; // Weaks
|
||||
/*
|
||||
* The below additions are not entirely correct
|
||||
* because days may very per month and per year.
|
||||
*/
|
||||
duration += obj->value.duration.parts[1]*86400*31; // Months
|
||||
duration += obj->value.duration.parts[0]*86400*365; // Years
|
||||
return (duration);
|
||||
}
|
||||
|
||||
/*
|
||||
* duration_fromtext initially taken from OpenDNSSEC code base.
|
||||
* Modified to fit the BIND 9 code.
|
||||
*
|
||||
* Copyright (c) 2009-2018 NLNet Labs.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
static isc_result_t
|
||||
duration_fromtext(isc_textregion_t *source, cfg_duration_t *duration) {
|
||||
char buf[CFG_DURATION_MAXLEN];
|
||||
char *P, *X, *T, *W, *str;
|
||||
bool not_weeks = false;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Copy the buffer as it may not be NULL terminated.
|
||||
* Anyone having a duration longer than 63 characters is crazy.
|
||||
*/
|
||||
if (source->length > sizeof(buf) - 1) {
|
||||
return (ISC_R_BADNUMBER);
|
||||
}
|
||||
/* Copy source->length bytes and NULL terminate. */
|
||||
snprintf(buf, sizeof(buf), "%.*s", (int)source->length, source->base);
|
||||
str = buf;
|
||||
|
||||
/* Clear out duration. */
|
||||
for (i = 0; i < 7; i++) {
|
||||
duration->parts[i] = 0;
|
||||
}
|
||||
|
||||
/* Every duration starts with 'P' */
|
||||
P = strchr(str, 'P');
|
||||
if (!P) {
|
||||
return (ISC_R_BADNUMBER);
|
||||
}
|
||||
|
||||
/* Record the time indicator. */
|
||||
T = strchr(str, 'T');
|
||||
|
||||
/* Record years. */
|
||||
X = strchr(str, 'Y');
|
||||
if (X) {
|
||||
duration->parts[0] = atoi(str+1);
|
||||
str = X;
|
||||
not_weeks = true;
|
||||
}
|
||||
/* Record months. */
|
||||
X = strchr(str, 'M');
|
||||
/*
|
||||
* M could be months or minutes. This is months if there is no time
|
||||
* part, or this M indicator is before the time indicator.
|
||||
*/
|
||||
if (X && (!T || (size_t) (X-P) < (size_t) (T-P))) {
|
||||
duration->parts[1] = atoi(str+1);
|
||||
str = X;
|
||||
not_weeks = true;
|
||||
}
|
||||
/* Record days. */
|
||||
X = strchr(str, 'D');
|
||||
if (X) {
|
||||
duration->parts[3] = atoi(str+1);
|
||||
str = X;
|
||||
not_weeks = true;
|
||||
}
|
||||
|
||||
/* Time part? */
|
||||
if (T) {
|
||||
str = T;
|
||||
not_weeks = true;
|
||||
}
|
||||
|
||||
/* Record hours. */
|
||||
X = strchr(str, 'H');
|
||||
if (X && T) {
|
||||
duration->parts[4] = atoi(str+1);
|
||||
str = X;
|
||||
not_weeks = true;
|
||||
}
|
||||
/* Record minutes. */
|
||||
X = strrchr(str, 'M');
|
||||
/*
|
||||
* M could be months or minutes. This is minutes if there is a time
|
||||
* part and the M indicator is behind the time indicator.
|
||||
*/
|
||||
if (X && T && (size_t) (X-P) > (size_t) (T-P)) {
|
||||
duration->parts[5] = atoi(str+1);
|
||||
str = X;
|
||||
not_weeks = true;
|
||||
}
|
||||
/* Record seconds. */
|
||||
X = strchr(str, 'S');
|
||||
if (X && T) {
|
||||
duration->parts[6] = atoi(str+1);
|
||||
str = X;
|
||||
not_weeks = true;
|
||||
}
|
||||
|
||||
/* Or is the duration configured in weeks? */
|
||||
W = strchr(buf, 'W');
|
||||
if (W) {
|
||||
if (not_weeks) {
|
||||
/* Mix of weeks and other indicators is not allowed */
|
||||
return (ISC_R_BADNUMBER);
|
||||
} else {
|
||||
duration->parts[2] = atoi(str+1);
|
||||
str = W;
|
||||
}
|
||||
}
|
||||
|
||||
/* Deal with trailing garbage. */
|
||||
if (str[1] != '\0') {
|
||||
return (ISC_R_BADNUMBER);
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
cfg_parse_duration(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
cfg_obj_t **ret)
|
||||
{
|
||||
isc_result_t result;
|
||||
cfg_obj_t *obj = NULL;
|
||||
cfg_duration_t duration;
|
||||
|
||||
UNUSED(type);
|
||||
|
||||
CHECK(cfg_gettoken(pctx, 0));
|
||||
if (pctx->token.type != isc_tokentype_string) {
|
||||
result = ISC_R_UNEXPECTEDTOKEN;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (TOKEN_STRING(pctx)[0] == 'P') {
|
||||
result = duration_fromtext(&pctx->token.value.as_textregion,
|
||||
&duration);
|
||||
duration.iso8601 = true;
|
||||
} else {
|
||||
uint32_t ttl;
|
||||
result = dns_ttl_fromtext(&pctx->token.value.as_textregion,
|
||||
&ttl);
|
||||
/*
|
||||
* With dns_ttl_fromtext() the information on optional units.
|
||||
* is lost, and is treated as seconds from now on.
|
||||
*/
|
||||
duration.parts[0] = 0;
|
||||
duration.parts[1] = 0;
|
||||
duration.parts[2] = 0;
|
||||
duration.parts[3] = 0;
|
||||
duration.parts[4] = 0;
|
||||
duration.parts[5] = 0;
|
||||
duration.parts[6] = ttl;
|
||||
duration.iso8601 = false;
|
||||
}
|
||||
if (result == ISC_R_RANGE) {
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR,
|
||||
"duration or TTL out of range");
|
||||
return (result);
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
CHECK(cfg_create_obj(pctx, &cfg_type_duration, &obj));
|
||||
obj->value.duration = duration;
|
||||
*ret = obj;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR,
|
||||
"expected ISO 8601 duration or TTL value");
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*%
|
||||
* A duration as defined by ISO 8601 (P[n]Y[n]M[n]DT[n]H[n]M[n]S).
|
||||
* - P is the duration indicator ("period") placed at the start.
|
||||
* - Y is the year indicator that follows the value for the number of years.
|
||||
* - M is the month indicator that follows the value for the number of months.
|
||||
* - D is the day indicator that follows the value for the number of days.
|
||||
* - T is the time indicator that precedes the time components.
|
||||
* - H is the hour indicator that follows the value for the number of hours.
|
||||
* - M is the minute indicator that follows the value for the number of
|
||||
* minutes.
|
||||
* - S is the second indicator that follows the value for the number of
|
||||
* seconds.
|
||||
*
|
||||
* A duration can also be a TTL value (number + optional unit).
|
||||
*/
|
||||
LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_duration = {
|
||||
"duration", cfg_parse_duration, cfg_print_duration, cfg_doc_terminal,
|
||||
&cfg_rep_duration, NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* qstring (quoted string), ustring (unquoted string), astring
|
||||
* (any string)
|
||||
* (any string), sstring (secret string)
|
||||
*/
|
||||
|
||||
/* Create a string object from a null-terminated C string. */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
syntax(2)
|
||||
test_suite('bind9')
|
||||
|
||||
tap_test_program{name='duration_test'}
|
||||
tap_test_program{name='parser_test'}
|
||||
|
|
|
|||
|
|
@ -30,13 +30,18 @@ ISCCFGDEPLIBS = ../libisccfg.@A@
|
|||
LIBS = @LIBS@ @CMOCKA_LIBS@
|
||||
|
||||
OBJS =
|
||||
SRCS = parser_test.c
|
||||
SRCS = duration_test.c parser_test.c
|
||||
|
||||
SUBDIRS =
|
||||
TARGETS = parser_test@EXEEXT@
|
||||
TARGETS = duration_test@EXEEXT@ parser_test@EXEEXT@
|
||||
|
||||
@BIND9_MAKE_RULES@
|
||||
|
||||
duration_test@EXEEXT@: duration_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${ISCCFGDEPLIBS}
|
||||
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \
|
||||
${LDFLAGS} -o $@ duration_test.@O@ \
|
||||
${ISCCFGLIBS} ${DNSLIBS} ${ISCLIBS} ${LIBS}
|
||||
|
||||
parser_test@EXEEXT@: parser_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${ISCCFGDEPLIBS}
|
||||
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \
|
||||
${LDFLAGS} -o $@ parser_test.@O@ \
|
||||
|
|
|
|||
207
lib/isccfg/tests/duration_test.c
Normal file
207
lib/isccfg/tests/duration_test.c
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if HAVE_CMOCKA
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <sched.h> /* IWYU pragma: keep */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define UNIT_TESTING
|
||||
#include <cmocka.h>
|
||||
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/lex.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/types.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <isccfg/cfg.h>
|
||||
#include <isccfg/grammar.h>
|
||||
#include <isccfg/namedconf.h>
|
||||
|
||||
#define CHECK(r) \
|
||||
do { \
|
||||
result = (r); \
|
||||
if (result != ISC_R_SUCCESS) \
|
||||
goto cleanup; \
|
||||
} while (0)
|
||||
|
||||
isc_mem_t *mctx = NULL;
|
||||
isc_log_t *lctx = NULL;
|
||||
static isc_logcategory_t categories[] = {
|
||||
{ "", 0 },
|
||||
{ "client", 0 },
|
||||
{ "network", 0 },
|
||||
{ "update", 0 },
|
||||
{ "queries", 0 },
|
||||
{ "unmatched", 0 },
|
||||
{ "update-security", 0 },
|
||||
{ "query-errors", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static void
|
||||
cleanup() {
|
||||
if (lctx != NULL) {
|
||||
isc_log_destroy(&lctx);
|
||||
}
|
||||
if (mctx != NULL) {
|
||||
isc_mem_destroy(&mctx);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
setup() {
|
||||
isc_result_t result;
|
||||
|
||||
isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
|
||||
isc_mem_create(&mctx);
|
||||
|
||||
isc_logdestination_t destination;
|
||||
isc_logconfig_t *logconfig = NULL;
|
||||
|
||||
CHECK(isc_log_create(mctx, &lctx, &logconfig));
|
||||
isc_log_registercategories(lctx, categories);
|
||||
isc_log_setcontext(lctx);
|
||||
|
||||
destination.file.stream = stderr;
|
||||
destination.file.name = NULL;
|
||||
destination.file.versions = ISC_LOG_ROLLNEVER;
|
||||
destination.file.maximum_size = 0;
|
||||
CHECK(isc_log_createchannel(logconfig, "stderr",
|
||||
ISC_LOG_TOFILEDESC,
|
||||
ISC_LOG_DYNAMIC,
|
||||
&destination, 0));
|
||||
CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL));
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
cleanup();
|
||||
return (result);
|
||||
}
|
||||
|
||||
struct duration_conf {
|
||||
const char* string;
|
||||
uint32_t time;
|
||||
};
|
||||
typedef struct duration_conf duration_conf_t;
|
||||
|
||||
/* test cfg_obj_asduration() */
|
||||
static void
|
||||
cfg_obj_asduration_test(void **state) {
|
||||
isc_result_t result;
|
||||
duration_conf_t durations[] = {
|
||||
{ .string = "PT0S", .time = 0 },
|
||||
{ .string = "PT42S", .time = 42 },
|
||||
{ .string = "PT10M", .time = 600 },
|
||||
{ .string = "PT10M4S", .time = 604 },
|
||||
{ .string = "PT2H", .time = 7200 },
|
||||
{ .string = "PT2H3S", .time = 7203 },
|
||||
{ .string = "PT2H1M3S", .time = 7263 },
|
||||
{ .string = "P7D", .time = 604800 },
|
||||
{ .string = "P7DT2H", .time = 612000 },
|
||||
{ .string = "P2W", .time = 1209600 },
|
||||
{ .string = "P3M", .time = 8035200 },
|
||||
{ .string = "P3MT10M", .time = 8035800 },
|
||||
{ .string = "P5Y", .time = 157680000 },
|
||||
{ .string = "P5YT2H", .time = 157687200 },
|
||||
{ .string = "P1Y1M1DT1H1M1S", .time = 34304461 },
|
||||
{ .string = "0", .time = 0 },
|
||||
{ .string = "30", .time = 30 },
|
||||
{ .string = "42s", .time = 42 },
|
||||
{ .string = "10m", .time = 600 },
|
||||
{ .string = "2h", .time = 7200 },
|
||||
{ .string = "7d", .time = 604800 },
|
||||
{ .string = "2w", .time = 1209600 },
|
||||
};
|
||||
int num = 22;
|
||||
isc_buffer_t buf1;
|
||||
cfg_parser_t *p1 = NULL;
|
||||
cfg_obj_t *c1 = NULL;
|
||||
|
||||
UNUSED(state);
|
||||
|
||||
setup();
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
const cfg_listelt_t *element;
|
||||
const cfg_obj_t *kasps = NULL;
|
||||
char conf[64];
|
||||
sprintf(&conf[0],
|
||||
"dnssec-policy \"dp\"\n{\nsignatures-refresh %s;\n};\n",
|
||||
durations[i].string);
|
||||
|
||||
isc_buffer_init(&buf1, conf, strlen(conf) - 1);
|
||||
isc_buffer_add(&buf1, strlen(conf) - 1);
|
||||
|
||||
/* Parse with default line numbering */
|
||||
result = cfg_parser_create(mctx, lctx, &p1);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
result = cfg_parse_buffer(p1, &buf1, "text1", 0,
|
||||
&cfg_type_namedconf, 0, &c1);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
(void)cfg_map_get(c1, "dnssec-policy", &kasps);
|
||||
assert_non_null(kasps);
|
||||
for (element = cfg_list_first(kasps);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
const cfg_obj_t *d1 = NULL;
|
||||
const cfg_obj_t *kopts = NULL;
|
||||
cfg_obj_t *kconf = cfg_listelt_value(element);
|
||||
assert_non_null(kconf);
|
||||
|
||||
kopts = cfg_tuple_get(kconf, "options");
|
||||
result = cfg_map_get(kopts, "signatures-refresh", &d1);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
assert_int_equal(durations[i].time,
|
||||
cfg_obj_asduration(d1));
|
||||
}
|
||||
|
||||
cfg_obj_destroy(p1, &c1);
|
||||
cfg_parser_destroy(&p1);
|
||||
}
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
||||
int
|
||||
main(void) {
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(cfg_obj_asduration_test),
|
||||
};
|
||||
|
||||
return (cmocka_run_group_tests(tests, NULL, NULL));
|
||||
}
|
||||
|
||||
#else /* HAVE_CMOCKA */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(void) {
|
||||
printf("1..0 # Skipped: cmocka not available\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -24,6 +24,7 @@ cfg_doc_tuple
|
|||
cfg_doc_void
|
||||
cfg_gettoken
|
||||
cfg_is_enum
|
||||
cfg_kasp_fromconfig
|
||||
cfg_list_first
|
||||
cfg_list_length
|
||||
cfg_list_next
|
||||
|
|
@ -36,6 +37,7 @@ cfg_map_get
|
|||
cfg_map_getname
|
||||
cfg_map_nextclause
|
||||
cfg_obj_asboolean
|
||||
cfg_obj_asduration
|
||||
cfg_obj_asfixedpoint
|
||||
cfg_obj_asnetprefix
|
||||
cfg_obj_aspercentage
|
||||
|
|
@ -48,6 +50,7 @@ cfg_obj_destroy
|
|||
cfg_obj_file
|
||||
cfg_obj_getdscp
|
||||
cfg_obj_isboolean
|
||||
cfg_obj_isduration
|
||||
cfg_obj_isfixedpoint
|
||||
cfg_obj_islist
|
||||
cfg_obj_ismap
|
||||
|
|
@ -68,6 +71,7 @@ cfg_parse_boolean
|
|||
cfg_parse_bracketed_list
|
||||
cfg_parse_buffer
|
||||
cfg_parse_dscp
|
||||
cfg_parse_duration
|
||||
cfg_parse_enum
|
||||
cfg_parse_enum_or_other
|
||||
cfg_parse_file
|
||||
|
|
@ -107,6 +111,7 @@ cfg_print_bracketed_list
|
|||
cfg_print_chars
|
||||
cfg_print_clauseflags
|
||||
cfg_print_cstr
|
||||
cfg_print_duration
|
||||
cfg_print_fixedpoint
|
||||
cfg_print_grammar
|
||||
cfg_print_indent
|
||||
|
|
@ -131,6 +136,7 @@ cfg_ungettoken
|
|||
; Exported Data
|
||||
|
||||
;cfg_rep_boolean
|
||||
;cfg_rep_duration
|
||||
;cfg_rep_fixedpoint
|
||||
;cfg_rep_list
|
||||
;cfg_rep_map
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@
|
|||
<ClCompile Include="..\dnsconf.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\kaspconf.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\log.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -53,6 +56,9 @@
|
|||
<ClInclude Include="..\include\isccfg\grammar.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\isccfg\kaspconf.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\isccfg\log.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -63,4 +69,4 @@
|
|||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="..\aclconf.c" />
|
||||
<ClCompile Include="..\dnsconf.c" />
|
||||
<ClCompile Include="..\kaspconf.c" />
|
||||
<ClCompile Include="..\log.c" />
|
||||
<ClCompile Include="..\namedconf.c" />
|
||||
<ClCompile Include="..\parser.c" />
|
||||
|
|
@ -127,6 +128,7 @@
|
|||
<ClInclude Include="..\include\isccfg\dnsconf.h" />
|
||||
<ClInclude Include="..\include\isccfg\cfg.h" />
|
||||
<ClInclude Include="..\include\isccfg\grammar.h" />
|
||||
<ClInclude Include="..\include\isccfg\kaspconf.h" />
|
||||
<ClInclude Include="..\include\isccfg\log.h" />
|
||||
<ClInclude Include="..\include\isccfg\namedconf.h" />
|
||||
<ClInclude Include="..\include\isccfg\version.h" />
|
||||
|
|
|
|||
|
|
@ -694,6 +694,14 @@
|
|||
./bin/tests/system/ixfr/prereq.sh SH 2001,2004,2007,2012,2014,2016,2018,2019
|
||||
./bin/tests/system/ixfr/setup.sh SH 2001,2004,2007,2011,2012,2013,2014,2016,2018,2019
|
||||
./bin/tests/system/ixfr/tests.sh SH 2001,2004,2007,2011,2012,2014,2016,2018,2019
|
||||
./bin/tests/system/kasp/README TXT.BRIEF 2019
|
||||
./bin/tests/system/kasp/clean.sh SH 2019
|
||||
./bin/tests/system/kasp/ns2/setup.sh SH 2019
|
||||
./bin/tests/system/kasp/ns3/setup.sh SH 2019
|
||||
./bin/tests/system/kasp/ns4/setup.sh SH 2019
|
||||
./bin/tests/system/kasp/ns5/setup.sh SH 2019
|
||||
./bin/tests/system/kasp/setup.sh SH 2019
|
||||
./bin/tests/system/kasp/tests.sh SH 2019
|
||||
./bin/tests/system/keepalive/clean.sh SH 2017,2018,2019
|
||||
./bin/tests/system/keepalive/expected X 2017,2018,2019
|
||||
./bin/tests/system/keepalive/setup.sh SH 2017,2018,2019
|
||||
|
|
@ -1410,6 +1418,7 @@
|
|||
./doc/arm/delegation-only.zoneopt.xml SGML 2018,2019
|
||||
./doc/arm/dlz.xml SGML 2012,2013,2014,2015,2016,2018,2019
|
||||
./doc/arm/dnssec-keys.grammar.xml SGML 2019
|
||||
./doc/arm/dnssec-policy.grammar.xml SGML 2019
|
||||
./doc/arm/dnssec.xml SGML 2010,2011,2015,2016,2017,2018,2019
|
||||
./doc/arm/dyndb.xml SGML 2015,2016,2018,2019
|
||||
./doc/arm/forward.zoneopt.xml SGML 2018,2019
|
||||
|
|
@ -1499,6 +1508,7 @@
|
|||
./doc/design/db_rules TXT.BRIEF 1999,2000,2001,2004,2016,2018,2019
|
||||
./doc/design/decompression TXT.BRIEF 1999,2000,2001,2004,2016,2018,2019
|
||||
./doc/design/dispatch TXT.BRIEF 2000,2001,2004,2016,2018,2019
|
||||
./doc/design/dnssec-policy TXT.BRIEF 2019
|
||||
./doc/design/dscp TXT.BRIEF 2013,2016,2018,2019
|
||||
./doc/design/keydone TXT.BRIEF 2011,2016,2018,2019
|
||||
./doc/design/logging TXT.BRIEF 1999,2000,2001,2004,2016,2018,2019
|
||||
|
|
@ -1675,8 +1685,10 @@
|
|||
./lib/dns/include/dns/ipkeylist.h C 2016,2018,2019
|
||||
./lib/dns/include/dns/iptable.h C 2007,2012,2014,2016,2018,2019
|
||||
./lib/dns/include/dns/journal.h C 1999,2000,2001,2004,2005,2006,2007,2008,2009,2011,2013,2016,2017,2018,2019
|
||||
./lib/dns/include/dns/kasp.h C 2019
|
||||
./lib/dns/include/dns/keydata.h C 2009,2016,2018,2019
|
||||
./lib/dns/include/dns/keyflags.h C 1999,2000,2001,2004,2005,2006,2007,2016,2018,2019
|
||||
./lib/dns/include/dns/keymgr.h C 2019
|
||||
./lib/dns/include/dns/keytable.h C 2000,2001,2004,2005,2007,2009,2010,2014,2015,2016,2017,2018,2019
|
||||
./lib/dns/include/dns/keyvalues.h C 1999,2000,2001,2003,2004,2005,2006,2007,2008,2009,2010,2012,2016,2017,2018,2019
|
||||
./lib/dns/include/dns/lib.h C 1999,2000,2001,2004,2005,2006,2007,2009,2016,2017,2018,2019
|
||||
|
|
@ -1742,8 +1754,10 @@
|
|||
./lib/dns/ipkeylist.c C 2016,2018,2019
|
||||
./lib/dns/iptable.c C 2007,2008,2009,2013,2014,2016,2017,2018,2019
|
||||
./lib/dns/journal.c C 1999,2000,2001,2002,2004,2005,2007,2008,2009,2010,2011,2013,2014,2015,2016,2017,2018,2019
|
||||
./lib/dns/kasp.c C 2019
|
||||
./lib/dns/key.c C 2001,2004,2005,2006,2007,2011,2016,2018,2019
|
||||
./lib/dns/keydata.c C 2009,2014,2016,2018,2019
|
||||
./lib/dns/keymgr.c C 2019
|
||||
./lib/dns/keytable.c C 2000,2001,2004,2005,2007,2009,2010,2013,2014,2015,2016,2017,2018,2019
|
||||
./lib/dns/lib.c C 1999,2000,2001,2004,2005,2007,2009,2013,2014,2015,2016,2017,2018,2019
|
||||
./lib/dns/log.c C 1999,2000,2001,2003,2004,2005,2006,2007,2009,2011,2012,2013,2014,2015,2016,2017,2018,2019
|
||||
|
|
@ -2433,13 +2447,16 @@
|
|||
./lib/isccfg/include/isccfg/cfg.h C 2000,2001,2002,2004,2005,2006,2007,2010,2013,2014,2015,2016,2018,2019
|
||||
./lib/isccfg/include/isccfg/dnsconf.h C 2009,2016,2018,2019
|
||||
./lib/isccfg/include/isccfg/grammar.h C 2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2013,2014,2015,2016,2017,2018,2019
|
||||
./lib/isccfg/include/isccfg/kaspconf.h C 2019
|
||||
./lib/isccfg/include/isccfg/log.h C 2001,2004,2005,2006,2007,2009,2016,2018,2019
|
||||
./lib/isccfg/include/isccfg/namedconf.h C 2002,2004,2005,2006,2007,2009,2010,2014,2016,2018,2019
|
||||
./lib/isccfg/include/isccfg/version.h C 2001,2004,2005,2006,2007,2016,2018,2019
|
||||
./lib/isccfg/kaspconf.c C 2019
|
||||
./lib/isccfg/log.c C 2001,2004,2005,2006,2007,2016,2018,2019
|
||||
./lib/isccfg/namedconf.c C 2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019
|
||||
./lib/isccfg/parser.c C 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019
|
||||
./lib/isccfg/tests/Kyuafile X 2017,2018,2019
|
||||
./lib/isccfg/tests/duration_test.c C 2019
|
||||
./lib/isccfg/tests/parser_test.c C 2016,2018,2019
|
||||
./lib/isccfg/version.c C 1998,1999,2000,2001,2004,2005,2007,2016,2018,2019
|
||||
./lib/isccfg/win32/DLLMain.c C 2001,2004,2007,2016,2018,2019
|
||||
|
|
|
|||
Loading…
Reference in a new issue