Skip to content
Snippets Groups Projects
Commit 4f35a14d authored by Jan Včelák's avatar Jan Včelák :rocket:
Browse files

DNSSEC tests: key lifetime timestamps functionality checks

refs #220
parent bd9804c0
No related branches found
No related tags found
No related merge requests found
$TTL 1h
$ORIGIN example.com.
@ SOA ns.example.com. admin.example.com. 1 60 60 2419200 3600
NS ns.example.com.
A 10.0.0.1
ns A 10.0.0.2
www A 10.0.0.3
example.com. IN DNSKEY 256 3 7 AwEAAaEKJNHrzrCitxCNzya1FMoXjfcwEFGELa1SvJFHYMqsvkaFtpkj BvGsOf24263lP/sINDtcZqbPZ3Z/VHM/j3s=
Private-key-format: v1.3
Algorithm: 7 (NSEC3RSASHA1)
Modulus: oQok0evOsKK3EI3PJrUUyheN9zAQUYQtrVK8kUdgyqy+RoW2mSMG8aw5/bjbreU/+wg0O1xmps9ndn9Ucz+Pew==
PublicExponent: AQAB
PrivateExponent: Mhw+8tdmnI41WsBVylykmHIV6eoZ2dPAhuNs6+QDGW2C5IYTefTllC5GdHS68DjsP67oUEqTnPZI61oHtsi6WQ==
Prime1: 0gsSz0cU8A0xQ88aQbHOi3eZEXvtoj0LecrbIy+ACI8=
Prime2: xEZIYq6Bb2rnNqwDLH7FRAphY88mnKZmMbbNSoyjyFU=
Exponent1: wEgI2R3OSg8ZqWS/OaKnXT+ILdxQZ3QQvFb7ExPZ1ns=
Exponent2: qGnOLq6h7aKDJsxOJN3aEln92xCihwPY6It8d51Z48k=
Coefficient: YeNurpSYJlSuE5IebVebybzRcDrrZpHD5kueq1SMzg0=
Created: 19700101000001
Publish: 19700101000001
Activate: 19700101000001
; This is a zone-signing key, keyid 55574, for example.com.
example.com. IN DNSKEY 256 3 7 AwEAAcm6ymueOZwLH7LvZkWLsk4NFplKrj9jCMBwgkRRwU1+8faMbo+/ Ml7QmYIWY5vhkpevfJDAcJtFf9iWxqQKYA8=
Private-key-format: v1.3
Algorithm: 7 (NSEC3RSASHA1)
Modulus: ybrKa545nAsfsu9mRYuyTg0WmUquP2MIwHCCRFHBTX7x9oxuj78yXtCZghZjm+GSl698kMBwm0V/2JbGpApgDw==
PublicExponent: AQAB
PrivateExponent: dW38w2TZ2FJJY5okiLtnUjQgQZ/NiyyVPaDA1BBbXEZO4HcktrWgwYengmVVLBhKw4OJAhyEHaxYw9DLqLlyAQ==
Prime1: 6NqaRS0mkuHiO2J+4XTCRzMVw3Bu+K88BfqFIkDQKoE=
Prime2: 3cgseuq7yfGAKcu07fOoTP3ITYxYPo+GZJ8TN0Rdoo8=
Exponent1: FmJNSjEY8C2+ra6+O7YZpvaGNQ9t24Ic5wY6HhzU5gE=
Exponent2: 0XCyILn/8WtxPwcyq+wIKf0X5bP9ucbMgcV/3hdf3Z0=
Coefficient: j7PtdA139xlQPVPB3OIoG5YENxin+ocOYp7/teH4xkk=
Created: 19700101000001
Publish: 20400101000000
Activate: 20400101000000
#!/usr/bin/env python3
"""
Check if DNSKEY lifetime timestamps are proccessed correctly by Knot.
"""
import dnstest
import dns
import collections
import os
import re
import shutil
import sys
# patched Knot class, enabling DNSSEC
class DnssecEnabledKnot(dnstest.Knot):
@property
def keydir(self):
return os.path.join(self.dir, "keys")
def get_config(self):
config = super().get_config()
# enable DNSSEC
config = re.sub(r'(\bzones\s+{\n)',
r'\1\tdnssec-keydir "%s";'
r'\n\tdnssec-enable on;\n\n' % self.keydir,
config)
return config
# change timestamps in DNSSEC key file
def key_settime(filename, **new_values):
lines = open(filename).readlines()
values = collections.OrderedDict()
for line in lines:
key, sep, value = line.partition(":")
values[key.strip()] = value.strip()
for key, value in new_values.items():
values[key] = value
with open(filename, "w") as keyfile:
for key, value in values.items():
if value is not None:
keyfile.write("%s: %s\n" % (key, value))
# check number of records of given type in DNS answer
def answer_count(response, rrtype):
for rrset in response.answer:
if rrset.rdtype == rrtype:
return len(rrset)
else:
return 0
# check zone if keys are present and used for signing
def check_zone(server, expect_dnskey, expect_rrsig):
dnskeys = server.dig("example.com", "DNSKEY")
soa = server.dig("example.com", "SOA", dnssec=True)
found_dnskeys = answer_count(dnskeys.resp, dns.rdatatype.DNSKEY)
found_rrsigs = answer_count(soa.resp, dns.rdatatype.RRSIG)
expect_dnskeys = 2 if expect_dnskey else 1
expect_rrsigs = 2 if expect_rrsig else 1
dnstest.detail_log("DNSKEYs: %d (expected %d) RRSIGs: %d (expected %d)" % (
found_dnskeys, expect_dnskeys, found_rrsigs, expect_rrsigs));
if found_dnskeys != expect_dnskeys or found_rrsigs != expect_rrsigs:
dnstest.err("Expectations do not match.")
dnstest.set_err("DNSKEYs not published and activated as expected.")
# Ugly Monkey patch
dnstest.Knot = DnssecEnabledKnot
t = dnstest.DnsTest()
knot = t.server("knot")
zone = t.zone("example.com.", "example.com.zone")
t.link(zone, knot)
# install keys (one always enabled, one for testing)
shutil.copytree(os.path.join(t.data_dir, "keys"), knot.keydir)
# parameters
key_file = os.path.join(knot.keydir, "test.private")
date_past = "19700101000001"
date_future = "20400101000000"
WAIT_SIGN = 0
#
# Common cases
#
# key not published, not active
key_settime(key_file, Publish=date_future, Activate=date_future)
t.start()
t.sleep(WAIT_SIGN)
check_zone(knot, False, False)
# key published, not active
key_settime(key_file, Publish=date_past)
knot.reload()
t.sleep(WAIT_SIGN)
check_zone(knot, True, False)
# key published, active
key_settime(key_file, Activate=date_past)
knot.reload()
t.sleep(WAIT_SIGN)
check_zone(knot, True, True)
# key published, inactive
key_settime(key_file, Inactive=date_past)
knot.reload()
t.sleep(WAIT_SIGN)
check_zone(knot, True, False)
# key deleted, inactive
key_settime(key_file, Delete=date_past)
knot.reload()
t.sleep(WAIT_SIGN)
check_zone(knot, False, False)
#
# Special cases
#
# key not published, active (algorithm rotation)
key_settime(key_file, Publish=date_future, Activate=date_past, Inactive=None, Delete=None)
knot.reload()
t.sleep(WAIT_SIGN)
check_zone(knot, False, True)
t.end()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment