2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 15:45:25 +00:00

[master] dnssec-keymgr

4349.   [contrib]       kasp2policy: A python script to create a DNSSEC
                        policy file from an OpenDNSSEC KASP XML file.

4348.	[func]		dnssec-keymgr: A new python-based DNSSEC key
			management utility, which reads a policy definition
			file and can create or update DNSSEC keys as needed
			to ensure that a zone's keys match policy, roll over
			correctly on schedule, etc.  Thanks to Sebastian
			Castro for assistance in development. [RT #39211]
This commit is contained in:
Evan Hunt
2016-04-28 00:12:33 -07:00
parent 16591ba9ae
commit f6096b958c
88 changed files with 4686 additions and 1129 deletions

View File

@@ -0,0 +1,33 @@
# Copyright (C) 2015 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@
PYTESTS = dnskey_test.py policy_test.py
@BIND9_MAKE_RULES@
check test:
for test in $(PYTESTS); do \
$(PYTHON) $$test; \
done
clean distclean::
rm -f *.pyc

View File

@@ -0,0 +1,57 @@
############################################################################
# Copyright (C) 2013-2015 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 sys
import unittest
sys.path.append('../..')
from isc import *
kdict = None
def getkey():
global kdict
if not kdict:
kd = keydict(path='testdata')
for key in kd:
return key
class DnskeyTest(unittest.TestCase):
def test_metdata(self):
key = getkey()
self.assertEqual(key.created(), 1448055647)
self.assertEqual(key.publish(), 1445463714)
self.assertEqual(key.activate(), 1448055714)
self.assertEqual(key.revoke(), 1479591714)
self.assertEqual(key.inactive(), 1511127714)
self.assertEqual(key.delete(), 1542663714)
self.assertEqual(key.syncpublish(), 1442871714)
self.assertEqual(key.syncdelete(), 1448919714)
def test_fmttime(self):
key = getkey()
self.assertEqual(key.getfmttime('Created'), '20151120214047')
self.assertEqual(key.getfmttime('Publish'), '20151021214154')
self.assertEqual(key.getfmttime('Activate'), '20151120214154')
self.assertEqual(key.getfmttime('Revoke'), '20161119214154')
self.assertEqual(key.getfmttime('Inactive'), '20171119214154')
self.assertEqual(key.getfmttime('Delete'), '20181119214154')
self.assertEqual(key.getfmttime('SyncPublish'), '20150921214154')
self.assertEqual(key.getfmttime('SyncDelete'), '20151130214154')
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,90 @@
############################################################################
# Copyright (C) 2013-2015 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 sys
import unittest
sys.path.append('../..')
from isc import *
class PolicyTest(unittest.TestCase):
def test_keysize(self):
pol = policy.dnssec_policy()
pol.load('test-policies/01-keysize.pol')
p = pol.policy('good_rsa.test', novalidate=True)
self.assertEqual(p.get_name(), "good_rsa.test")
self.assertEqual(p.constructed(), False)
self.assertEqual(p.validate(), (True, ""))
p = pol.policy('good_dsa.test', novalidate=True)
self.assertEqual(p.get_name(), "good_dsa.test")
self.assertEqual(p.constructed(), False)
self.assertEqual(p.validate(), (True, ""))
p = pol.policy('bad_dsa.test', novalidate=True)
self.assertEqual(p.validate(),
(False, 'ZSK key size 769 not divisible by 64 as required for DSA'))
def test_prepublish(self):
pol = policy.dnssec_policy()
pol.load('test-policies/02-prepublish.pol')
p = pol.policy('good_prepublish.test', novalidate=True)
self.assertEqual(p.validate(), (True, ""))
p = pol.policy('bad_prepublish.test', novalidate=True)
self.assertEqual(p.validate(),
(False, 'KSK pre/post-publish periods '
'(10368000/5184000) combined exceed '
'rollover period 10368000'))
def test_postpublish(self):
pol = policy.dnssec_policy()
pol.load('test-policies/03-postpublish.pol')
p = pol.policy('good_postpublish.test', novalidate=True)
self.assertEqual(p.validate(), (True, ""))
p = pol.policy('bad_postpublish.test', novalidate=True)
self.assertEqual(p.validate(),
(False, 'KSK pre/post-publish periods '
'(10368000/5184000) combined exceed '
'rollover period 10368000'))
def test_combined_pre_post(self):
pol = policy.dnssec_policy()
pol.load('test-policies/04-combined-pre-post.pol')
p = pol.policy('good_combined_pre_post_ksk.test', novalidate=True)
self.assertEqual(p.validate(), (True, ""))
p = pol.policy('bad_combined_pre_post_ksk.test', novalidate=True)
self.assertEqual(p.validate(),
(False, 'KSK pre/post-publish periods '
'(5184000/5184000) combined exceed '
'rollover period 10368000'))
p = pol.policy('good_combined_pre_post_zsk.test', novalidate=True)
self.assertEqual(p.validate(),
(True, ""))
p = pol.policy('bad_combined_pre_post_zsk.test', novalidate=True)
self.assertEqual(p.validate(),
(False, 'ZSK pre/post-publish periods '
'(5184000/5184000) combined exceed '
'rollover period 7776000'))
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,41 @@
policy keysize_rsa {
algorithm rsasha1;
coverage 1y;
roll-period zsk 3mo;
pre-publish zsk 2w;
post-publish zsk 2w;
roll-period ksk 1y;
pre-publish ksk 1mo;
post-publish ksk 2mo;
keyttl 1h;
key-size ksk 2048;
key-size zsk 1024;
};
policy keysize_dsa {
algorithm dsa;
coverage 1y;
key-size ksk 2048;
key-size zsk 1024;
};
zone good_rsa.test {
policy keysize_rsa;
};
zone bad_rsa.test {
policy keysize_rsa;
key-size ksk 511;
};
zone good_dsa.test {
policy keysize_dsa;
key-size ksk 1024;
key-size zsk 768;
};
zone bad_dsa.test {
policy keysize_dsa;
key-size ksk 1024;
key-size zsk 769;
};

View File

@@ -0,0 +1,31 @@
policy prepublish_rsa {
algorithm rsasha1;
coverage 1y;
roll-period zsk 3mo;
pre-publish zsk 2w;
post-publish zsk 2w;
roll-period ksk 1y;
pre-publish ksk 1mo;
post-publish ksk 2mo;
keyttl 1h;
key-size ksk 2048;
key-size zsk 1024;
};
// Policy that defines a pre-publish period lower than the rollover period
zone good_prepublish.test {
policy prepublish_rsa;
coverage 6mo;
roll-period ksk 4mo;
pre-publish ksk 1mo;
};
// Policy that defines a pre-publish period equal to the rollover period
zone bad_prepublish.test {
policy prepublish_rsa;
coverage 6mo;
roll-period ksk 4mo;
pre-publish ksk 4mo;
};

View File

@@ -0,0 +1,31 @@
policy postpublish_rsa {
algorithm rsasha1;
coverage 1y;
roll-period zsk 3mo;
pre-publish zsk 2w;
post-publish zsk 2w;
roll-period ksk 1y;
pre-publish ksk 1mo;
post-publish ksk 2mo;
keyttl 1h;
key-size ksk 2048;
key-size zsk 1024;
};
// Policy that defines a post-publish period lower than the rollover period
zone good_postpublish.test {
policy postpublish_rsa;
coverage 6mo;
roll-period ksk 4mo;
pre-publish ksk 1mo;
};
// Policy that defines a post-publish period equal to the rollover period
zone bad_postpublish.test {
policy postpublish_rsa;
coverage 6mo;
roll-period ksk 4mo;
pre-publish ksk 4mo;
};

View File

@@ -0,0 +1,55 @@
policy combined_pre_post_rsa {
algorithm rsasha1;
coverage 1y;
roll-period zsk 3mo;
pre-publish zsk 2w;
post-publish zsk 2w;
roll-period ksk 1y;
pre-publish ksk 1mo;
post-publish ksk 2mo;
keyttl 1h;
key-size ksk 2048;
key-size zsk 1024;
};
// Policy that defines a combined pre-publish and post-publish period lower
// than the rollover period
zone good_combined_pre_post_ksk.test {
policy combined_pre_post_rsa;
coverage 6mo;
roll-period ksk 4mo;
pre-publish ksk 1mo;
post-publish ksk 1mo;
};
// Policy that defines a combined pre-publish and post-publish period higher
// than the rollover period
zone bad_combined_pre_post_ksk.test {
policy combined_pre_post_rsa;
coverage 6mo;
roll-period ksk 4mo;
pre-publish ksk 2mo;
post-publish ksk 2mo;
};
// Policy that defines a combined pre-publish and post-publish period lower
// than the rollover period
zone good_combined_pre_post_zsk.test {
policy combined_pre_post_rsa;
coverage 1y;
roll-period zsk 3mo;
pre-publish zsk 1mo;
post-publish zsk 1mo;
};
// Policy that defines a combined pre-publish and post-publish period higher
// than the rollover period
zone bad_combined_pre_post_zsk.test {
policy combined_pre_post_rsa;
coverage 1y;
roll-period zsk 3mo;
pre-publish zsk 2mo;
post-publish zsk 2mo;
};

View File

@@ -0,0 +1,8 @@
; This is a key-signing key, keyid 35529, for example.com.
; Created: 20151120214047 (Fri Nov 20 13:40:47 2015)
; Publish: 20151021214154 (Wed Oct 21 14:41:54 2015)
; Activate: 20151120214154 (Fri Nov 20 13:41:54 2015)
; Revoke: 20161119214154 (Sat Nov 19 13:41:54 2016)
; Inactive: 20171119214154 (Sun Nov 19 13:41:54 2017)
; Delete: 20181119214154 (Mon Nov 19 13:41:54 2018)
example.com. IN DNSKEY 257 3 7 AwEAAbbJK96tY8d4sF6RLxh9SVIhho5s2ZhrcijT5j1SNLECen7QLutj VJPEiG8UgBLaJSGkxPDxOygYv4hwh4JXBSj89o9rNabAJtCa9XzIXSpt /cfiCfvqmcOZb9nepmDCXsC7gn/gbae/4Y5ym9XOiCp8lu+tlFWgRiJ+ kxDGN48rRPrGfpq+SfwM9NUtftVa7B0EFVzDkADKedRj0SSGYOqH+WYH CnWjhPFmgJoAw3/m4slTHW1l+mDwFvsCMjXopg4JV0CNnTybnOmyuIwO LWRhB3q8ze24sYBU1fpE9VAMxZ++4Kqh/2MZFeDAs7iPPKSmI3wkRCW5 pkwDLO5lJ9c=

View File

@@ -0,0 +1,18 @@
Private-key-format: v1.3
Algorithm: 7 (NSEC3RSASHA1)
Modulus: tskr3q1jx3iwXpEvGH1JUiGGjmzZmGtyKNPmPVI0sQJ6ftAu62NUk8SIbxSAEtolIaTE8PE7KBi/iHCHglcFKPz2j2s1psAm0Jr1fMhdKm39x+IJ++qZw5lv2d6mYMJewLuCf+Btp7/hjnKb1c6IKnyW762UVaBGIn6TEMY3jytE+sZ+mr5J/Az01S1+1VrsHQQVXMOQAMp51GPRJIZg6of5ZgcKdaOE8WaAmgDDf+biyVMdbWX6YPAW+wIyNeimDglXQI2dPJuc6bK4jA4tZGEHerzN7bixgFTV+kT1UAzFn77gqqH/YxkV4MCzuI88pKYjfCREJbmmTAMs7mUn1w==
PublicExponent: AQAB
PrivateExponent: jfiM6YU1Rd6Y5qrPsK7HP1Ko54DmNbvmzI1hfGmYYZAyQsNCXjQloix5aAW9QGdNhecrzJUhxJAMXFZC+lrKuD5a56R25JDE1Sw21nft3SHXhuQrqw5Z5hIMTWXhRrBR1lMOFnLj2PJxqCmenp+vJYjl1z20RBmbv/keE15SExFRJIJ3G0lI4V0KxprY5rgsT/vID0pS32f7rmXhgEzyWDyuxceTMidBooD5BSeEmSTYa4rvCVZ2vgnzIGSxjYDPJE2rGve2dpvdXQuujRFaf4+/FzjaOgg35rTtUmC9klfB4D6KJIfc1PNUwcH7V0VJ2fFlgZgMYi4W331QORl9sQ==
Prime1: 479rW3EeoBwHhUKDy5YeyfnMKjhaosrcYhW4resevLzatFrvS/n2KxJnsHoEzmGr2A13naI61RndgVBBOwNDWI3/tQ+aKvcr+V9m4omROV3xYa8s1FsDbEW0Z6G0UheaqRFir8WK98/Lj6Zht1uBXHSPPf91OW0qj+b5gbX7TK8=
Prime2: zXXlxgIq+Ih6kxsUw4Ith0nd/d2P3d42QYPjxYjsg4xYicPAjva9HltnbBQ2lr4JEG9Yyb8KalSnJUSuvXtn7bGfBzLu8W6omCeVWXQVH4NIu9AjpO16NpMKWGRfiHHbbSYJs1daTZKHC2FEmi18MKX/RauHGGOakFQ/3A/GMVk=
Exponent1: 0o9UQ1uHNAIWFedUEHJ/jr7LOrGVYnLpZCmu7+S0K0zzatGz8ets44+FnAyDywdUKFDzKSMm/4SFXRwE4vl2VzYZlp2RLG4PEuRYK9OCF6a6F1UsvjxTItQjIbjIDSnTjMINGnMps0lDa1EpgKsyI3eEQ46eI3TBZ//k6D6G0vM=
Exponent2: d+CYJgXRyJzo17fvT3s+0TbaHWsOq+chROyNEw4m4UIbzpW2XjO8eF/gYgERMLbEVyCAb4XVr+CgfXArfEbqhpciMHMZUyi7mbtOupiuUmqpH1v70Bj3O6xjVtuJmfTEkFSnSEppV+VsgclI26Q6V7Ai1yWTdzl2T0u4zs8tVlE=
Coefficient: E4EYw76gIChdQDn6+Uh44/xH9Uwmvq3OETR8w/kEZ0xQ8AkTdKFKUp84nlR6gN+ljb2mUxERKrVLwnBsU8EbUlo9UccMbBGkkZ/8MyfGCBb9nUyOFtOxdHY2M0MQadesRptXHt/m30XjdohwmT7qfSIENwtgUOHbwFnn7WPMc/k=
Created: 20151120214047
Publish: 20151021214154
Activate: 20151120214154
Revoke: 20161119214154
Inactive: 20171119214154
Delete: 20181119214154
SyncPublish: 20150921214154
SyncDelete: 20151130214154