mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-09 09:52:04 -04:00
Resolver query forwarding to DoT-enabled upstream servers
Implement TLS transport usage in the resolver. Use the configured TLS transport for the forwarders in the resolver.
This commit is contained in:
parent
3aa2d84880
commit
6ea05ac3fe
12 changed files with 96 additions and 27 deletions
|
|
@ -41,6 +41,7 @@
|
|||
#include <isc/string.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/timer.h>
|
||||
#include <isc/tls.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/byaddr.h>
|
||||
|
|
@ -85,6 +86,9 @@ static isc_nm_t *netmgr = NULL;
|
|||
static isc_loopmgr_t *loopmgr = NULL;
|
||||
static isc_taskmgr_t *taskmgr = NULL;
|
||||
|
||||
/* TLS */
|
||||
static isc_tlsctx_cache_t *tlsctx_client_cache = NULL;
|
||||
|
||||
/* Configurables */
|
||||
static char *server = NULL;
|
||||
static const char *port = "53";
|
||||
|
|
@ -1835,8 +1839,10 @@ main(int argc, char *argv[]) {
|
|||
setup_logging(stderr);
|
||||
|
||||
/* Create client */
|
||||
result = dns_client_create(mctx, loopmgr, taskmgr, netmgr, 0, &client,
|
||||
srcaddr4, srcaddr6);
|
||||
isc_tlsctx_cache_create(mctx, &tlsctx_client_cache);
|
||||
result = dns_client_create(mctx, loopmgr, taskmgr, netmgr, 0,
|
||||
tlsctx_client_cache, &client, srcaddr4,
|
||||
srcaddr6);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
delv_log(ISC_LOG_ERROR, "dns_client_create: %s",
|
||||
isc_result_totext(result));
|
||||
|
|
@ -1869,6 +1875,9 @@ cleanup:
|
|||
if (style != NULL) {
|
||||
dns_master_styledestroy(&style, mctx);
|
||||
}
|
||||
if (tlsctx_client_cache != NULL) {
|
||||
isc_tlsctx_cache_detach(&tlsctx_client_cache);
|
||||
}
|
||||
|
||||
isc_log_destroy(&lctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -4758,7 +4758,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
|
|||
ndisp = 4 * ISC_MIN(named_g_udpdisp, MAX_UDP_DISPATCH);
|
||||
CHECK(dns_view_createresolver(
|
||||
view, named_g_loopmgr, named_g_taskmgr, ndisp, named_g_netmgr,
|
||||
resopts, named_g_dispatchmgr, dispatch4, dispatch6));
|
||||
resopts, named_g_server->tlsctx_client_cache,
|
||||
named_g_dispatchmgr, dispatch4, dispatch6));
|
||||
|
||||
if (resstats == NULL) {
|
||||
CHECK(isc_stats_create(mctx, &resstats,
|
||||
|
|
|
|||
|
|
@ -2884,8 +2884,12 @@ authoritative and does not have the answer in its cache.
|
|||
|
||||
This specifies a list of IP addresses to which queries are forwarded. The
|
||||
default is the empty list (no forwarding). Each address in the list can be
|
||||
associated with an optional port number. A default port number can be set
|
||||
for the entire list.
|
||||
associated with an optional port number and a TLS transport. A default port
|
||||
number and a TLS transport can be set for the entire list.
|
||||
|
||||
If a TLS configuration is specified, :iscman:`named` will use DNS-over-TLS
|
||||
(DoT) connections when connecting to the specified IP address(es), using the
|
||||
TLS configuration referenced by the :any:`tls` statement.
|
||||
|
||||
Forwarding can also be configured on a per-domain basis, allowing for
|
||||
the global forwarding options to be overridden in a variety of ways.
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include <dns/rdatatype.h>
|
||||
#include <dns/resolver.h>
|
||||
#include <dns/stats.h>
|
||||
#include <dns/transport.h>
|
||||
|
||||
#define DNS_ADB_MAGIC ISC_MAGIC('D', 'a', 'd', 'b')
|
||||
#define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
|
||||
|
|
@ -1321,6 +1322,9 @@ free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
|
|||
|
||||
ai->magic = 0;
|
||||
|
||||
if (ai->transport != NULL) {
|
||||
dns_transport_detach(&ai->transport);
|
||||
}
|
||||
dns_adbentry_detach(&ai->entry);
|
||||
|
||||
isc_mem_put(adb->mctx, ai, sizeof(*ai));
|
||||
|
|
|
|||
|
|
@ -204,9 +204,10 @@ getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr,
|
|||
|
||||
static isc_result_t
|
||||
createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_loopmgr_t *loopmgr,
|
||||
isc_taskmgr_t *taskmgr, isc_nm_t *nm, dns_dispatchmgr_t *dispatchmgr,
|
||||
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
|
||||
dns_view_t **viewp) {
|
||||
isc_taskmgr_t *taskmgr, isc_nm_t *nm,
|
||||
isc_tlsctx_cache_t *tlsctx_client_cache,
|
||||
dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4,
|
||||
dns_dispatch_t *dispatchv6, dns_view_t **viewp) {
|
||||
isc_result_t result;
|
||||
dns_view_t *view = NULL;
|
||||
|
||||
|
|
@ -222,7 +223,8 @@ createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_loopmgr_t *loopmgr,
|
|||
}
|
||||
|
||||
result = dns_view_createresolver(view, loopmgr, taskmgr, 1, nm, 0,
|
||||
dispatchmgr, dispatchv4, dispatchv6);
|
||||
tlsctx_client_cache, dispatchmgr,
|
||||
dispatchv4, dispatchv6);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_view;
|
||||
}
|
||||
|
|
@ -244,6 +246,7 @@ cleanup_view:
|
|||
isc_result_t
|
||||
dns_client_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
|
||||
isc_taskmgr_t *taskmgr, isc_nm_t *nm, unsigned int options,
|
||||
isc_tlsctx_cache_t *tlsctx_client_cache,
|
||||
dns_client_t **clientp, const isc_sockaddr_t *localaddr4,
|
||||
const isc_sockaddr_t *localaddr6) {
|
||||
isc_result_t result;
|
||||
|
|
@ -255,6 +258,7 @@ dns_client_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
|
|||
REQUIRE(mctx != NULL);
|
||||
REQUIRE(taskmgr != NULL);
|
||||
REQUIRE(nm != NULL);
|
||||
REQUIRE(tlsctx_client_cache != NULL);
|
||||
REQUIRE(clientp != NULL && *clientp == NULL);
|
||||
|
||||
UNUSED(options);
|
||||
|
|
@ -309,7 +313,8 @@ dns_client_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
|
|||
|
||||
/* Create the default view for class IN */
|
||||
result = createview(mctx, dns_rdataclass_in, loopmgr, taskmgr, nm,
|
||||
client->dispatchmgr, dispatchv4, dispatchv6, &view);
|
||||
tlsctx_client_cache, client->dispatchmgr,
|
||||
dispatchv4, dispatchv6, &view);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_references;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,8 +204,9 @@ struct dns_adbfind {
|
|||
struct dns_adbaddrinfo {
|
||||
unsigned int magic; /*%< private */
|
||||
|
||||
isc_sockaddr_t sockaddr; /*%< [rw] */
|
||||
unsigned int srtt; /*%< [rw] microsecs */
|
||||
isc_sockaddr_t sockaddr; /*%< [rw] */
|
||||
unsigned int srtt; /*%< [rw] microsecs */
|
||||
dns_transport_t *transport;
|
||||
|
||||
unsigned int flags; /*%< [rw] */
|
||||
dns_adbentry_t *entry; /*%< private */
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ typedef struct dns_clientresevent {
|
|||
isc_result_t
|
||||
dns_client_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
|
||||
isc_taskmgr_t *taskmgr, isc_nm_t *nm, unsigned int options,
|
||||
isc_tlsctx_cache_t *tlsctx_client_cache,
|
||||
dns_client_t **clientp, const isc_sockaddr_t *localaddr4,
|
||||
const isc_sockaddr_t *localaddr6);
|
||||
/*%<
|
||||
|
|
@ -113,7 +114,7 @@ dns_client_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
|
|||
*
|
||||
*\li 'nm' is a valid network manager.
|
||||
*
|
||||
*\li 'timermgr' is a valid timer manager.
|
||||
*\li 'tlsctx_client_cache' is a valid TLS context cache.
|
||||
*
|
||||
*\li clientp != NULL && *clientp == NULL.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include <isc/lang.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/stats.h>
|
||||
#include <isc/types.h>
|
||||
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/types.h>
|
||||
|
|
@ -171,9 +172,9 @@ typedef enum { dns_quotatype_zone = 0, dns_quotatype_server } dns_quotatype_t;
|
|||
isc_result_t
|
||||
dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
|
||||
isc_taskmgr_t *taskmgr, unsigned int ndisp, isc_nm_t *nm,
|
||||
unsigned int options, dns_dispatchmgr_t *dispatchmgr,
|
||||
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
|
||||
dns_resolver_t **resp);
|
||||
unsigned int options, isc_tlsctx_cache_t *tlsctx_cache,
|
||||
dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4,
|
||||
dns_dispatch_t *dispatchv6, dns_resolver_t **resp);
|
||||
|
||||
/*%<
|
||||
* Create a resolver.
|
||||
|
|
@ -193,6 +194,10 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
|
|||
*
|
||||
*\li 'nm' is a valid network manager.
|
||||
*
|
||||
*\li 'tlsctx_cache' != NULL.
|
||||
*
|
||||
*\li 'dispatchmgr' != NULL.
|
||||
*
|
||||
*\li 'dispatchv4' is a dispatch with an IPv4 UDP socket, or is NULL.
|
||||
* If not NULL, 'ndisp' clones of it will be created by the resolver.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -390,7 +390,8 @@ isc_result_t
|
|||
dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr,
|
||||
isc_taskmgr_t *taskmgr, unsigned int ndisp,
|
||||
isc_nm_t *netmgr, unsigned int options,
|
||||
dns_dispatchmgr_t *dispatchmgr,
|
||||
isc_tlsctx_cache_t *tlsctx_cache,
|
||||
dns_dispatchmgr_t *dispatchmgr,
|
||||
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6);
|
||||
/*%<
|
||||
* Create a resolver and address database for the view.
|
||||
|
|
@ -402,7 +403,8 @@ dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr,
|
|||
*\li 'view' does not have a resolver already.
|
||||
*
|
||||
*\li The requirements of dns_resolver_create() apply to 'taskmgr',
|
||||
* 'ndisp', 'netmgr', 'options', 'dispatchv4', and 'dispatchv6'.
|
||||
* 'ndisp', 'netmgr', 'options', 'tlsctx_cache', 'dispatchv4', and
|
||||
* 'dispatchv6'.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -548,6 +548,7 @@ struct dns_resolver {
|
|||
dns_view_t *view;
|
||||
bool frozen;
|
||||
unsigned int options;
|
||||
isc_tlsctx_cache_t *tlsctx_cache;
|
||||
dns_dispatchmgr_t *dispatchmgr;
|
||||
dns_dispatchset_t *dispatches4;
|
||||
dns_dispatchset_t *dispatches6;
|
||||
|
|
@ -2134,6 +2135,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
|||
isc_sockaddr_t addr;
|
||||
bool have_addr = false;
|
||||
unsigned int srtt;
|
||||
isc_tlsctx_cache_t *tlsctx_cache = NULL;
|
||||
|
||||
FCTXTRACE("query");
|
||||
|
||||
|
|
@ -2141,6 +2143,21 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
|||
|
||||
srtt = addrinfo->srtt;
|
||||
|
||||
if (addrinfo->transport != NULL) {
|
||||
switch (dns_transport_get_type(addrinfo->transport)) {
|
||||
case DNS_TRANSPORT_TLS:
|
||||
options |= DNS_FETCHOPT_TCP;
|
||||
tlsctx_cache = res->tlsctx_cache;
|
||||
break;
|
||||
case DNS_TRANSPORT_TCP:
|
||||
case DNS_TRANSPORT_HTTP:
|
||||
options |= DNS_FETCHOPT_TCP;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow an additional second for the kernel to resend the SYN
|
||||
* (or SYN without ECN in the case of stupid firewalls blocking
|
||||
|
|
@ -2301,9 +2318,9 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
|
|||
/* Set up the dispatch and set the query ID */
|
||||
result = dns_dispatch_add(
|
||||
query->dispatch, 0, isc_interval_ms(&fctx->interval),
|
||||
&query->addrinfo->sockaddr, NULL, NULL, resquery_connected,
|
||||
resquery_senddone, resquery_response, query, &query->id,
|
||||
&query->dispentry);
|
||||
&query->addrinfo->sockaddr, addrinfo->transport, tlsctx_cache,
|
||||
resquery_connected, resquery_senddone, resquery_response, query,
|
||||
&query->id, &query->dispentry);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup_udpfetch;
|
||||
}
|
||||
|
|
@ -3679,6 +3696,15 @@ fctx_getaddresses(fetchctx_t *fctx, bool badcache) {
|
|||
if (result == ISC_R_SUCCESS) {
|
||||
dns_adbaddrinfo_t *cur;
|
||||
ai->flags |= FCTX_ADDRINFO_FORWARDER;
|
||||
if (fwd->tlsname != NULL) {
|
||||
result = dns_view_gettransport(
|
||||
res->view, DNS_TRANSPORT_TLS,
|
||||
fwd->tlsname, &ai->transport);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_adb_freeaddrinfo(fctx->adb, &ai);
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
cur = ISC_LIST_HEAD(fctx->forwaddrs);
|
||||
while (cur != NULL && cur->srtt < ai->srtt) {
|
||||
cur = ISC_LIST_NEXT(cur, publink);
|
||||
|
|
@ -3690,6 +3716,7 @@ fctx_getaddresses(fetchctx_t *fctx, bool badcache) {
|
|||
ISC_LIST_APPEND(fctx->forwaddrs, ai, publink);
|
||||
}
|
||||
}
|
||||
next:
|
||||
fwd = ISC_LIST_NEXT(fwd, link);
|
||||
}
|
||||
|
||||
|
|
@ -10095,9 +10122,9 @@ spillattimer_countdown(void *arg) {
|
|||
isc_result_t
|
||||
dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
|
||||
isc_taskmgr_t *taskmgr, unsigned int ndisp, isc_nm_t *nm,
|
||||
unsigned int options, dns_dispatchmgr_t *dispatchmgr,
|
||||
dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
|
||||
dns_resolver_t **resp) {
|
||||
unsigned int options, isc_tlsctx_cache_t *tlsctx_cache,
|
||||
dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4,
|
||||
dns_dispatch_t *dispatchv6, dns_resolver_t **resp) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
char name[sizeof("res4294967295")];
|
||||
dns_resolver_t *res = NULL;
|
||||
|
|
@ -10109,6 +10136,7 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
|
|||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
REQUIRE(ndisp > 0);
|
||||
REQUIRE(resp != NULL && *resp == NULL);
|
||||
REQUIRE(tlsctx_cache != NULL);
|
||||
REQUIRE(dispatchmgr != NULL);
|
||||
REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL);
|
||||
|
||||
|
|
@ -10122,6 +10150,7 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
|
|||
.taskmgr = taskmgr,
|
||||
.dispatchmgr = dispatchmgr,
|
||||
.options = options,
|
||||
.tlsctx_cache = tlsctx_cache,
|
||||
.spillatmin = 10,
|
||||
.spillat = 10,
|
||||
.spillatmax = 100,
|
||||
|
|
|
|||
|
|
@ -655,6 +655,7 @@ isc_result_t
|
|||
dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr,
|
||||
isc_taskmgr_t *taskmgr, unsigned int ndisp,
|
||||
isc_nm_t *netmgr, unsigned int options,
|
||||
isc_tlsctx_cache_t *tlsctx_cache,
|
||||
dns_dispatchmgr_t *dispatchmgr,
|
||||
dns_dispatch_t *dispatchv4,
|
||||
dns_dispatch_t *dispatchv6) {
|
||||
|
|
@ -672,8 +673,8 @@ dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr,
|
|||
isc_task_setname(view->task, "view", view);
|
||||
|
||||
result = dns_resolver_create(view, loopmgr, taskmgr, ndisp, netmgr,
|
||||
options, dispatchmgr, dispatchv4,
|
||||
dispatchv6, &view->resolver);
|
||||
options, tlsctx_cache, dispatchmgr,
|
||||
dispatchv4, dispatchv6, &view->resolver);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_task_detach(&view->task);
|
||||
return (result);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <isc/print.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/timer.h>
|
||||
#include <isc/tls.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/dispatch.h>
|
||||
|
|
@ -38,6 +39,7 @@
|
|||
static dns_dispatchmgr_t *dispatchmgr = NULL;
|
||||
static dns_dispatch_t *dispatch = NULL;
|
||||
static dns_view_t *view = NULL;
|
||||
static isc_tlsctx_cache_t *tlsctx_cache = NULL;
|
||||
|
||||
static int
|
||||
setup_test(void **state) {
|
||||
|
|
@ -73,8 +75,10 @@ static void
|
|||
mkres(dns_resolver_t **resolverp) {
|
||||
isc_result_t result;
|
||||
|
||||
isc_tlsctx_cache_create(mctx, &tlsctx_cache);
|
||||
result = dns_resolver_create(view, loopmgr, taskmgr, 1, netmgr, 0,
|
||||
dispatchmgr, dispatch, NULL, resolverp);
|
||||
tlsctx_cache, dispatchmgr, dispatch, NULL,
|
||||
resolverp);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
@ -82,6 +86,9 @@ static void
|
|||
destroy_resolver(dns_resolver_t **resolverp) {
|
||||
dns_resolver_shutdown(*resolverp);
|
||||
dns_resolver_detach(resolverp);
|
||||
if (tlsctx_cache != NULL) {
|
||||
isc_tlsctx_cache_detach(&tlsctx_cache);
|
||||
}
|
||||
}
|
||||
|
||||
/* dns_resolver_create */
|
||||
|
|
|
|||
Loading…
Reference in a new issue