Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19ace9e681 | ||
|
|
e2b027001b | ||
|
|
c9b7857387 |
@@ -30,3 +30,6 @@ ns8 is a caching-only server, configured with unsupported and disabled
|
|||||||
algorithms. It is used for testing failure cases.
|
algorithms. It is used for testing failure cases.
|
||||||
|
|
||||||
ns9 is a forwarding-only server.
|
ns9 is a forwarding-only server.
|
||||||
|
|
||||||
|
ans11 is a mocked authoritative server. Used to simulate broken authoritative
|
||||||
|
server supporting DNSSEC.
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MPL-2.0
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
from isctest.asyncserver import (
|
||||||
|
AsyncDnsServer,
|
||||||
|
DomainHandler,
|
||||||
|
QueryContext,
|
||||||
|
ResponseAction,
|
||||||
|
DnsResponseSend,
|
||||||
|
)
|
||||||
|
from typing import AsyncGenerator
|
||||||
|
import dns
|
||||||
|
|
||||||
|
|
||||||
|
class DnssecManglerHandler(DomainHandler):
|
||||||
|
domains = ["missingdnskey.example."]
|
||||||
|
|
||||||
|
def hide_dnskey(self, qctx: QueryContext) -> None:
|
||||||
|
qctx.response.answer = []
|
||||||
|
|
||||||
|
def add_rrsig(self, qctx: QueryContext) -> None:
|
||||||
|
rrsig = None
|
||||||
|
if qctx.qname == qctx.zone.origin:
|
||||||
|
rrsig = qctx.zone.find_rdataset(
|
||||||
|
qctx.zone.origin, dns.rdatatype.RRSIG, qctx.qtype, True
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
rrsig = qctx.node.get_rdataset(qctx.qclass, dns.rdatatype.RRSIG, True)
|
||||||
|
if rrsig:
|
||||||
|
rrsig_rrset = dns.rrset.RRset(qctx.qname, qctx.qclass, dns.rdatatype.RRSIG)
|
||||||
|
rrsig_rrset.update(rrsig)
|
||||||
|
qctx.response.answer.append(rrsig_rrset)
|
||||||
|
|
||||||
|
async def get_responses(
|
||||||
|
self, qctx: QueryContext
|
||||||
|
) -> AsyncGenerator[ResponseAction, None]:
|
||||||
|
if qctx.qtype == dns.rdatatype.DNSKEY:
|
||||||
|
self.hide_dnskey(qctx)
|
||||||
|
else:
|
||||||
|
self.add_rrsig(qctx)
|
||||||
|
yield DnsResponseSend(qctx.response)
|
||||||
|
|
||||||
|
|
||||||
|
server = AsyncDnsServer()
|
||||||
|
server.install_response_handler(DnssecManglerHandler())
|
||||||
|
server.run()
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
;
|
||||||
|
; SPDX-License-Identifier: MPL-2.0
|
||||||
|
;
|
||||||
|
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
;
|
||||||
|
; See the COPYRIGHT file distributed with this work for additional
|
||||||
|
; information regarding copyright ownership.
|
||||||
|
|
||||||
|
$TTL 300 ; 5 minutes
|
||||||
|
@ IN SOA mname1. . (
|
||||||
|
2000042407 ; serial
|
||||||
|
20 ; refresh (20 seconds)
|
||||||
|
20 ; retry (20 seconds)
|
||||||
|
1814400 ; expire (3 weeks)
|
||||||
|
3600 ; minimum (1 hour)
|
||||||
|
)
|
||||||
|
NS ns
|
||||||
|
MX 10 mx
|
||||||
|
ns A 10.53.0.3
|
||||||
|
a A 10.0.0.1
|
||||||
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MPL-2.0
|
||||||
|
#
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
#
|
||||||
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
|
# shellcheck source=conf.sh
|
||||||
|
. ../../conf.sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo_i "ans11/sign.sh"
|
||||||
|
|
||||||
|
zone=missingdnskey.example.
|
||||||
|
infile=missingdnskey.example.db.in
|
||||||
|
zonefile=missingdnskey.example.db
|
||||||
|
keyname1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone")
|
||||||
|
keyname2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$zone")
|
||||||
|
cat "$infile" "$keyname1.key" "$keyname2.key" >"$zonefile"
|
||||||
|
"$SIGNER" -o "$zone" "$zonefile" >/dev/null
|
||||||
|
|
||||||
|
# AsyncDnsServer expects a file zone name defined as <apexname>.db, so let's
|
||||||
|
# renamed the signed file.
|
||||||
|
mv "$zonefile".signed $zonefile
|
||||||
@@ -177,3 +177,6 @@ rsasha1-1024 NS ns.rsasha1-1024
|
|||||||
ns.rsasha1-1024 A 10.53.0.3
|
ns.rsasha1-1024 A 10.53.0.3
|
||||||
|
|
||||||
dname-at-apex-nsec3 NS ns3
|
dname-at-apex-nsec3 NS ns3
|
||||||
|
|
||||||
|
missingdnskey NS ns.missingdnskey
|
||||||
|
ns.missingdnskey A 10.53.0.11
|
||||||
|
|||||||
@@ -16,8 +16,9 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Sign child zones (served by ns3).
|
# Sign child zones (served by ns3 and ans11).
|
||||||
(cd ../ns3 && $SHELL sign.sh)
|
(cd ../ns3 && $SHELL sign.sh)
|
||||||
|
(cd ../ans11 && $SHELL sign.sh)
|
||||||
|
|
||||||
echo_i "ns2/sign.sh"
|
echo_i "ns2/sign.sh"
|
||||||
|
|
||||||
@@ -69,6 +70,8 @@ for subdomain in digest-alg-unsupported ds-unsupported secure badds \
|
|||||||
cp "../ns3/dsset-$subdomain.example." .
|
cp "../ns3/dsset-$subdomain.example." .
|
||||||
done
|
done
|
||||||
|
|
||||||
|
cp "../ans11/dsset-missingdnskey.example." .
|
||||||
|
|
||||||
# Sign the "example." zone.
|
# Sign the "example." zone.
|
||||||
keyname1=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone -f KSK "$zone")
|
keyname1=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone -f KSK "$zone")
|
||||||
keyname2=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone "$zone")
|
keyname2=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone "$zone")
|
||||||
|
|||||||
@@ -4133,6 +4133,16 @@ n=$((n + 1))
|
|||||||
test "$ret" -eq 0 || echo_i "failed"
|
test "$ret" -eq 0 || echo_i "failed"
|
||||||
status=$((status + ret))
|
status=$((status + ret))
|
||||||
|
|
||||||
|
echo_i "check EDE 9 (Missing DNSKEY) is added when the zone is signed but no DNSKEY is provided ($n)"
|
||||||
|
ret=0
|
||||||
|
dig_with_opts @10.53.0.4 missingdnskey.example SOA >dig.out.ns4.test$n
|
||||||
|
grep "status: SERVFAIL," dig.out.ns4.test$n >/dev/null || ret=1
|
||||||
|
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1
|
||||||
|
grep "; EDE: 9 (DNSKEY Missing): (missingdnskey.example/DNSKEY)" dig.out.ns4.test$n >/dev/null || ret=1
|
||||||
|
n=$((n + 1))
|
||||||
|
test "$ret" -eq 0 || echo_i "failed"
|
||||||
|
status=$((status + ret))
|
||||||
|
|
||||||
# The next two queries ensure that a zone signed with a DNSKEY that the nameserver
|
# The next two queries ensure that a zone signed with a DNSKEY that the nameserver
|
||||||
# has a disabled algorithm match for will yield insecure positive responses.
|
# has a disabled algorithm match for will yield insecure positive responses.
|
||||||
# These trust anchors in ns8 are ignored and so this domain is treated as insecure.
|
# These trust anchors in ns8 are ignored and so this domain is treated as insecure.
|
||||||
|
|||||||
@@ -156,6 +156,8 @@ pytestmark = pytest.mark.extra_artifacts(
|
|||||||
"ns6/optout-tld.db",
|
"ns6/optout-tld.db",
|
||||||
"ns7/split-rrsig.db",
|
"ns7/split-rrsig.db",
|
||||||
"ns7/split-rrsig.db.unsplit",
|
"ns7/split-rrsig.db.unsplit",
|
||||||
|
"ans11/missingdnskey.example.db",
|
||||||
|
"ans11/missingdnskey.example.db.tmp",
|
||||||
"signer/example.db",
|
"signer/example.db",
|
||||||
"signer/example.db.after",
|
"signer/example.db.after",
|
||||||
"signer/example.db.before",
|
"signer/example.db.before",
|
||||||
|
|||||||
@@ -3275,6 +3275,11 @@ proveunsecure(dns_validator_t *val, bool have_ds, bool resume) {
|
|||||||
/* Couldn't complete insecurity proof. */
|
/* Couldn't complete insecurity proof. */
|
||||||
validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed: %s",
|
validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed: %s",
|
||||||
isc_result_totext(result));
|
isc_result_totext(result));
|
||||||
|
|
||||||
|
if (val->type == dns_rdatatype_dnskey && val->rdataset == NULL) {
|
||||||
|
validator_addede(val, DNS_EDE_DNSKEYMISSING, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return DNS_R_NOTINSECURE;
|
return DNS_R_NOTINSECURE;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|||||||
Reference in New Issue
Block a user