mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
Add support for TSIG in isctest.kasp
For some kasp test we are going to need TSIG based queries to
differentiate between views.
(cherry picked from commit 9cb287afa0
)
This commit is contained in:
@@ -21,6 +21,7 @@ from typing import Dict, List, Optional, Union
|
|||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
|
|
||||||
import dns
|
import dns
|
||||||
|
import dns.tsig
|
||||||
import isctest.log
|
import isctest.log
|
||||||
import isctest.query
|
import isctest.query
|
||||||
|
|
||||||
@@ -29,8 +30,14 @@ DEFAULT_TTL = 300
|
|||||||
NEXT_KEY_EVENT_THRESHOLD = 100
|
NEXT_KEY_EVENT_THRESHOLD = 100
|
||||||
|
|
||||||
|
|
||||||
def _query(server, qname, qtype):
|
def _query(server, qname, qtype, tsig=None):
|
||||||
query = dns.message.make_query(qname, qtype, use_edns=True, want_dnssec=True)
|
query = dns.message.make_query(qname, qtype, use_edns=True, want_dnssec=True)
|
||||||
|
|
||||||
|
if tsig is not None:
|
||||||
|
tsigkey = tsig.split(":")
|
||||||
|
keyring = dns.tsig.Key(tsigkey[1], tsigkey[2], tsigkey[0])
|
||||||
|
query.use_tsig(keyring)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = isctest.query.tcp(query, server.ip, server.ports.dns, timeout=3)
|
response = isctest.query.tcp(query, server.ip, server.ports.dns, timeout=3)
|
||||||
except dns.exception.Timeout:
|
except dns.exception.Timeout:
|
||||||
@@ -554,14 +561,14 @@ class Key:
|
|||||||
return self.path
|
return self.path
|
||||||
|
|
||||||
|
|
||||||
def check_zone_is_signed(server, zone):
|
def check_zone_is_signed(server, zone, tsig=None):
|
||||||
addr = server.ip
|
addr = server.ip
|
||||||
fqdn = f"{zone}."
|
fqdn = f"{zone}."
|
||||||
|
|
||||||
# wait until zone is fully signed
|
# wait until zone is fully signed
|
||||||
signed = False
|
signed = False
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
response = _query(server, fqdn, dns.rdatatype.NSEC)
|
response = _query(server, fqdn, dns.rdatatype.NSEC, tsig=tsig)
|
||||||
if not isinstance(response, dns.message.Message):
|
if not isinstance(response, dns.message.Message):
|
||||||
isctest.log.debug(f"no response for {fqdn} NSEC from {addr}")
|
isctest.log.debug(f"no response for {fqdn} NSEC from {addr}")
|
||||||
elif response.rcode() != dns.rcode.NOERROR:
|
elif response.rcode() != dns.rcode.NOERROR:
|
||||||
@@ -711,13 +718,13 @@ def check_keyrelationships(keys, expected):
|
|||||||
assert key.is_metadata_consistent(status, expect.metadata)
|
assert key.is_metadata_consistent(status, expect.metadata)
|
||||||
|
|
||||||
|
|
||||||
def check_dnssec_verify(server, zone):
|
def check_dnssec_verify(server, zone, tsig=None):
|
||||||
# Check if zone if DNSSEC valid with dnssec-verify.
|
# Check if zone if DNSSEC valid with dnssec-verify.
|
||||||
fqdn = f"{zone}."
|
fqdn = f"{zone}."
|
||||||
|
|
||||||
verified = False
|
verified = False
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
transfer = _query(server, fqdn, dns.rdatatype.AXFR)
|
transfer = _query(server, fqdn, dns.rdatatype.AXFR, tsig=tsig)
|
||||||
if not isinstance(transfer, dns.message.Message):
|
if not isinstance(transfer, dns.message.Message):
|
||||||
isctest.log.debug(f"no response for {fqdn} AXFR from {server.ip}")
|
isctest.log.debug(f"no response for {fqdn} AXFR from {server.ip}")
|
||||||
elif transfer.rcode() != dns.rcode.NOERROR:
|
elif transfer.rcode() != dns.rcode.NOERROR:
|
||||||
@@ -936,8 +943,8 @@ def check_cds(rrset, keys):
|
|||||||
assert numcds == len(cdss)
|
assert numcds == len(cdss)
|
||||||
|
|
||||||
|
|
||||||
def _query_rrset(server, fqdn, qtype):
|
def _query_rrset(server, fqdn, qtype, tsig=None):
|
||||||
response = _query(server, fqdn, qtype)
|
response = _query(server, fqdn, qtype, tsig=tsig)
|
||||||
assert response.rcode() == dns.rcode.NOERROR
|
assert response.rcode() == dns.rcode.NOERROR
|
||||||
|
|
||||||
rrs = []
|
rrs = []
|
||||||
@@ -957,46 +964,46 @@ def _query_rrset(server, fqdn, qtype):
|
|||||||
return rrs, rrsigs
|
return rrs, rrsigs
|
||||||
|
|
||||||
|
|
||||||
def check_apex(server, zone, ksks, zsks):
|
def check_apex(server, zone, ksks, zsks, tsig=None):
|
||||||
# Test the apex of a zone. This checks that the SOA and DNSKEY RRsets
|
# Test the apex of a zone. This checks that the SOA and DNSKEY RRsets
|
||||||
# are signed correctly and with the appropriate keys.
|
# are signed correctly and with the appropriate keys.
|
||||||
fqdn = f"{zone}."
|
fqdn = f"{zone}."
|
||||||
|
|
||||||
# test dnskey query
|
# test dnskey query
|
||||||
dnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.DNSKEY)
|
dnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.DNSKEY, tsig=tsig)
|
||||||
assert len(dnskeys) > 0
|
assert len(dnskeys) > 0
|
||||||
check_dnskeys(dnskeys, ksks, zsks)
|
check_dnskeys(dnskeys, ksks, zsks)
|
||||||
assert len(rrsigs) > 0
|
assert len(rrsigs) > 0
|
||||||
check_signatures(rrsigs, dns.rdatatype.DNSKEY, fqdn, ksks, zsks)
|
check_signatures(rrsigs, dns.rdatatype.DNSKEY, fqdn, ksks, zsks)
|
||||||
|
|
||||||
# test soa query
|
# test soa query
|
||||||
soa, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.SOA)
|
soa, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.SOA, tsig=tsig)
|
||||||
assert len(soa) == 1
|
assert len(soa) == 1
|
||||||
assert f"{zone}. {DEFAULT_TTL} IN SOA" in soa[0].to_text()
|
assert f"{zone}. {DEFAULT_TTL} IN SOA" in soa[0].to_text()
|
||||||
assert len(rrsigs) > 0
|
assert len(rrsigs) > 0
|
||||||
check_signatures(rrsigs, dns.rdatatype.SOA, fqdn, ksks, zsks)
|
check_signatures(rrsigs, dns.rdatatype.SOA, fqdn, ksks, zsks)
|
||||||
|
|
||||||
# test cdnskey query
|
# test cdnskey query
|
||||||
cdnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDNSKEY)
|
cdnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDNSKEY, tsig=tsig)
|
||||||
check_dnskeys(cdnskeys, ksks, zsks, cdnskey=True)
|
check_dnskeys(cdnskeys, ksks, zsks, cdnskey=True)
|
||||||
if len(cdnskeys) > 0:
|
if len(cdnskeys) > 0:
|
||||||
assert len(rrsigs) > 0
|
assert len(rrsigs) > 0
|
||||||
check_signatures(rrsigs, dns.rdatatype.CDNSKEY, fqdn, ksks, zsks)
|
check_signatures(rrsigs, dns.rdatatype.CDNSKEY, fqdn, ksks, zsks)
|
||||||
|
|
||||||
# test cds query
|
# test cds query
|
||||||
cds, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDS)
|
cds, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.CDS, tsig=tsig)
|
||||||
check_cds(cds, ksks)
|
check_cds(cds, ksks)
|
||||||
if len(cds) > 0:
|
if len(cds) > 0:
|
||||||
assert len(rrsigs) > 0
|
assert len(rrsigs) > 0
|
||||||
check_signatures(rrsigs, dns.rdatatype.CDS, fqdn, ksks, zsks)
|
check_signatures(rrsigs, dns.rdatatype.CDS, fqdn, ksks, zsks)
|
||||||
|
|
||||||
|
|
||||||
def check_subdomain(server, zone, ksks, zsks):
|
def check_subdomain(server, zone, ksks, zsks, tsig=None):
|
||||||
# Test an RRset below the apex and verify it is signed correctly.
|
# Test an RRset below the apex and verify it is signed correctly.
|
||||||
fqdn = f"{zone}."
|
fqdn = f"{zone}."
|
||||||
qname = f"a.{zone}."
|
qname = f"a.{zone}."
|
||||||
qtype = dns.rdatatype.A
|
qtype = dns.rdatatype.A
|
||||||
response = _query(server, qname, qtype)
|
response = _query(server, qname, qtype, tsig=tsig)
|
||||||
assert response.rcode() == dns.rcode.NOERROR
|
assert response.rcode() == dns.rcode.NOERROR
|
||||||
|
|
||||||
match = f"{qname} {DEFAULT_TTL} IN A 10.0.0.1"
|
match = f"{qname} {DEFAULT_TTL} IN A 10.0.0.1"
|
||||||
|
Reference in New Issue
Block a user