mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-09 01:32:05 -04:00
System test for nxdomain-redirect combined with dns64
An AAAA query for a non-existent name into a view that combines nxdomain-redirect with dns64 used to abort named via the DNS64 fallback in query_nodata(). The new module exercises all three documented entry paths into query_redirect(): the authoritative NXDOMAIN path (ns7, tripping INSIST(!is_zone) in query_notfound()), the recursive NCACHENXRRSET path (ns8, tripping REQUIRE in dns_rdataset_first() on a disassociated rdataset), and the synth-from-dnssec path (ns10 validating against ns9's signed root, with a primer A query so the second AAAA reaches query_redirect() via query_coveringnsec()). ns9 serves as a neutral upstream so the cached and synthesized negatives land real NXRRSETs. Assisted-by: Claude:claude-opus-4-7
This commit is contained in:
parent
d61fef7c10
commit
739a067de8
15 changed files with 253 additions and 0 deletions
29
bin/tests/system/redirect/ns10/named.conf.j2
Normal file
29
bin/tests/system/redirect/ns10/named.conf.j2
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// NS10 — validating recursor used to drive the synth-from-dnssec entry
|
||||
// into query_redirect (covering NSEC from ns9 synthesizes NXDOMAIN
|
||||
// locally, then nxdomain-redirect+dns64 hit the same buggy path as ns7).
|
||||
|
||||
options {
|
||||
port @PORT@;
|
||||
listen-on port @PORT@ { 10.53.0.10; };
|
||||
pid-file "named.pid";
|
||||
nxdomain-redirect redirect;
|
||||
dnssec-validation yes;
|
||||
synth-from-dnssec yes;
|
||||
dns64 64:ff9b::/96 {
|
||||
clients { any; };
|
||||
mapped { any; };
|
||||
suffix ::;
|
||||
};
|
||||
};
|
||||
|
||||
include "trusted.conf";
|
||||
|
||||
zone "." {
|
||||
type hint;
|
||||
file "root.hints";
|
||||
};
|
||||
|
||||
zone "redirect" {
|
||||
type primary;
|
||||
file "redirect.db";
|
||||
};
|
||||
5
bin/tests/system/redirect/ns10/redirect.db
Normal file
5
bin/tests/system/redirect/ns10/redirect.db
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
$TTL 300
|
||||
@ IN SOA ns.redirect. admin.redirect. 1 3600 900 604800 86400
|
||||
@ IN NS ns.redirect.
|
||||
ns IN A 10.53.0.10
|
||||
* IN A 203.0.113.1
|
||||
2
bin/tests/system/redirect/ns10/root.hints
Normal file
2
bin/tests/system/redirect/ns10/root.hints
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
. 518400 IN NS a.root-servers.nil.
|
||||
a.root-servers.nil. 518400 IN A 10.53.0.9
|
||||
24
bin/tests/system/redirect/ns7/named.conf.j2
Normal file
24
bin/tests/system/redirect/ns7/named.conf.j2
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// NS7
|
||||
|
||||
options {
|
||||
port @PORT@;
|
||||
listen-on port @PORT@ { 10.53.0.7; };
|
||||
pid-file "named.pid";
|
||||
nxdomain-redirect redirect;
|
||||
dnssec-validation no;
|
||||
dns64 64:ff9b::/96 {
|
||||
clients { any; };
|
||||
mapped { any; };
|
||||
suffix ::;
|
||||
};
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type primary;
|
||||
file "root.db";
|
||||
};
|
||||
|
||||
zone "redirect" {
|
||||
type primary;
|
||||
file "redirect.db";
|
||||
};
|
||||
5
bin/tests/system/redirect/ns7/redirect.db
Normal file
5
bin/tests/system/redirect/ns7/redirect.db
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
$TTL 300
|
||||
@ IN SOA ns.redirect. admin.redirect. 1 3600 900 604800 86400
|
||||
@ IN NS ns.redirect.
|
||||
ns IN A 10.53.0.7
|
||||
* IN A 203.0.113.1
|
||||
3
bin/tests/system/redirect/ns7/root.db
Normal file
3
bin/tests/system/redirect/ns7/root.db
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
. 86400 IN SOA a.root-servers.nil. hostmaster.example.net. 2019022100 1800 900 604800 86400
|
||||
. 518400 IN NS a.root-servers.nil.
|
||||
a.root-servers.nil. 518400 IN A 10.53.0.7
|
||||
19
bin/tests/system/redirect/ns8/named.conf.j2
Normal file
19
bin/tests/system/redirect/ns8/named.conf.j2
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// NS8
|
||||
|
||||
options {
|
||||
port @PORT@;
|
||||
listen-on port @PORT@ { 10.53.0.8; };
|
||||
pid-file "named.pid";
|
||||
nxdomain-redirect redirect;
|
||||
dnssec-validation no;
|
||||
dns64 64:ff9b::/96 {
|
||||
clients { any; };
|
||||
mapped { any; };
|
||||
suffix ::;
|
||||
};
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type hint;
|
||||
file "root.hints";
|
||||
};
|
||||
2
bin/tests/system/redirect/ns8/root.hints
Normal file
2
bin/tests/system/redirect/ns8/root.hints
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
. 518400 IN NS a.root-servers.nil.
|
||||
a.root-servers.nil. 518400 IN A 10.53.0.9
|
||||
20
bin/tests/system/redirect/ns9/named.conf.j2
Normal file
20
bin/tests/system/redirect/ns9/named.conf.j2
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// NS9 — signed-root upstream for ns8 (advisor cached path) and ns10
|
||||
// (synth-from-dnssec path)
|
||||
|
||||
options {
|
||||
port @PORT@;
|
||||
listen-on port @PORT@ { 10.53.0.9; };
|
||||
pid-file "named.pid";
|
||||
dnssec-validation no;
|
||||
recursion no;
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type primary;
|
||||
file "root.db.signed";
|
||||
};
|
||||
|
||||
zone "redirect" {
|
||||
type primary;
|
||||
file "redirect.db";
|
||||
};
|
||||
5
bin/tests/system/redirect/ns9/redirect.db
Normal file
5
bin/tests/system/redirect/ns9/redirect.db
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
$TTL 300
|
||||
@ IN SOA ns.redirect. admin.redirect. 1 3600 900 604800 86400
|
||||
@ IN NS ns.redirect.
|
||||
ns IN A 10.53.0.9
|
||||
* IN A 203.0.113.1
|
||||
3
bin/tests/system/redirect/ns9/root.db.in
Normal file
3
bin/tests/system/redirect/ns9/root.db.in
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
. 86400 IN SOA a.root-servers.nil. hostmaster.example.net. 2019022100 1800 900 604800 86400
|
||||
. 518400 IN NS a.root-servers.nil.
|
||||
a.root-servers.nil. 518400 IN A 10.53.0.9
|
||||
27
bin/tests/system/redirect/ns9/sign.sh
Normal file
27
bin/tests/system/redirect/ns9/sign.sh
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#!/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.
|
||||
|
||||
. ../../conf.sh
|
||||
|
||||
zone=.
|
||||
infile=root.db.in
|
||||
zonefile=root.db
|
||||
|
||||
key1=$($KEYGEN -q -a $DEFAULT_ALGORITHM $zone)
|
||||
key2=$($KEYGEN -q -a $DEFAULT_ALGORITHM -fk $zone)
|
||||
|
||||
cat $infile $key1.key $key2.key >$zonefile
|
||||
|
||||
$SIGNER -P -g -O full -o $zone $zonefile >sign.ns9.root.out
|
||||
|
||||
keyfile_to_static_keys $key2 >../ns10/trusted.conf
|
||||
|
|
@ -20,3 +20,4 @@ cp ns2/example.db.in ns2/example.db
|
|||
cp ns4/example.db.in ns4/example.db
|
||||
(cd ns3 && $SHELL sign.sh)
|
||||
(cd ns5 && $SHELL sign.sh)
|
||||
(cd ns9 && $SHELL sign.sh)
|
||||
|
|
|
|||
102
bin/tests/system/redirect/tests_redirect_dns64.py
Normal file
102
bin/tests/system/redirect/tests_redirect_dns64.py
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
# 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.
|
||||
|
||||
import pytest
|
||||
|
||||
import isctest
|
||||
|
||||
pytestmark = pytest.mark.extra_artifacts(
|
||||
[
|
||||
"dig.out.*",
|
||||
"ns1/K*",
|
||||
"ns1/*.signed",
|
||||
"ns1/dsset-nsec3.",
|
||||
"ns1/dsset-signed.",
|
||||
"ns1/nsec3.db",
|
||||
"ns1/signed.db",
|
||||
"ns2/example.db",
|
||||
"ns2/named.stats",
|
||||
"ns2/redirect.db",
|
||||
"ns3/K*",
|
||||
"ns3/*.signed",
|
||||
"ns3/dsset-nsec3.",
|
||||
"ns3/dsset-signed.",
|
||||
"ns3/nsec3.db",
|
||||
"ns3/signed.db",
|
||||
"ns4/example.db",
|
||||
"ns4/named.stats",
|
||||
"ns5/K*",
|
||||
"ns5/dsset-*",
|
||||
"ns5/*.signed",
|
||||
"ns5/root.db",
|
||||
"ns5/sign.ns5.*",
|
||||
"ns5/signed.db",
|
||||
"ns6/signed.db.signed",
|
||||
"ns9/K*",
|
||||
"ns9/dsset-*",
|
||||
"ns9/root.db",
|
||||
"ns9/root.db.signed",
|
||||
"ns9/sign.ns9.*",
|
||||
"ns10/trusted.conf",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def _no_crash(server, qname):
|
||||
# DO=0 so nxdomain-redirect is not skipped on validated upstream
|
||||
# responses; the documented landing-page deployment serves
|
||||
# non-DNSSEC clients.
|
||||
msg = isctest.query.create(qname, "AAAA", dnssec=False)
|
||||
response = isctest.query.tcp(msg, server.ip)
|
||||
isctest.check.noerror(response)
|
||||
|
||||
|
||||
def _alive(server):
|
||||
msg = isctest.query.create("ns.redirect.", "A", dnssec=False)
|
||||
response = isctest.query.tcp(msg, server.ip)
|
||||
isctest.check.noerror(response)
|
||||
|
||||
|
||||
def test_nxdomain_redirect_dns64_authoritative(ns7):
|
||||
# Direct AAAA to a server that is authoritative for both '.' (NXDOMAIN)
|
||||
# and the redirect zone (wildcard A only). Reproduces the
|
||||
# INSIST(!qctx->is_zone) abort in query_notfound() entered via
|
||||
# authoritative NXDOMAIN.
|
||||
_no_crash(ns7, "no-exist.")
|
||||
_alive(ns7)
|
||||
|
||||
|
||||
def test_nxdomain_redirect_dns64_recursive(ns8):
|
||||
# Recursive resolver: the upstream returns a real NOERROR-empty AAAA
|
||||
# for '*.redirect.', which the resolver caches as NCACHENXRRSET.
|
||||
# Reproduces the REQUIRE(rdataset->methods != NULL) abort in
|
||||
# dns_rdataset_first() reached via the disassociated rdataset on the
|
||||
# second pass through redirect2().
|
||||
_no_crash(ns8, "no-exist.")
|
||||
_alive(ns8)
|
||||
|
||||
|
||||
def test_nxdomain_redirect_dns64_synth_from_dnssec(ns10):
|
||||
# Validating recursor with synth-from-dnssec. Prime the NSEC chain
|
||||
# with an A query (the redirect zone serves a wildcard A, so this
|
||||
# path returns successfully without entering the DNS64 fallback). A
|
||||
# subsequent AAAA query for a different nonexistent name is then
|
||||
# synthesized via query_coveringnsec() and reaches query_redirect()
|
||||
# through the third documented entry. Same downstream bug as the
|
||||
# authoritative path.
|
||||
msg = isctest.query.create("prime.", "A", dnssec=False)
|
||||
response = isctest.query.tcp(msg, ns10.ip)
|
||||
isctest.check.noerror(response)
|
||||
|
||||
_no_crash(ns10, "trigger.")
|
||||
_alive(ns10)
|
||||
|
|
@ -38,6 +38,12 @@ pytestmark = pytest.mark.extra_artifacts(
|
|||
"ns5/sign.ns5.*",
|
||||
"ns5/signed.db",
|
||||
"ns6/signed.db.signed",
|
||||
"ns9/K*",
|
||||
"ns9/dsset-*",
|
||||
"ns9/root.db",
|
||||
"ns9/root.db.signed",
|
||||
"ns9/sign.ns9.*",
|
||||
"ns10/trusted.conf",
|
||||
]
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue