2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 22:45:39 +00:00

[master] dnssec-checkds -s

4794.	[func]		"dnssec-checkds -s" specifies a file from which
			to read a DS set rather than querying the parent.
			[RT #44667]
This commit is contained in:
Evan Hunt
2017-10-26 21:05:11 -07:00
parent 08f18efba2
commit 3b4f23cdbf
10 changed files with 190 additions and 38 deletions

View File

@@ -1,3 +1,7 @@
4794. [func] "dnssec-checkds -s" specifies a file from which
to read a DS set rather than querying the parent.
[RT #44667]
4793. [bug] nsupdate -[46] could overflow the array of server 4793. [bug] nsupdate -[46] could overflow the array of server
addresses. [RT #46402] addresses. [RT #46402]
@@ -317,8 +321,8 @@
4713. [func] Added support for the DNS Response Policy Service 4713. [func] Added support for the DNS Response Policy Service
(DNSRPS) API, which allows named to use an external (DNSRPS) API, which allows named to use an external
response policy daemon when built with response policy daemon when built with
"configure --enable-dnsrps". Thanks to Vernon "configure --enable-dnsrps". Thanks to Farsight
Schryver and Farsight Security. [RT #43376] Security. [RT #43376]
4712. [bug] "dig +domain" and "dig +search" didn't retain the 4712. [bug] "dig +domain" and "dig +search" didn't retain the
search domain when retrying with TCP. [RT #45547] search domain when retrying with TCP. [RT #45547]

View File

@@ -42,20 +42,13 @@
<refsynopsisdiv> <refsynopsisdiv>
<cmdsynopsis sepchar=" "> <cmdsynopsis sepchar=" ">
<command>dnssec-checkds</command> <command>dnssec-checkds</command>
<arg choice="opt" rep="norepeat"><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-f <replaceable class="parameter">file</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-d <replaceable class="parameter">dig path</replaceable></option></arg> <arg choice="opt" rep="norepeat"><option>-d <replaceable class="parameter">dig path</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-D <replaceable class="parameter">dsfromkey path</replaceable></option></arg> <arg choice="opt" rep="norepeat"><option>-D <replaceable class="parameter">dsfromkey path</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-f <replaceable class="parameter">file</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-s <replaceable class="parameter">file</replaceable></option></arg>
<arg choice="req" rep="norepeat">zone</arg> <arg choice="req" rep="norepeat">zone</arg>
</cmdsynopsis> </cmdsynopsis>
<cmdsynopsis sepchar=" ">
<command>dnssec-dsfromkey</command>
<arg choice="opt" rep="norepeat"><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-f <replaceable class="parameter">file</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-d <replaceable class="parameter">dig path</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-D <replaceable class="parameter">dsfromkey path</replaceable></option></arg>
<arg choice="req" rep="norepeat">zone</arg>
</cmdsynopsis>
</refsynopsisdiv> </refsynopsisdiv>
<refsection><info><title>DESCRIPTION</title></info> <refsection><info><title>DESCRIPTION</title></info>
@@ -92,6 +85,17 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>-s <replaceable class="parameter">file</replaceable></term>
<listitem>
<para>
Specifies a prepared dsset file, such as would be generated
by <command>dnssec-signzone</command>, to use as a source for
the DS RRset instead of querying the parent.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term>-d <replaceable class="parameter">dig path</replaceable></term> <term>-d <replaceable class="parameter">dig path</replaceable></term>
<listitem> <listitem>

View File

@@ -34,7 +34,11 @@ class SECRR:
if not rrtext: if not rrtext:
raise Exception raise Exception
fields = rrtext.decode('ascii').split() # 'str' does not have decode method in python3
if type(rrtext) is not str:
fields = rrtext.decode('ascii').split()
else:
fields = rrtext.split()
if len(fields) < 7: if len(fields) < 7:
raise Exception raise Exception
@@ -89,35 +93,39 @@ class SECRR:
# Generate a set of expected DS/DLV records from the DNSKEY RRset, # Generate a set of expected DS/DLV records from the DNSKEY RRset,
# and report on congruency. # and report on congruency.
############################################################################ ############################################################################
def check(zone, args, masterfile=None, lookaside=None): def check(zone, args):
rrlist = [] rrlist = []
cmd = [args.dig, "+noall", "+answer", "-t", "dlv" if lookaside else "ds", if args.dssetfile:
"-q", zone + "." + lookaside if lookaside else zone] fp = open(args.dssetfile).read()
fp, _ = Popen(cmd, stdout=PIPE).communicate() else:
cmd = [args.dig, "+noall", "+answer", "-t",
"dlv" if args.lookaside else "ds", "-q",
zone + "." + args.lookaside if args.lookaside else zone]
fp, _ = Popen(cmd, stdout=PIPE).communicate()
for line in fp.splitlines(): for line in fp.splitlines():
rrlist.append(SECRR(line, lookaside)) rrlist.append(SECRR(line, args.lookaside))
rrlist = sorted(rrlist, key=lambda rr: (rr.keyid, rr.keyalg, rr.hashalg)) rrlist = sorted(rrlist, key=lambda rr: (rr.keyid, rr.keyalg, rr.hashalg))
klist = [] klist = []
if masterfile: if args.masterfile:
cmd = [args.dsfromkey, "-f", masterfile] cmd = [args.dsfromkey, "-f", args.masterfile]
if lookaside: if args.lookaside:
cmd += ["-l", lookaside] cmd += ["-l", args.lookaside]
cmd.append(zone) cmd.append(zone)
fp, _ = Popen(cmd, stdout=PIPE).communicate() fp, _ = Popen(cmd, stdout=PIPE).communicate()
else: else:
intods, _ = Popen([args.dig, "+noall", "+answer", "-t", "dnskey", intods, _ = Popen([args.dig, "+noall", "+answer", "-t", "dnskey",
"-q", zone], stdout=PIPE).communicate() "-q", zone], stdout=PIPE).communicate()
cmd = [args.dsfromkey, "-f", "-"] cmd = [args.dsfromkey, "-f", "-"]
if lookaside: if args.lookaside:
cmd += ["-l", lookaside] cmd += ["-l", args.lookaside]
cmd.append(zone) cmd.append(zone)
fp, _ = Popen(cmd, stdin=PIPE, stdout=PIPE).communicate(intods) fp, _ = Popen(cmd, stdin=PIPE, stdout=PIPE).communicate(intods)
for line in fp.splitlines(): for line in fp.splitlines():
klist.append(SECRR(line, lookaside)) klist.append(SECRR(line, args.lookaside))
if len(klist) < 1: if len(klist) < 1:
print("No DNSKEY records found in zone apex") print("No DNSKEY records found in zone apex")
@@ -136,7 +144,8 @@ def check(zone, args, masterfile=None, lookaside=None):
rr.keyid, SECRR.hashalgs[rr.hashalg])) rr.keyid, SECRR.hashalgs[rr.hashalg]))
if not found: if not found:
print("No %s records were found for any DNSKEY" % ("DLV" if lookaside else "DS")) print("No %s records were found for any DNSKEY" %
("DLV" if args.lookaside else "DS"))
return found return found
@@ -151,10 +160,6 @@ def parse_args():
sbindir = 'bin' if os.name == 'nt' else 'sbin' sbindir = 'bin' if os.name == 'nt' else 'sbin'
parser.add_argument('zone', type=str, help='zone to check') parser.add_argument('zone', type=str, help='zone to check')
parser.add_argument('-f', '--file', dest='masterfile', type=str,
help='zone master file')
parser.add_argument('-l', '--lookaside', dest='lookaside', type=str,
help='DLV lookaside zone')
parser.add_argument('-d', '--dig', dest='dig', parser.add_argument('-d', '--dig', dest='dig',
default=os.path.join(prefix(bindir), 'dig'), default=os.path.join(prefix(bindir), 'dig'),
type=str, help='path to \'dig\'') type=str, help='path to \'dig\'')
@@ -162,6 +167,12 @@ def parse_args():
default=os.path.join(prefix(sbindir), default=os.path.join(prefix(sbindir),
'dnssec-dsfromkey'), 'dnssec-dsfromkey'),
type=str, help='path to \'dig\'') type=str, help='path to \'dig\'')
parser.add_argument('-f', '--file', dest='masterfile', type=str,
help='zone master file')
parser.add_argument('-l', '--lookaside', dest='lookaside', type=str,
help='DLV lookaside zone')
parser.add_argument('-s', '--dsset', dest='dssetfile', type=str,
help='prepared DSset file')
parser.add_argument('-v', '--version', action='version', parser.add_argument('-v', '--version', action='version',
version=version) version=version)
args = parser.parse_args() args = parser.parse_args()
@@ -178,5 +189,5 @@ def parse_args():
############################################################################ ############################################################################
def main(): def main():
args = parse_args() args = parse_args()
found = check(args.zone, args, args.masterfile, args.lookaside) found = check(args.zone, args)
exit(0 if found else 1) exit(0 if found else 1)

View File

@@ -6,7 +6,5 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
# $Id$
rm -f checkds.* rm -f checkds.*
rm -f ns*/named.lock rm -f ns*/named.lock

View File

@@ -6,8 +6,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
# $Id$
my $arg; my $arg;
my $ext; my $ext;
my $file; my $file;

View File

@@ -6,9 +6,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
# $Id$
while [ "$#" != 0 ]; do while [ "$#" != 0 ]; do
case $1 in case $1 in
+*) shift ;; +*) shift ;;

View File

@@ -0,0 +1,121 @@
; File written on Thu Oct 5 23:44:34 2017
; dnssec_signzone version 9.12.0a1
prep.example. 300 IN SOA ns1.prep.example. hostmaster.prep.example. (
1 ; serial
2000 ; refresh (33 minutes 20 seconds)
2000 ; retry (33 minutes 20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
300 RRSIG SOA 8 2 300 (
20171105054434 20171006054434 19260 prep.example.
1fX0z7Swu4gMPews/ZE8bzNg+JXNedFBDGIH
PTSfVQtVLIvRWpME+PylX7MdVMZE/PST+x4/
mWyveyjetEOo7/7aQL236FfI0y6TxQFy7HwC
FMieqoQCUluuKOvToxg4vUp4GOdlUGbqC63h
DbX5Z37VptJXLkt4niF4Kl2iD+U9/bk7HAEU
4zDiKroYnusGKfVB9xAWddzoHdLxhVuPi7ut
328suPdgX0bfs7uB+y4cikhGzAmPpNMlGHju
qYG74NcFGQNutLB7ayx/m87t7mTty7jbNKm3
QWJSPf5IR8/kmzAi8HMnapY5vUmm+hX8JOfU
UtH7i0iEsUqRbEwu5A== )
300 NS ns1.prep.example.
300 RRSIG NS 8 2 300 (
20171105054434 20171006054434 19260 prep.example.
u5sU2cfqNqIyCLw18ZNnFw28/GyRt0EOiPYS
dygmpfMDrvDaxjiiai8zWYjnl/E3qzVH9Zku
07lEDORZdVb0uCDe1NynjAyw4AHps85cAwVc
8HTSbzdVZsQTELpunYFJffh24PDr9unw7KOY
jzTP6qNedJ1uM54TOr177zfmBh7N2fkAoGyV
NjvTKrlgDYGNIn8/YMgHb4sNgyfe54MYY00f
kehVxfKnRCgDsbJ0Pk6jhBMCQWvOh8jG8WyV
ElAa/eMqlxUC1idF8ydWefjsI/7lPcjSalw9
qZw4CDCLHHZy0TOSmCYRRZuIeVXzBfDPJyi4
2A3iLntKFJ4AOLFMJg== )
3600 NSEC ns1.prep.example. NS SOA RRSIG NSEC DNSKEY
3600 RRSIG NSEC 8 2 3600 (
20171105054434 20171006054434 19260 prep.example.
Aed99/jdG82YAkKVWjoKOsAGtB3JnyKkCaAq
zgMrYkXU41y3KDCAmGzooGPQY7NN+WxX7FJ2
1nXkgljma/azgpsbi9ssneFtv7PPFClVmN+u
j+mM4MK/ZR7eJOsMqETg4PAO5VAh6c/GVmyA
RD/m6EhJVZEjPfLWbDoC4hVAgem7DP/NMjyI
GfztpDjMmyLQyv6tL+UEXSJHGp3ZEa5Z5i7X
Nl/bRTUlZs7L4rTgoqHv6LEmsXKAf9rZYq4b
eP6GF9I1Ry41MfHLc7lPUmtR38ErEsM5uGzw
trCQYEFhuRWUBxZ8OSL2EZK9rUBXZX+cwK/8
ZP7mIfDfljkXPQcmow== )
3600 DNSKEY 256 3 8 (
AwEAAfMzj6aZIgZDVcpH1pKOtq998E85+nEY
YJa0lLS8+QTCC1Efke8GLwsXT0IPTuwnOuXM
RjySirab0NuEr69T8KP/43YxcRdmCg89mjjN
szoVPPstC9xBKVOc0pRMDF7sfsTrSye3RY7+
Z6uZEH5FOAkz2hNbJJHOn4HpNUhLPJGRauhf
0evamwUmQ/mlhkVW5q4WmqPCDMNY3K6XtkEm
cvm8n9ZCXC9Z5AX6KpynujzLdKyxpdGqUk6r
lavp9ILPpRKoTZDX+2q1pDgP5cDndwtgNSvU
DBQZoD0psS2cyB3PHo+dPwwpEyM//ZSKsH9m
e85Ti0413TOWFyFd/jUOUA8=
) ; ZSK; alg = RSASHA256 ; key id = 19260
3600 DNSKEY 257 3 8 (
AwEAAbV8X06Qvk350aZ6eZ1d7WbT1H/Y0Sv7
qAdbk5fbYIKpMvZ8D9xqoTHgD0z0uCgWWIcm
/xyKBfmax76oLwMBpR/kdtuJz0irgFITnJCH
pEfR9AJ/Mfm7NyMglq+/39I03E1/LXvpXQLG
tg+Mo/2CUE5sbG31jmPNK/2J8RMESkIi87fW
azZU/oyUEtECE5PGbdyw+4PacAsXNjnwl30T
aatL277wX4pt+IUPdE6EIph3t+dxXJ7OpHgW
8g+YSHLlCImLVapdg3oD/cs6ncaBq9z7la5Y
dHNw2QAIAvQ11EsonrkonPqO6zNVZAVdT2VB
X5YzGAoCFUvbCvlnl2a7SxM=
) ; KSK; alg = RSASHA256 ; key id = 65482
3600 RRSIG DNSKEY 8 2 3600 (
20171105054434 20171006054434 19260 prep.example.
pPw81pJ3PeF+tqEswTul9N8Qsl9JKgK4v8SV
lPfP0pnlMBMbtMFFkx5ZmhQg3Z3U8SdE64Bt
C5St3qItyyKdTQ0Rbm9mfV6twxDB8lVry8F7
Pv7gJmmcWzBcbLGcrXIrVNSZhigkemQXTElj
P8y1j7kaNFWBWbDMn7KesiZ9BiC6sqvuKa3R
wSofjwXTESspWZP0NtXr5ymaBIMR9UtNj5Wh
jm1+tg6BxNBKxhCHlSC0ltPS/qq9J1ZUmtJz
sj/EAFfPVJVuEveebMvi1oDWPTgajO9+EHl4
ELrgnQHCgaybMzbpd/A5+Tr1hQkv48I8Mb0/
8LJ2/6xrvJm64yRteg== )
3600 RRSIG DNSKEY 8 2 3600 (
20171105054434 20171006054434 65482 prep.example.
WeIWiC9SnBe2+UocVjpap62O8Rz+iljwJiu9
VlGUwct3Vydq4/4FVAKdPklXV5cYbBLhO2MB
3R4toX8RNU/0Ny8DnugQzLKvVfg0xoyU/UAJ
k4aWa/vPivSLGouLQPiNp71bdXN4LB/2xmzu
cPYXzS9ePpwCOp/9JLoNjBSMQkfjfWAcaNtj
1DKDmHHL1sPMizninxSJLQOAKb+JwUAjAkOM
O1JqwkB12/IZuzxN5hly+uNsbFFxPzQkcnJ4
5bhzxuh5D/JRXW0nF5aO4aR+9X+lSUpDJQZ1
5fOt1cybZCn/ag68RA92zrnisdbrggJGS003
wn/VKbLVfFj3eQrfNA== )
ns1.prep.example. 300 IN A 1.1.1.1
300 RRSIG A 8 3 300 (
20171105054434 20171006054434 19260 prep.example.
QUyDyJVk3JGEq+VTZtY3firzsRqOA0LUm3Tf
/fnemQBeOlMda2ErA7DqYVriIGfM8jph416E
YX8SKAZXGEAlsEbC9cWBVyc5TYH6tZ43sV51
55kGTiUY92NnrH10Q+m2SLAEEaKCA/cgBwOR
tN2Wb1meHgiLbGYN2LbANfDQzoEk4AYAgT6r
wDKVVg/V9Ed7JnCnBQc9MN9+LQ3h4NBGUiEY
mr7HX2w+yzqcGFNLI1aFPe2IwFt120QPLyyl
cZgc6FUBX4YCnWoCb0aFyyOT76AQkKF5YBRn
gAv6S8q1pZ/0B5w4gjaLEGlts3LG0bxZ1GJd
gCQMEhgYgyXUchTtZA== )
3600 NSEC prep.example. A RRSIG NSEC
3600 RRSIG NSEC 8 3 3600 (
20171105054434 20171006054434 19260 prep.example.
rDWN40u1a3DSzWOrS+4YR2XOxaem0BAQ/glN
QkXNDew1WsZo3fe0IHIhDKlJ/5MJAfAHq8Xs
A5UGUw2efoNAN/0LuWsI/9IPm4dwQOXiTCly
uxugXf5islPYyvn1Z14ay/7/2P3W6HZknXzo
lZFpwqfFZQCxz7c/1aH+2ntAMeqx8LHuewSr
Rz/sLsSiCcZQ6NMWnZdoC5SGy4CTcIIPPS8z
9dQ6QYTC5iq4MKRfyJUyvODyU9be4e6jbo5b
mjRcov4ttbImhD5jrLAZIfjO6DSazGNVFf/x
6rjxjrc8SISPkt2xYwcOlYch9OZuoH86wcZu
3Don6yAnLDYDrZylAA== )

View File

@@ -0,0 +1,2 @@
prep.example. IN DS 65482 8 1 F3673708FBADDEC3EB55933E2E393ACE85EAC2BB
prep.example. IN DS 65482 8 2 51A7C97AAC42803DA515D1CAFEE28031A5018F6345F12F4B6C1B6D20 02B59820

View File

@@ -171,6 +171,15 @@ n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret` status=`expr $status + $ret`
echo "I:checking with prepared dsset file ($n)"
ret=0
$CHECKDS -f prep.example.db -s prep.example.ds.db prep.example > checkds.out.$n || ret=1
grep 'SHA-1.*found' checkds.out.$n > /dev/null 2>&1 || ret=1
grep 'SHA-256.*found' checkds.out.$n > /dev/null 2>&1 || ret=1
n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
if [ $status = 0 ]; then $SHELL clean.sh; fi if [ $status = 0 ]; then $SHELL clean.sh; fi
echo "I:exit status: $status" echo "I:exit status: $status"
[ $status -eq 0 ] || exit 1 [ $status -eq 0 ] || exit 1

View File

@@ -449,6 +449,14 @@
<command>dnssec-settime</command>, etc. [RT #46149] <command>dnssec-settime</command>, etc. [RT #46149]
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<command>dnssec-checkds -s</command> specifies a file from
which to read a DS set rather than querying the parent zone.
This can be used to check zone correctness prior to
publication. Thanks to Niall O'Reilly [RT #44667]
</para>
</listitem>
</itemizedlist> </itemizedlist>
</section> </section>