mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-02 07:35:26 +00:00
3344. [func] New "dnssec-checkds" command checks a zone to
determine which DS records should be published in the parent zone, or which DLV records should be published in a DLV zone, and queries the DNS to ensure that it exists. (Note: This tool depends on python; it will not be built or installed on systems that do not have a python interpreter.) [RT #28099]
This commit is contained in:
2
bin/python/.gitignore
vendored
Normal file
2
bin/python/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
dnssec-checkds
|
||||
dnssec-checkds.py
|
50
bin/python/Makefile.in
Normal file
50
bin/python/Makefile.in
Normal file
@@ -0,0 +1,50 @@
|
||||
# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@BIND9_MAKE_INCLUDES@
|
||||
|
||||
PYTHON = @PYTHON@
|
||||
|
||||
TARGETS = dnssec-checkds
|
||||
SRCS = dnssec-checkds.py
|
||||
|
||||
MANPAGES = dnssec-checkds.8
|
||||
HTMLPAGES = dnssec-checkds.html
|
||||
MANOBJS = ${MANPAGES} ${HTMLPAGES}
|
||||
|
||||
@BIND9_MAKE_RULES@
|
||||
|
||||
dnssec-checkds: ${srcdir}/dnssec-checkds.py
|
||||
cp -f $< $@
|
||||
chmod +x $@
|
||||
|
||||
doc man:: ${MANOBJS}
|
||||
|
||||
docclean manclean maintainer-clean::
|
||||
rm -f ${MANOBJS}
|
||||
|
||||
installdirs:
|
||||
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir}
|
||||
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8
|
||||
|
||||
install:: ${TARGETS} installdirs
|
||||
${INSTALL_PROGRAM} dnssec-checkds@EXEEXT@ ${DESTDIR}${sbindir}
|
||||
${INSTALL_DATA} ${srcdir}/dnssec-checkds.8 ${DESTDIR}${mandir}/man8
|
||||
|
||||
clean distclean::
|
||||
rm -f ${TARGETS}
|
80
bin/python/dnssec-checkds.8
Normal file
80
bin/python/dnssec-checkds.8
Normal file
@@ -0,0 +1,80 @@
|
||||
.\" Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and/or distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
.\" copyright notice and this permission notice appear in all copies.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
.\" PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.hy 0
|
||||
.ad l
|
||||
.\" Title: dnssec\-checkds
|
||||
.\" Author:
|
||||
.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/>
|
||||
.\" Date: April 11, 2012
|
||||
.\" Manual: BIND9
|
||||
.\" Source: BIND9
|
||||
.\"
|
||||
.TH "DNSSEC\-CHECKDS" "8" "April 11, 2012" "BIND9" "BIND9"
|
||||
.\" disable hyphenation
|
||||
.nh
|
||||
.\" disable justification (adjust text to left margin only)
|
||||
.ad l
|
||||
.SH "NAME"
|
||||
dnssec\-dsfromkey \- DNSSEC DS RR generation tool
|
||||
.SH "SYNOPSIS"
|
||||
.HP 15
|
||||
\fBdnssec\-chedkcs\fR [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-f\ \fR\fB\fIfile\fR\fR] [\fB\-d\ \fR\fB\fIdig\ path\fR\fR] [\fB\-D\ \fR\fB\fIdsfromkey\ path\fR\fR] {zone}
|
||||
.HP 17
|
||||
\fBdnssec\-dsfromkey\fR [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-f\ \fR\fB\fIfile\fR\fR] [\fB\-d\ \fR\fB\fIdig\ path\fR\fR] [\fB\-D\ \fR\fB\fIdsfromkey\ path\fR\fR] {zone}
|
||||
.SH "DESCRIPTION"
|
||||
.PP
|
||||
\fBdnssec\-checkds\fR
|
||||
verifies the correctness of Delegation Signer (DS) or DNSSEC Lookaside Validation (DLV) resource records for keys in a specified zone.
|
||||
.SH "OPTIONS"
|
||||
.PP
|
||||
\-f \fIfile\fR
|
||||
.RS 4
|
||||
If a
|
||||
\fBfile\fR
|
||||
is specified, then the zone is read from that file to find the DNSKEY records. If not, then the DNSKEY records for the zone are looked up in the DNS.
|
||||
.RE
|
||||
.PP
|
||||
\-l \fIdomain\fR
|
||||
.RS 4
|
||||
Check for a DLV record in the specified lookaside domain, instead of checking for a DS record in the zone's parent. For example, to check for DLV records for "example.com" in ISC's DLV zone, use:
|
||||
\fBdnssec\-checkds \-l dlv.isc.org example.com\fR
|
||||
.RE
|
||||
.PP
|
||||
\-d \fIdig path\fR
|
||||
.RS 4
|
||||
Specifies a path to a
|
||||
\fBdig\fR
|
||||
binary. Used for testing.
|
||||
.RE
|
||||
.PP
|
||||
\-D \fIdsfromkey path\fR
|
||||
.RS 4
|
||||
Specifies a path to a
|
||||
\fBdnssec\-dsfromkey\fR
|
||||
binary. Used for testing.
|
||||
.RE
|
||||
.SH "SEE ALSO"
|
||||
.PP
|
||||
\fBdnssec\-dsfromkey\fR(8),
|
||||
\fBdnssec\-keygen\fR(8),
|
||||
\fBdnssec\-signzone\fR(8),
|
||||
.SH "AUTHOR"
|
||||
.PP
|
||||
Internet Systems Consortium
|
||||
.SH "COPYRIGHT"
|
||||
Copyright \(co 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
.br
|
145
bin/python/dnssec-checkds.docbook
Normal file
145
bin/python/dnssec-checkds.docbook
Normal file
@@ -0,0 +1,145 @@
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
|
||||
[<!ENTITY mdash "—">]>
|
||||
<!--
|
||||
- Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
-
|
||||
- Permission to use, copy, modify, and/or distribute this software for any
|
||||
- purpose with or without fee is hereby granted, provided that the above
|
||||
- copyright notice and this permission notice appear in all copies.
|
||||
-
|
||||
- THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
- AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
- PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
|
||||
<refentry id="man.dnssec-dsfromkey">
|
||||
<refentryinfo>
|
||||
<date>April 11, 2012</date>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle><application>dnssec-checkds</application></refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
<refmiscinfo>BIND9</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname><application>dnssec-dsfromkey</application></refname>
|
||||
<refpurpose>DNSSEC DS RR generation tool</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<docinfo>
|
||||
<copyright>
|
||||
<year>2012</year>
|
||||
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
|
||||
</copyright>
|
||||
</docinfo>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>dnssec-chedkcs</command>
|
||||
<arg><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
|
||||
<arg><option>-f <replaceable class="parameter">file</replaceable></option></arg>
|
||||
<arg><option>-d <replaceable class="parameter">dig path</replaceable></option></arg>
|
||||
<arg><option>-D <replaceable class="parameter">dsfromkey path</replaceable></option></arg>
|
||||
<arg choice="req">zone</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>dnssec-dsfromkey</command>
|
||||
<arg><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
|
||||
<arg><option>-f <replaceable class="parameter">file</replaceable></option></arg>
|
||||
<arg><option>-d <replaceable class="parameter">dig path</replaceable></option></arg>
|
||||
<arg><option>-D <replaceable class="parameter">dsfromkey path</replaceable></option></arg>
|
||||
<arg choice="req">zone</arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>DESCRIPTION</title>
|
||||
<para><command>dnssec-checkds</command>
|
||||
verifies the correctness of Delegation Signer (DS) or DNSSEC
|
||||
Lookaside Validation (DLV) resource records for keys in a specified
|
||||
zone.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>OPTIONS</title>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>-f <replaceable class="parameter">file</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
If a <option>file</option> is specified, then the zone is
|
||||
read from that file to find the DNSKEY records. If not,
|
||||
then the DNSKEY records for the zone are looked up in the DNS.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-l <replaceable class="parameter">domain</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Check for a DLV record in the specified lookaside domain,
|
||||
instead of checking for a DS record in the zone's parent.
|
||||
For example, to check for DLV records for "example.com"
|
||||
in ISC's DLV zone, use:
|
||||
<command>dnssec-checkds -l dlv.isc.org example.com</command>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-d <replaceable class="parameter">dig path</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specifies a path to a <command>dig</command> binary. Used
|
||||
for testing.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-D <replaceable class="parameter">dsfromkey path</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specifies a path to a <command>dnssec-dsfromkey</command> binary.
|
||||
Used for testing.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>SEE ALSO</title>
|
||||
<para><citerefentry>
|
||||
<refentrytitle>dnssec-dsfromkey</refentrytitle><manvolnum>8</manvolnum>
|
||||
</citerefentry>,
|
||||
<citerefentry>
|
||||
<refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>
|
||||
</citerefentry>,
|
||||
<citerefentry>
|
||||
<refentrytitle>dnssec-signzone</refentrytitle><manvolnum>8</manvolnum>
|
||||
</citerefentry>,
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>AUTHOR</title>
|
||||
<para><corpauthor>Internet Systems Consortium</corpauthor>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</refentry><!--
|
||||
- Local variables:
|
||||
- mode: sgml
|
||||
- End:
|
||||
-->
|
84
bin/python/dnssec-checkds.html
Normal file
84
bin/python/dnssec-checkds.html
Normal file
@@ -0,0 +1,84 @@
|
||||
<!--
|
||||
- Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
-
|
||||
- Permission to use, copy, modify, and/or distribute this software for any
|
||||
- purpose with or without fee is hereby granted, provided that the above
|
||||
- copyright notice and this permission notice appear in all copies.
|
||||
-
|
||||
- THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
- AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
- PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
<!-- $Id$ -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>dnssec-checkds</title>
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
|
||||
<a name="man.dnssec-dsfromkey"></a><div class="titlepage"></div>
|
||||
<div class="refnamediv">
|
||||
<h2>Name</h2>
|
||||
<p><span class="application">dnssec-dsfromkey</span> — DNSSEC DS RR generation tool</p>
|
||||
</div>
|
||||
<div class="refsynopsisdiv">
|
||||
<h2>Synopsis</h2>
|
||||
<div class="cmdsynopsis"><p><code class="command">dnssec-chedkcs</code> [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-f <em class="replaceable"><code>file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>dig path</code></em></code>] [<code class="option">-D <em class="replaceable"><code>dsfromkey path</code></em></code>] {zone}</p></div>
|
||||
<div class="cmdsynopsis"><p><code class="command">dnssec-dsfromkey</code> [<code class="option">-l <em class="replaceable"><code>domain</code></em></code>] [<code class="option">-f <em class="replaceable"><code>file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>dig path</code></em></code>] [<code class="option">-D <em class="replaceable"><code>dsfromkey path</code></em></code>] {zone}</p></div>
|
||||
</div>
|
||||
<div class="refsect1" lang="en">
|
||||
<a name="id2543418"></a><h2>DESCRIPTION</h2>
|
||||
<p><span><strong class="command">dnssec-checkds</strong></span>
|
||||
verifies the correctness of Delegation Signer (DS) or DNSSEC
|
||||
Lookaside Validation (DLV) resource records for keys in a specified
|
||||
zone.
|
||||
</p>
|
||||
</div>
|
||||
<div class="refsect1" lang="en">
|
||||
<a name="id2543430"></a><h2>OPTIONS</h2>
|
||||
<div class="variablelist"><dl>
|
||||
<dt><span class="term">-f <em class="replaceable"><code>file</code></em></span></dt>
|
||||
<dd><p>
|
||||
If a <code class="option">file</code> is specified, then the zone is
|
||||
read from that file to find the DNSKEY records. If not,
|
||||
then the DNSKEY records for the zone are looked up in the DNS.
|
||||
</p></dd>
|
||||
<dt><span class="term">-l <em class="replaceable"><code>domain</code></em></span></dt>
|
||||
<dd><p>
|
||||
Check for a DLV record in the specified lookaside domain,
|
||||
instead of checking for a DS record in the zone's parent.
|
||||
For example, to check for DLV records for "example.com"
|
||||
in ISC's DLV zone, use:
|
||||
<span><strong class="command">dnssec-checkds -l dlv.isc.org example.com</strong></span>
|
||||
</p></dd>
|
||||
<dt><span class="term">-d <em class="replaceable"><code>dig path</code></em></span></dt>
|
||||
<dd><p>
|
||||
Specifies a path to a <span><strong class="command">dig</strong></span> binary. Used
|
||||
for testing.
|
||||
</p></dd>
|
||||
<dt><span class="term">-D <em class="replaceable"><code>dsfromkey path</code></em></span></dt>
|
||||
<dd><p>
|
||||
Specifies a path to a <span><strong class="command">dnssec-dsfromkey</strong></span> binary.
|
||||
Used for testing.
|
||||
</p></dd>
|
||||
</dl></div>
|
||||
</div>
|
||||
<div class="refsect1" lang="en">
|
||||
<a name="id2543526"></a><h2>SEE ALSO</h2>
|
||||
<p><span class="citerefentry"><span class="refentrytitle">dnssec-dsfromkey</span>(8)</span>,
|
||||
<span class="citerefentry"><span class="refentrytitle">dnssec-keygen</span>(8)</span>,
|
||||
<span class="citerefentry"><span class="refentrytitle">dnssec-signzone</span>(8)</span>,
|
||||
</p>
|
||||
</div>
|
||||
<div class="refsect1" lang="en">
|
||||
<a name="id2543560"></a><h2>AUTHOR</h2>
|
||||
<p><span class="corpauthor">Internet Systems Consortium</span>
|
||||
</p>
|
||||
</div>
|
||||
</div></body>
|
||||
</html>
|
274
bin/python/dnssec-checkds.py.in
Normal file
274
bin/python/dnssec-checkds.py.in
Normal file
@@ -0,0 +1,274 @@
|
||||
#!@PYTHON@
|
||||
############################################################################
|
||||
# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
############################################################################
|
||||
|
||||
import argparse
|
||||
import pprint
|
||||
import os
|
||||
|
||||
def shellquote(s):
|
||||
return "'" + s.replace("'", "'\\''") + "'"
|
||||
|
||||
############################################################################
|
||||
# DSRR class:
|
||||
# Delegation Signer (DS) resource record
|
||||
############################################################################
|
||||
class DSRR:
|
||||
hashalgs = {1: 'SHA-1', 2: 'SHA-256', 3: 'GOST'}
|
||||
rrname=''
|
||||
rrclass='IN'
|
||||
rrtype='DS'
|
||||
keyid=None
|
||||
keyalg=None
|
||||
hashalg=None
|
||||
digest=''
|
||||
ttl=0
|
||||
|
||||
def __init__(self, rrtext):
|
||||
if not rrtext:
|
||||
return
|
||||
|
||||
fields = rrtext.split()
|
||||
if len(fields) < 7:
|
||||
return
|
||||
|
||||
self.rrname = fields[0].lower()
|
||||
fields = fields[1:]
|
||||
if fields[0].upper() in ['IN','CH','HS']:
|
||||
self.rrclass = fields[0].upper()
|
||||
fields = fields[1:]
|
||||
else:
|
||||
self.ttl = int(fields[0])
|
||||
self.rrclass = fields[1].upper()
|
||||
fields = fields[2:]
|
||||
|
||||
if fields[0].upper() != 'DS':
|
||||
raise Exception
|
||||
|
||||
self.rrtype = 'DS'
|
||||
self.keyid = int(fields[1])
|
||||
self.keyalg = int(fields[2])
|
||||
self.hashalg = int(fields[3])
|
||||
self.digest = ''.join(fields[4:]).upper()
|
||||
|
||||
def __repr__(self):
|
||||
return('%s %s %s %d %d %d %s' %
|
||||
(self.rrname, self.rrclass, self.rrtype, self.keyid,
|
||||
self.keyalg, self.hashalg, self.digest))
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.__repr__() == other.__repr__()
|
||||
|
||||
############################################################################
|
||||
# DLVRR class:
|
||||
# DNSSEC Lookaside Validation (DLV) resource record
|
||||
############################################################################
|
||||
class DLVRR:
|
||||
hashalgs = {1: 'SHA-1', 2: 'SHA-256', 3: 'GOST'}
|
||||
parent=''
|
||||
dlvname=''
|
||||
rrname='IN'
|
||||
rrclass='IN'
|
||||
rrtype='DLV'
|
||||
keyid=None
|
||||
keyalg=None
|
||||
hashalg=None
|
||||
digest=''
|
||||
ttl=0
|
||||
|
||||
def __init__(self, rrtext, dlvname):
|
||||
if not rrtext:
|
||||
return
|
||||
|
||||
fields = rrtext.split()
|
||||
if len(fields) < 7:
|
||||
return
|
||||
|
||||
self.dlvname = dlvname.lower()
|
||||
parent = fields[0].lower().strip('.').split('.')
|
||||
parent.reverse()
|
||||
dlv = dlvname.split('.')
|
||||
dlv.reverse()
|
||||
while len(dlv) != 0 and len(parent) != 0 and parent[0] == dlv[0]:
|
||||
parent = parent[1:]
|
||||
dlv = dlv[1:]
|
||||
if len(dlv) != 0:
|
||||
raise Exception
|
||||
parent.reverse()
|
||||
self.parent = '.'.join(parent)
|
||||
self.rrname = self.parent + '.' + self.dlvname + '.'
|
||||
|
||||
fields = fields[1:]
|
||||
if fields[0].upper() in ['IN','CH','HS']:
|
||||
self.rrclass = fields[0].upper()
|
||||
fields = fields[1:]
|
||||
else:
|
||||
self.ttl = int(fields[0])
|
||||
self.rrclass = fields[1].upper()
|
||||
fields = fields[2:]
|
||||
|
||||
if fields[0].upper() != 'DLV':
|
||||
raise Exception
|
||||
|
||||
self.rrtype = 'DLV'
|
||||
self.keyid = int(fields[1])
|
||||
self.keyalg = int(fields[2])
|
||||
self.hashalg = int(fields[3])
|
||||
self.digest = ''.join(fields[4:]).upper()
|
||||
|
||||
def __repr__(self):
|
||||
return('%s %s %s %d %d %d %s' %
|
||||
(self.rrname, self.rrclass, self.rrtype,
|
||||
self.keyid, self.keyalg, self.hashalg, self.digest))
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.__repr__() == other.__repr__()
|
||||
|
||||
############################################################################
|
||||
# checkds:
|
||||
# Fetch DS RRset for the given zone from the DNS; fetch DNSKEY
|
||||
# RRset from the masterfile if specified, or from DNS if not.
|
||||
# Generate a set of expected DS records from the DNSKEY RRset,
|
||||
# and report on congruency.
|
||||
############################################################################
|
||||
def checkds(zone, masterfile = None):
|
||||
dslist=[]
|
||||
fp=os.popen("%s +noall +answer -t ds -q %s" %
|
||||
(shellquote(args.dig), shellquote(zone)))
|
||||
for line in fp:
|
||||
dslist.append(DSRR(line))
|
||||
dslist = sorted(dslist, key=lambda ds: (ds.keyid, ds.keyalg, ds.hashalg))
|
||||
fp.close()
|
||||
|
||||
dsklist=[]
|
||||
|
||||
if masterfile:
|
||||
fp = os.popen("%s -f %s %s " %
|
||||
(shellquote(args.dsfromkey), shellquote(masterfile),
|
||||
shellquote(zone)))
|
||||
else:
|
||||
fp = os.popen("%s +noall +answer -t dnskey -q %s | %s -f - %s" %
|
||||
(shellquote(args.dig), shellquote(zone),
|
||||
shellquote(args.dsfromkey), shellquote(zone)))
|
||||
|
||||
for line in fp:
|
||||
dsklist.append(DSRR(line))
|
||||
|
||||
fp.close()
|
||||
|
||||
found = False
|
||||
for ds in dsklist:
|
||||
if ds in dslist:
|
||||
print ("DS for KSK %s/%03d/%05d (%s) found in parent" %
|
||||
(ds.rrname.strip('.'), ds.keyalg,
|
||||
ds.keyid, DSRR.hashalgs[ds.hashalg]))
|
||||
found = True
|
||||
else:
|
||||
print ("No DS records found for KSK %s/%03d/%05d" %
|
||||
(ds.rrname, ds.keyalg, ds.keyid))
|
||||
|
||||
return found
|
||||
|
||||
############################################################################
|
||||
# checkdlv:
|
||||
# Fetch DLV RRset for the given zone from the DNS; fetch DNSKEY
|
||||
# RRset from the masterfile if specified, or from DNS if not.
|
||||
# Generate a set of expected DLV records from the DNSKEY RRset,
|
||||
# and report on congruency.
|
||||
############################################################################
|
||||
def checkdlv(zone, lookaside, masterfile = None):
|
||||
dlvlist=[]
|
||||
fp=os.popen("%s +noall +answer -t dlv -q %s" %
|
||||
(shellquote(args.dig), shellquote(zone + '.' + lookaside)))
|
||||
for line in fp:
|
||||
dlvlist.append(DLVRR(line, lookaside))
|
||||
dlvlist = sorted(dlvlist,
|
||||
key=lambda dlv: (dlv.keyid, dlv.keyalg, dlv.hashalg))
|
||||
fp.close()
|
||||
|
||||
#
|
||||
# Fetch DNSKEY records from DNS and generate DLV records from them
|
||||
#
|
||||
dlvklist=[]
|
||||
if masterfile:
|
||||
fp = os.popen("%s -f %s -l %s %s " %
|
||||
(args.dsfromkey, masterfile, lookaside, zone))
|
||||
else:
|
||||
fp = os.popen("%s +noall +answer -t dnskey %s | %s -f - -l %s %s"
|
||||
% (shellquote(args.dig), shellquote(zone),
|
||||
shellquote(args.dsfromkey), shellquote(lookaside),
|
||||
shellquote(zone)))
|
||||
|
||||
for line in fp:
|
||||
dlvklist.append(DLVRR(line, lookaside))
|
||||
|
||||
fp.close()
|
||||
|
||||
found = False
|
||||
for dlv in dlvklist:
|
||||
if dlv in dlvlist:
|
||||
print ("DLV for KSK %s/%03d/%05d (%s) found in %s" %
|
||||
(dlv.parent, dlv.keyalg, dlv.keyid,
|
||||
DLVRR.hashalgs[dlv.hashalg], dlv.dlvname))
|
||||
found = True
|
||||
else:
|
||||
print ("No DLV records found for KSK %s/%03d/%05d in %s" %
|
||||
(dlv.parent, dlv.keyalg, dlv.keyid, dlv.dlvname))
|
||||
|
||||
return found
|
||||
|
||||
|
||||
############################################################################
|
||||
# parse_args:
|
||||
# Read command line arguments, set global 'args' structure
|
||||
############################################################################
|
||||
def parse_args():
|
||||
global args
|
||||
parser = argparse.ArgumentParser(description='checkds: checks DS coverage')
|
||||
|
||||
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',
|
||||
default='@prefix@/bin/dig', type=str,
|
||||
help='path to \'dig\'')
|
||||
parser.add_argument('-D', '--dsfromkey', dest='dsfromkey',
|
||||
default='@prefix@/sbin/dnssec-dsfromkey', type=str,
|
||||
help='path to \'dig\'')
|
||||
parser.add_argument('-v', '--version', action='version', version='9.9.1')
|
||||
args = parser.parse_args()
|
||||
|
||||
args.zone = args.zone.strip('.')
|
||||
if args.lookaside:
|
||||
lookaside = args.lookaside.strip('.')
|
||||
|
||||
############################################################################
|
||||
# Main
|
||||
############################################################################
|
||||
def main():
|
||||
parse_args()
|
||||
|
||||
if args.lookaside:
|
||||
found = checkdlv(args.zone, args.lookaside, args.masterfile)
|
||||
else:
|
||||
found = checkds(args.zone, args.masterfile)
|
||||
|
||||
exit(0 if found else 1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user