Merge branch '4528-honor-listen-on-changes-v9.18' into 'bind-9.18'

[9.18] Recreate listeners on DNS transport change

See merge request isc-projects/bind9!8652
This commit is contained in:
Artem Boldariev
2024-01-15 13:07:55 +00:00
16 changed files with 445 additions and 21 deletions

View File

@@ -1,3 +1,9 @@
6322. [bug] Changes to "listen-on" statements were ignored on
reconfiguration unless the port or interface address was
changed, making it impossible to change a related
listener transport type. Thanks to Thomas Amgarten.
[GL #4518] [GL #4528]
6320. [bug] Fix a possible crash in 'dig +nssearch +nofail' and
'host -C' commands when one of the name servers returns
SERVFAIL. [GL #4508]

View File

@@ -0,0 +1,24 @@
#!/bin/sh
# 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.
#
# Clean up after zone transfer tests.
#
rm -f ./*/named.conf
rm -f ./*/named.memstats
rm -f ./*/named.run
rm -f ./*/named.run.prev
rm -f ./dig.out.*
rm -f ./*/example.db
rm -rf ./headers.*

View File

@@ -0,0 +1,45 @@
/*
* 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.
*/
include "../../_common/rndc.key";
controls {
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
tls self-signed {
cert-file "../self-signed-cert.pem";
key-file "../self-signed-key.pem";
};
options {
pid-file "named.pid";
##
# generic
listen-on port @PORT@ { 10.53.0.1; };
# test TLS
listen-on port @EXTRAPORT1@ tls none http default { 10.53.0.1; };
listen-on-v6 port @EXTRAPORT1@ tls none http default { fd92:7065:b8e:ffff::1; };
##
recursion no;
notify explicit;
statistics-file "named.stats";
dnssec-validation yes;
tcp-initial-timeout 1200;
};
zone "example" {
type primary;
file "example.db";
allow-transfer { any; };
};

View File

@@ -0,0 +1,45 @@
/*
* 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.
*/
include "../../_common/rndc.key";
controls {
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
tls self-signed {
cert-file "../self-signed-cert.pem";
key-file "../self-signed-key.pem";
};
options {
pid-file "named.pid";
##
# generic
listen-on port @PORT@ { 10.53.0.1; };
# test TLS
listen-on port @EXTRAPORT1@ tls self-signed http default { 10.53.0.1; };
listen-on-v6 port @EXTRAPORT1@ tls self-signed http default { fd92:7065:b8e:ffff::1; };
##
recursion no;
notify explicit;
statistics-file "named.stats";
dnssec-validation yes;
tcp-initial-timeout 1200;
};
zone "example" {
type primary;
file "example.db";
allow-transfer { any; };
};

View File

@@ -0,0 +1,45 @@
/*
* 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.
*/
include "../../_common/rndc.key";
controls {
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
tls self-signed {
cert-file "../self-signed-cert.pem";
key-file "../self-signed-key.pem";
};
options {
pid-file "named.pid";
##
# generic
listen-on port @PORT@ { 10.53.0.1; };
# test TLS
listen-on port @EXTRAPORT1@ tls self-signed { 10.53.0.1; };
listen-on-v6 port @EXTRAPORT1@ tls self-signed { fd92:7065:b8e:ffff::1; };
##
recursion no;
notify explicit;
statistics-file "named.stats";
dnssec-validation yes;
tcp-initial-timeout 1200;
};
zone "example" {
type primary;
file "example.db";
allow-transfer { any; };
};

View File

@@ -0,0 +1,45 @@
/*
* 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.
*/
include "../../_common/rndc.key";
controls {
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
tls self-signed {
cert-file "../self-signed-cert.pem";
key-file "../self-signed-key.pem";
};
options {
pid-file "named.pid";
##
# generic
listen-on port @PORT@ { 10.53.0.1; };
# test
listen-on port @EXTRAPORT1@ { 10.53.0.1; };
listen-on-v6 port @EXTRAPORT1@ { fd92:7065:b8e:ffff::1; };
##
recursion no;
notify explicit;
statistics-file "named.stats";
dnssec-validation yes;
tcp-initial-timeout 1200;
};
zone "example" {
type primary;
file "example.db";
allow-transfer { any; };
};

View File

@@ -0,0 +1,22 @@
#!/bin/sh
# 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 disable=SC1091
. ../conf.sh
$FEATURETEST --with-libnghttp2 || {
echo_i "This test requires libnghttp2 support." >&2
exit 255
}
exit 0

View File

@@ -0,0 +1,11 @@
-----BEGIN CERTIFICATE-----
MIIBqTCCAVCgAwIBAgIULBCxkDF3scu+KzMu4JWrS1MiD8gwCgYIKoZIzj0EAwIw
FjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wIBcNMjQwMTEwMTQwOTAyWhgPMjA1MTA1
MjgxNDA5MDJaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYI
KoZIzj0DAQcDQgAEraleW8FCXwU72Iva/H2FRiY5yrnKOVG0wZ8UN8bghx2yyK+z
EFaHS5buo5jEnWnweX2qrX4N9RWDii7nqfwjNaN6MHgwHQYDVR0OBBYEFEGCx9FF
rNxaR7zTM74ksT4fDaGjMB8GA1UdIwQYMBaAFEGCx9FFrNxaR7zTM74ksT4fDaGj
MA8GA1UdEwEB/wQFMAMBAf8wJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhh
bXBsZS5jb20wCgYIKoZIzj0EAwIDRwAwRAIgL+cDL9EKz9YY3iR6/fZqjniXaiap
lMfzbtesX1LVi04CIBOBW97oz4jQ1K4D1QN4aDJpit2LJWrEKHyLk4SPqZUS
-----END CERTIFICATE-----

View File

@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg9uAMbwHDtsF9BDAu
CafftgyXCZbbRy8aJpoo76B8iwWhRANCAAStqV5bwUJfBTvYi9r8fYVGJjnKuco5
UbTBnxQ3xuCHHbLIr7MQVodLlu6jmMSdafB5faqtfg31FYOKLuep/CM1
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,21 @@
#!/bin/sh
# 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 disable=SC1091
. ../conf.sh
$SHELL clean.sh
$SHELL "${TOP_SRCDIR}"/bin/tests/system/genzone.sh 2 >ns1/example.db
copy_setports ns1/named.conf.in ns1/named.conf

View File

@@ -0,0 +1,81 @@
#!/bin/sh
# 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.
set -e
# shellcheck disable=SC1091
. ../conf.sh
dig_out_basename="dig.out.test"
testing="testing if the query is successfully completed"
dig_with_opts() {
# shellcheck disable=SC2086
"$DIG" -p "${EXTRAPORT1}" +noadd +nosea +nostat +noquest +nocmd "$@" NS example
}
status=0
n=0
run_dig_test() {
test_message="$1"
shift
n=$((n + 1))
echo_i "$test_message ($n)"
dig_failed=0
dig_with_opts "$@" >"$dig_out_basename$n" || dig_failed=1
}
run_dig_test_expect_success() {
ret=0
run_dig_test "$@"
if [ $dig_failed != 0 ]; then
ret=1
elif ! [ -s "$dig_out_basename$n" ]; then
ret=1
fi
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
}
run_dig_multitest_expect_success() {
message="$1"
shift
run_dig_test_expect_success "$message (IPv4)" -b 10.53.0.10 @10.53.0.1 "$@"
run_dig_test_expect_success "$message (IPv6)" -b fd92:7065:b8e:ffff::10 @fd92:7065:b8e:ffff::1 "$@"
}
reconfig_server() {
message="$1"
shift
config_file="$1"
shift
echo_i "$message"
copy_setports "ns1/$config_file" "ns1/named.conf"
rndc_reconfig ns1 10.53.0.1
}
run_dig_multitest_expect_success "$testing: a UDP query over Do53"
run_dig_multitest_expect_success "$testing: a TCP query over Do53" +tcp
reconfig_server "reconfiguring the server to use TLS/DoT" named-tls.conf.in
run_dig_multitest_expect_success "$testing: a query over TLS/DoT" +tls
reconfig_server "reconfiguring the server to use HTTPS/DoH" named-https.conf.in
run_dig_multitest_expect_success "$testing: a query over HTTPS/DoH" +https
reconfig_server "reconfiguring the server to use plain HTTP/DoH" named-http-plain.conf.in
run_dig_multitest_expect_success "$testing: a query over plain HTTP/DoH" +http-plain
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1

View File

@@ -0,0 +1,14 @@
# 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.
def test_transport_change(run_tests_sh):
run_tests_sh()

View File

@@ -35,7 +35,13 @@ Feature Changes
Bug Fixes
~~~~~~~~~
- None.
- Changes to ``listen-on`` statements were ignored on reconfiguration
unless the port or interface address was changed, making it
impossible to change a related listener transport type. That issue
has been fixed.
ISC would like to thank Thomas Amgarten for bringing this issue to
our attention. :gl:`#4518`, :gl:`#4528`
Known Issues
~~~~~~~~~~~~

View File

@@ -77,6 +77,7 @@ struct ns_interface {
char name[32]; /*%< Null terminated. */
isc_nmsocket_t *udplistensocket;
isc_nmsocket_t *tcplistensocket;
isc_nmsocket_t *tlslistensocket;
isc_nmsocket_t *http_listensocket;
isc_nmsocket_t *http_secure_listensocket;
isc_quota_t *http_quota;

View File

@@ -541,7 +541,7 @@ ns_interface_listentls(ns_interface_t *ifp, isc_tlsctx_t *sslctx) {
result = isc_nm_listentlsdns(
ifp->mgr->nm, &ifp->addr, ns__client_request, ifp,
ns__client_tcpconn, ifp, sizeof(ns_client_t), ifp->mgr->backlog,
&ifp->mgr->sctx->tcpquota, sslctx, &ifp->tcplistensocket);
&ifp->mgr->sctx->tcpquota, sslctx, &ifp->tlslistensocket);
if (result != ISC_R_SUCCESS) {
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
@@ -672,6 +672,9 @@ interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, const char *name,
interface_create(mgr, addr, name, &ifp);
} else {
REQUIRE(!LISTENING(ifp));
LOCK(&mgr->lock);
ifp->generation = mgr->generation;
UNLOCK(&mgr->lock);
}
ifp->flags |= NS_INTERFACEFLAG_LISTENING;
@@ -743,6 +746,10 @@ ns_interface_shutdown(ns_interface_t *ifp) {
isc_nm_stoplistening(ifp->tcplistensocket);
isc_nmsocket_close(&ifp->tcplistensocket);
}
if (ifp->tlslistensocket != NULL) {
isc_nm_stoplistening(ifp->tlslistensocket);
isc_nmsocket_close(&ifp->tlslistensocket);
}
if (ifp->http_listensocket != NULL) {
isc_nm_stoplistening(ifp->http_listensocket);
isc_nmsocket_close(&ifp->http_listensocket);
@@ -798,6 +805,14 @@ find_matching_interface(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) {
return (ifp);
}
static void
log_interface_shutdown(const ns_interface_t *ifp) {
char sabuf[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf));
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_INFO,
"no longer listening on %s", sabuf);
}
/*%
* Remove any interfaces whose generation number is not the current one.
*/
@@ -822,10 +837,7 @@ purge_old_interfaces(ns_interfacemgr_t *mgr) {
for (ifp = ISC_LIST_HEAD(interfaces); ifp != NULL; ifp = next) {
next = ISC_LIST_NEXT(ifp, link);
if (LISTENING(ifp)) {
char sabuf[256];
isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf));
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_INFO,
"no longer listening on %s", sabuf);
log_interface_shutdown(ifp);
ns_interface_shutdown(ifp);
}
ISC_LIST_UNLINK(interfaces, ifp, link);
@@ -942,9 +954,8 @@ replace_listener_tlsctx(ns_interface_t *ifp, isc_tlsctx_t *newctx) {
isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf));
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_INFO,
"updating TLS context on %s", sabuf);
if (ifp->tcplistensocket != NULL) {
/* 'tcplistensocket' is used for DoT */
isc_nmsocket_set_tlsctx(ifp->tcplistensocket, newctx);
if (ifp->tlslistensocket != NULL) {
isc_nmsocket_set_tlsctx(ifp->tlslistensocket, newctx);
} else if (ifp->http_secure_listensocket != NULL) {
isc_nmsocket_set_tlsctx(ifp->http_secure_listensocket, newctx);
}
@@ -1015,6 +1026,54 @@ update_listener_configuration(ns_interfacemgr_t *mgr, ns_interface_t *ifp,
UNLOCK(&mgr->lock);
}
static bool
same_listener_type(ns_interface_t *ifp, ns_listenelt_t *new_le) {
bool same_transport_type = false;
/* See 'interface_setup()' above */
if (new_le->is_http) {
/* HTTP/DoH */
same_transport_type = (new_le->sslctx != NULL &&
ifp->http_secure_listensocket != NULL) ||
(new_le->sslctx == NULL &&
ifp->http_listensocket != NULL);
} else if (new_le->sslctx != NULL && ifp->tlslistensocket != NULL) {
/* TLS/DoT */
same_transport_type = true;
} else if (new_le->sslctx == NULL && (ifp->udplistensocket != NULL ||
ifp->tcplistensocket != NULL))
{
/* "plain" DNS/Do53 */
same_transport_type = true;
}
return (same_transport_type);
}
static bool
interface_update_or_shutdown(ns_interfacemgr_t *mgr, ns_interface_t *ifp,
ns_listenelt_t *le, const bool config) {
if (LISTENING(ifp) && config && !same_listener_type(ifp, le)) {
/*
* DNS listener type has been changed on re-configuration. We
* will need to recreate the listener anew.
*/
log_interface_shutdown(ifp);
ns_interface_shutdown(ifp);
} else {
LOCK(&mgr->lock);
ifp->generation = mgr->generation;
UNLOCK(&mgr->lock);
if (LISTENING(ifp)) {
if (config) {
update_listener_configuration(mgr, ifp, le);
}
return (true);
}
}
return (false);
}
static isc_result_t
do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
isc_interfaceiter_t *iter = NULL;
@@ -1082,12 +1141,9 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
ifp = find_matching_interface(mgr, &listen_addr);
if (ifp != NULL) {
ifp->generation = mgr->generation;
if (LISTENING(ifp)) {
if (config) {
update_listener_configuration(
mgr, ifp, le);
}
bool cont = interface_update_or_shutdown(
mgr, ifp, le, config);
if (cont) {
continue;
}
}
@@ -1233,12 +1289,9 @@ do_scan(ns_interfacemgr_t *mgr, bool verbose, bool config) {
ifp = find_matching_interface(mgr, &listen_sockaddr);
if (ifp != NULL) {
ifp->generation = mgr->generation;
if (LISTENING(ifp)) {
if (config) {
update_listener_configuration(
mgr, ifp, le);
}
bool cont = interface_update_or_shutdown(
mgr, ifp, le, config);
if (cont) {
continue;
}
}