2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

[master] new dnssec-coverage options

3702.	[func]		'dnssec-coverage -l' option specifies a length
			of time to check for coverage; events further into
			the future are ignored.  'dnssec-coverage -z'
			checks only ZSK events, and 'dnssec-coverage -k'
			checks only KSK events.  (Thanks to Peter Palfrader.)
			[RT #35168]
This commit is contained in:
Evan Hunt 2014-01-10 17:53:21 -08:00
parent 990d0e893f
commit 7d2b185f16
5 changed files with 158 additions and 25 deletions

View File

@ -1,3 +1,10 @@
3702. [func] 'dnssec-coverage -l' option specifies a length
of time to check for coverage; events further into
the future are ignored. 'dnssec-coverage -z'
checks only ZSK events, and 'dnssec-coverage -k'
checks only KSK events. (Thanks to Peter Palfrader.)
[RT #35168]
3701. [func] named-checkconf can now obscure shared secrets
when printing by specifying '-x'. [RT #34465]

View File

@ -44,11 +44,14 @@
<cmdsynopsis>
<command>dnssec-coverage</command>
<arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
<arg><option>-l <replaceable class="parameter">length</replaceable></option></arg>
<arg><option>-f <replaceable class="parameter">file</replaceable></option></arg>
<arg><option>-d <replaceable class="parameter">DNSKEY TTL</replaceable></option></arg>
<arg><option>-m <replaceable class="parameter">max TTL</replaceable></option></arg>
<arg><option>-r <replaceable class="parameter">interval</replaceable></option></arg>
<arg><option>-c <replaceable class="parameter">compilezone path</replaceable></option></arg>
<arg><option>-k</option></arg>
<arg><option>-z</option></arg>
<arg choice="opt">zone</arg>
</cmdsynopsis>
</refsynopsisdiv>
@ -86,6 +89,16 @@
<title>OPTIONS</title>
<variablelist>
<varlistentry>
<term>-K <replaceable class="parameter">directory</replaceable></term>
<listitem>
<para>
Sets the directory in which keys can be found. Defaults to the
current working directory.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-f <replaceable class="parameter">file</replaceable></term>
<listitem>
@ -100,11 +113,18 @@
</varlistentry>
<varlistentry>
<term>-K <replaceable class="parameter">directory</replaceable></term>
<term>-l <replaceable class="parameter">duration</replaceable></term>
<listitem>
<para>
Sets the directory in which keys can be found. Defaults to the
current working directory.
The length of time to check for DNSSEC coverage. Key events
scheduled further into the future than <option>duration</option>
will be ignored, and assumed to be correct.
</para>
<para>
The value of <option>duration</option> can be set in seconds,
or in larger units of time by adding a suffix: 'mi' for minutes,
'h' for hours, 'd' for days, 'w' for weeks, 'mo' for months,
'y' for years.
</para>
</listitem>
</varlistentry>
@ -185,6 +205,27 @@
</listitem>
</varlistentry>
<varlistentry>
<term>-k</term>
<listitem>
<para>
Only check KSK coverage; ignore ZSK events. Cannot be
used with <option>-z</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-z</term>
<listitem>
<para>
Only check ZSK coverage; ignore KSK events. Cannot be
used with <option>-k</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-c <replaceable class="parameter">compilezone path</replaceable></term>
<listitem>

View File

@ -15,6 +15,10 @@
# PERFORMANCE OF THIS SOFTWARE.
############################################################################
# changes 2014-01-08, Peter Palfrader:
# - support checking only X days into the future.
# - support checking only KSK keys or only ZSK keys.
import argparse
import os
import glob
@ -506,6 +510,13 @@ def check_events(eventsList, ksk):
eventgroups.append(eventgroup)
for eventgroup in eventgroups:
if (args.checklimit and
calendar.timegm(eventgroup[0].when) > args.checklimit):
print("Ignoring events after %s" %
time.strftime("%a %b %d %H:%M:%S UTC %Y",
time.gmtime(args.checklimit)))
return True
(active, published) = \
process_events(eventgroup, active, published)
@ -548,21 +559,23 @@ def check_zones(eventsList):
zonesfound = True
for alg in eventsList[zone]:
vspace()
print("Checking scheduled KSK events for zone %s, algorithm %s..." %
(zone, algname(alg)))
if not check_events(eventsList[zone][alg], True):
foundprob = True
else:
print ("No errors found")
if not args.no_ksk:
vspace()
print("Checking scheduled KSK events for zone %s, algorithm %s..." %
(zone, algname(alg)))
if not check_events(eventsList[zone][alg], True):
foundprob = True
else:
print ("No errors found")
vspace()
print("Checking scheduled ZSK events for zone %s, algorithm %s..." %
(zone, algname(alg)))
if not check_events(eventsList[zone][alg], False):
foundprob = True
else:
print ("No errors found")
if not args.no_zsk:
vspace()
print("Checking scheduled ZSK events for zone %s, algorithm %s..." %
(zone, algname(alg)))
if not check_events(eventsList[zone][alg], False):
foundprob = True
else:
print ("No errors found")
if not zonesfound:
print("ERROR: No key events found for %s in '%s'" %
@ -637,17 +650,28 @@ def parse_args():
help='zone master file', metavar='file')
parser.add_argument('-m', dest='maxttl', type=str,
help='the longest TTL in the zone(s)',
metavar='int')
metavar='time')
parser.add_argument('-d', dest='keyttl', type=str,
help='the DNSKEY TTL', metavar='int')
help='the DNSKEY TTL', metavar='time')
parser.add_argument('-r', dest='resign', default='1944000',
type=int, help='the RRSIG refresh interval '
'in seconds [default: 22.5 days]',
metavar='int')
metavar='time')
parser.add_argument('-c', dest='compilezone',
default=compilezone, type=str,
help='path to \'named-compilezone\'',
metavar='path')
parser.add_argument('-l', dest='checklimit',
type=str, default='0',
help='Length of time to check for '
'DNSSEC coverage [default: 0 (unlimited)]',
metavar='time')
parser.add_argument('-z', dest='no_ksk',
action='store_true', default=False,
help='Only check zone-signing keys (ZSKs)')
parser.add_argument('-k', dest='no_zsk',
action='store_true', default=False,
help='Only check key-signing keys (KSKs)')
parser.add_argument('-D', '--debug', dest='debug_mode',
action='store_true', default=False,
help='Turn on debugging output')
@ -655,6 +679,10 @@ def parse_args():
args = parser.parse_args()
if args.no_zsk and args.no_ksk:
print("ERROR: -z and -k cannot be used together.");
exit(1)
# convert from time arguments to seconds
try:
if args.maxttl:
@ -677,6 +705,17 @@ def parse_args():
except:
pass
try:
if args.checklimit:
lim = args.checklimit
r = parse_time(args.checklimit)
if r == 0:
args.checklimit = None
else:
args.checklimit = time.time() + r
except:
pass
# if we've got the values we need from the command line, stop now
if args.maxttl and args.keyttl:
return

View File

@ -105,3 +105,33 @@ zsk2=`$KEYGEN -K $dir -S $zsk1`
# allow only 1 day between publication and activation
$SETTIME -K $dir -P +269d $zsk2 > /dev/null 2>&1
ksk1=`$KEYGEN -K $dir -3fk example.com`
# Test 9: KSK goes inactive before successor is active, but checking ZSKs
dir=09-check-zsk
rm -f $dir/K*.key
rm -f $dir/K*.private
ksk1=`$KEYGEN -K $dir -3fk example.com`
$SETTIME -K $dir -I +9mo -D +1y $ksk1 > /dev/null 2>&1
ksk2=`$KEYGEN -K $dir -S $ksk1`
$SETTIME -K $dir -I +7mo $ksk1 > /dev/null 2>&1
zsk1=`$KEYGEN -K $dir -3 example.com`
# Test 10: ZSK goes inactive before successor is active, but checking KSKs
dir=10-check-ksk
rm -f $dir/K*.key
rm -f $dir/K*.private
zsk1=`$KEYGEN -K $dir -3 example.com`
$SETTIME -K $dir -I +9mo -D +1y $zsk1 > /dev/null 2>&1
zsk2=`$KEYGEN -K $dir -S $zsk1`
$SETTIME -K $dir -I +7mo $zsk1 > /dev/null 2>&1
ksk1=`$KEYGEN -K $dir -3fk example.com`
# Test 11: ZSK goes inactive before successor is active, but after cutoff
dir=11-cutoff
rm -f $dir/K*.key
rm -f $dir/K*.private
zsk1=`$KEYGEN -K $dir -3 example.com`
$SETTIME -K $dir -I +18mo -D +2y $zsk1 > /dev/null 2>&1
zsk2=`$KEYGEN -K $dir -S $zsk1`
$SETTIME -K $dir -I +16mo $zsk1 > /dev/null 2>&1
ksk1=`$KEYGEN -K $dir -3fk example.com`

View File

@ -42,22 +42,38 @@ for dir in [0-9][0-9]-*; do
$COVERAGE $args -K $dir example.com > coverage.$n 2>&1
# check that return code matches expectations
[ $? -eq $retcode ] || ret=1
found=$?
if [ $found -ne $retcode ]; then
echo "retcode was $found expected $retcode"
ret=1
fi
# check for correct number of errors
found=`grep ERROR coverage.$n | wc -l`
[ $found -eq $error ] || ret=1
if [ $found -ne $error ]; then
echo "error count was $found expected $error"
ret=1
fi
# check for correct number of warnings
found=`grep WARNING coverage.$n | wc -l`
[ $found -eq $warn ] || ret=1
if [ $found -ne $warn ]; then
echo "warning count was $found expected $warn"
ret=1
fi
# check for correct number of OKs
found=`grep "No errors found" coverage.$n | wc -l`
[ $found -eq $ok ] || ret=1
if [ $found -ne $ok ]; then
echo "good count was $found expected $ok"
ret=1
fi
found=`matchall coverage.$n "$match"`
[ "$found" = "FAIL" ] && ret=1
if [ "$found" = "FAIL" ]; then
echo "no match on '$match'"
ret=1
fi
n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi