mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 05:28:00 +00:00
Introduce dnssec-policy configuration
This commit introduces the initial `dnssec-policy` configuration statement. It has an initial set of options to deal with signature and key maintenance. Add some checks to ensure that dnssec-policy is configured at the right locations, and that policies referenced to in zone statements actually exist. Add some checks that when a user adds the new `dnssec-policy` configuration, it will no longer contain existing DNSSEC configuration options. Specifically: `inline-signing`, `auto-dnssec`, `dnssec-dnskey-kskonly`, `dnssec-secure-to-insecure`, `update-check-ksk`, `dnssec-update-mode`, `dnskey-sig-validity`, and `sig-validity-interval`. Test a good kasp configuration, and some bad configurations.
This commit is contained in:
parent
1fbd8bb1b3
commit
a50d707fdc
@ -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>;
|
||||
@ -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>;
|
||||
@ -1008,6 +1010,21 @@ 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 <replaceable>duration</replaceable> <replaceable>integer</replaceable> [ <replaceable>integer</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>;
|
||||
};
|
||||
</literallayout>
|
||||
</refsection>
|
||||
|
||||
<refsection><info><title>FILES</title></info>
|
||||
|
||||
<para><filename>/etc/named.conf</filename>
|
||||
|
20
bin/tests/system/checkconf/bad-kasp1.conf
Normal file
20
bin/tests/system/checkconf/bad-kasp1.conf
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
options {
|
||||
dnssec-policy "notatzonelevel";
|
||||
};
|
||||
|
||||
zone "example.net" {
|
||||
type master;
|
||||
file "example.db";
|
||||
};
|
||||
|
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";
|
||||
};
|
||||
|
@ -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*
|
||||
|
47
bin/tests/system/checkconf/good-kasp.conf
Normal file
47
bin/tests/system/checkconf/good-kasp.conf
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 P1Y 13 256;
|
||||
zsk key-directory P30D 13;
|
||||
csk key-directory P30D 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;
|
||||
dnssec-policy "test";
|
||||
file "example1.db";
|
||||
};
|
||||
zone "example2" {
|
||||
type master;
|
||||
dnssec-policy "default";
|
||||
file "example2.db";
|
||||
};
|
@ -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
|
||||
|
@ -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,147 @@ 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 P5Y 8 2048;
|
||||
zsk key-directory P30D 8;
|
||||
csk key-directory P6MT12H3M15S 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>
|
||||
|
||||
</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 +12029,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>
|
||||
|
25
doc/arm/dnssec-policy.grammar.xml
Normal file
25
doc/arm/dnssec-policy.grammar.xml
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.
|
||||
-->
|
||||
|
||||
<!-- 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>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>;
|
||||
};
|
||||
</programlisting>
|
||||
|
@ -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>;
|
||||
|
@ -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 );
|
||||
|
@ -122,7 +122,6 @@ dnssec-policy "nsec3" {
|
||||
description "policy for zones that require zone walking mitigation";
|
||||
|
||||
// Signatures
|
||||
signatures-resign PT2H;
|
||||
signatures-refresh P3D;
|
||||
signatures-validity P14D;
|
||||
signatures-validity-dnskey P14D;
|
||||
|
@ -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,17 @@ 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 <duration> <string>
|
||||
[ <integer> ]; ... };
|
||||
publish-safety <duration>;
|
||||
retire-safety <duration>;
|
||||
signatures-refresh <duration>;
|
||||
signatures-validity <duration>;
|
||||
signatures-validity-dnskey <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 );
|
||||
|
@ -856,6 +856,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";
|
||||
|
||||
/*
|
||||
@ -948,6 +949,44 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check dnssec-policy at the view/options level
|
||||
*/
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(options, "dnssec-policy", &obj);
|
||||
if (obj != NULL) {
|
||||
bool bad_kasp = true;
|
||||
if (optlevel == optlevel_zone && cfg_obj_isstring(obj)) {
|
||||
bad_kasp = false;
|
||||
} 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)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
bad_kasp = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (bad_kasp) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"dnssec-policy may only be activated at "
|
||||
"the top level and referenced to at the "
|
||||
"zone level");
|
||||
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) {
|
||||
@ -996,6 +1035,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;
|
||||
@ -1012,6 +1058,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;
|
||||
@ -1117,8 +1169,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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1858,6 +1911,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[] = {
|
||||
@ -2070,6 +2124,42 @@ 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 {
|
||||
(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.
|
||||
*/
|
||||
@ -2256,19 +2346,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;
|
||||
@ -2293,6 +2400,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);
|
||||
@ -2315,6 +2437,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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
@ -410,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.
|
||||
*/
|
||||
@ -465,6 +481,40 @@ 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 cfg_tuplefielddef_t kaspkey_fields[] = {
|
||||
{ "role", &cfg_type_dnsseckeyrole, 0 },
|
||||
{ "keystore-type", &cfg_type_dnsseckeystore, 0 },
|
||||
{ "lifetime", &cfg_type_duration, 0 },
|
||||
{ "algorithm", &cfg_type_uint32, 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
|
||||
};
|
||||
|
||||
static keyword_type_t wild_class_kw = { "class", &cfg_type_ustring };
|
||||
|
||||
static cfg_type_t cfg_type_optional_wild_class = {
|
||||
@ -637,6 +687,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,
|
||||
@ -962,6 +1020,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 },
|
||||
@ -1997,6 +2056,21 @@ 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 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
/*%
|
||||
* Clauses that can be found in a 'zone' statement,
|
||||
* with defaults in the 'view' or 'options' statement.
|
||||
@ -2241,6 +2315,9 @@ zone_only_clauses[] = {
|
||||
{ "dlz", &cfg_type_astring,
|
||||
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_REDIRECT
|
||||
},
|
||||
{ "dnssec-policy", &cfg_type_astring,
|
||||
CFG_ZONE_MASTER | CFG_ZONE_SLAVE
|
||||
},
|
||||
{ "file", &cfg_type_qstring,
|
||||
CFG_ZONE_MASTER | CFG_ZONE_SLAVE | CFG_ZONE_MIRROR |
|
||||
CFG_ZONE_STUB | CFG_ZONE_HINT | CFG_ZONE_REDIRECT
|
||||
@ -2345,6 +2422,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
|
||||
|
@ -1410,6 +1410,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
|
||||
|
Loading…
x
Reference in New Issue
Block a user