+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]
<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>
<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>
</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>
</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>
# 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
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)
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")
-
- 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_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")
+
+ 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'" %
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')
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:
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
# 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`
$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