Load and validate the configured TLS transport for forwarders

Add support for loading and validating the 'tls' parameter from
the forwarders' configuration.

This prepares ground for adding support to forward queries to
DoT-enabled upstream servers.
This commit is contained in:
Aram Sargsyan
2022-12-08 14:17:24 +00:00
parent e1dd86aa07
commit 3aa2d84880
3 changed files with 104 additions and 4 deletions

View File

@@ -447,6 +447,9 @@ static isc_result_t
configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
cfg_aclconfctx_t *actx);
static const cfg_obj_t *
find_maplist(const cfg_obj_t *config, const char *listname, const char *name);
static isc_result_t
add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx);
@@ -6204,11 +6207,44 @@ cleanup:
return (result);
}
static isc_result_t
validate_tls(const cfg_obj_t *config, dns_view_t *view, const cfg_obj_t *obj,
isc_log_t *logctx, const char *str, dns_name_t **name) {
dns_fixedname_t fname;
dns_name_t *nm = dns_fixedname_initname(&fname);
isc_result_t result = dns_name_fromstring(nm, str, 0, NULL);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"'%s' is not a valid name", str);
return (result);
}
if (strcasecmp(str, "ephemeral") != 0) {
const cfg_obj_t *tlsmap = find_maplist(config, "tls", str);
if (tlsmap == NULL) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"tls '%s' is not defined", str);
return (ISC_R_FAILURE);
}
}
if (name != NULL && *name == NULL) {
*name = isc_mem_get(view->mctx, sizeof(dns_name_t));
dns_name_init(*name, NULL);
dns_name_dup(nm, view->mctx, *name);
}
return (ISC_R_SUCCESS);
}
static isc_result_t
configure_forward(const cfg_obj_t *config, dns_view_t *view,
const dns_name_t *origin, const cfg_obj_t *forwarders,
const cfg_obj_t *forwardtype) {
const cfg_obj_t *portobj = NULL;
const cfg_obj_t *tlspobj = NULL;
const cfg_obj_t *faddresses = NULL;
const cfg_listelt_t *element = NULL;
dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none;
@@ -6216,6 +6252,8 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view,
dns_forwarder_t *fwd = NULL;
isc_result_t result;
in_port_t port;
in_port_t tls_port;
const char *tls = NULL;
ISC_LIST_INIT(fwdlist);
@@ -6223,6 +6261,7 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view,
* Determine which port to send forwarded requests to.
*/
CHECKM(named_config_getport(config, "port", &port), "port");
CHECKM(named_config_getport(config, "tls-port", &tls_port), "tls-port");
if (forwarders != NULL) {
portobj = cfg_tuple_get(forwarders, "port");
@@ -6234,7 +6273,24 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view,
"port '%u' out of range", val);
return (ISC_R_RANGE);
}
port = (in_port_t)val;
port = tls_port = (in_port_t)val;
}
}
/*
* TLS value for forwarded requests.
*/
if (forwarders != NULL) {
tlspobj = cfg_tuple_get(forwarders, "tls");
if (cfg_obj_isstring(tlspobj)) {
tls = cfg_obj_asstring(tlspobj);
if (tls != NULL) {
result = validate_tls(config, view, tlspobj,
named_g_lctx, tls, NULL);
if (result != ISC_R_SUCCESS) {
return (result);
}
}
}
}
@@ -6247,10 +6303,28 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view,
element = cfg_list_next(element))
{
const cfg_obj_t *forwarder = cfg_listelt_value(element);
const char *cur_tls = NULL;
fwd = isc_mem_get(view->mctx, sizeof(dns_forwarder_t));
fwd->tlsname = NULL;
cur_tls = cfg_obj_getsockaddrtls(forwarder);
if (cur_tls == NULL) {
cur_tls = tls;
}
if (cur_tls != NULL) {
result = validate_tls(config, view, faddresses,
named_g_lctx, cur_tls,
&fwd->tlsname);
if (result != ISC_R_SUCCESS) {
isc_mem_put(view->mctx, fwd,
sizeof(dns_forwarder_t));
goto cleanup;
}
}
fwd->addr = *cfg_obj_assockaddr(forwarder);
if (isc_sockaddr_getport(&fwd->addr) == 0) {
isc_sockaddr_setport(&fwd->addr, port);
isc_sockaddr_setport(&fwd->addr,
cur_tls != NULL ? tls_port : port);
}
ISC_LINK_INIT(fwd, link);
ISC_LIST_APPEND(fwdlist, fwd, link);
@@ -6300,6 +6374,11 @@ cleanup:
while (!ISC_LIST_EMPTY(fwdlist)) {
fwd = ISC_LIST_HEAD(fwdlist);
ISC_LIST_UNLINK(fwdlist, fwd, link);
if (fwd->tlsname != NULL) {
dns_name_free(fwd->tlsname, view->mctx);
isc_mem_put(view->mctx, fwd->tlsname,
sizeof(dns_name_t));
}
isc_mem_put(view->mctx, fwd, sizeof(dns_forwarder_t));
}

View File

@@ -20,6 +20,7 @@
#include <isc/util.h>
#include <dns/forward.h>
#include <dns/name.h>
#include <dns/rbt.h>
#include <dns/types.h>
@@ -84,6 +85,15 @@ dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, const dns_name_t *name,
{
nfwd = isc_mem_get(fwdtable->mctx, sizeof(*nfwd));
*nfwd = *fwd;
if (fwd->tlsname != NULL) {
nfwd->tlsname = isc_mem_get(fwdtable->mctx,
sizeof(*nfwd->tlsname));
dns_name_init(nfwd->tlsname, NULL);
dns_name_dup(fwd->tlsname, fwdtable->mctx,
nfwd->tlsname);
}
ISC_LINK_INIT(nfwd, link);
ISC_LIST_APPEND(forwarders->fwdrs, nfwd, link);
}
@@ -103,6 +113,11 @@ cleanup:
while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
fwd = ISC_LIST_HEAD(forwarders->fwdrs);
ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
if (fwd->tlsname != NULL) {
dns_name_free(fwd->tlsname, fwdtable->mctx);
isc_mem_put(fwdtable->mctx, fwd->tlsname,
sizeof(*fwd->tlsname));
}
isc_mem_put(fwdtable->mctx, fwd, sizeof(*fwd));
}
isc_mem_put(fwdtable->mctx, forwarders, sizeof(*forwarders));
@@ -126,8 +141,8 @@ dns_fwdtable_add(dns_fwdtable_t *fwdtable, const dns_name_t *name,
sa = ISC_LIST_NEXT(sa, link))
{
fwd = isc_mem_get(fwdtable->mctx, sizeof(*fwd));
fwd->addr = *sa;
ISC_LINK_INIT(fwd, link);
*fwd = (dns_forwarder_t){ .addr = *sa,
.link = ISC_LINK_INITIALIZER };
ISC_LIST_APPEND(forwarders->fwdrs, fwd, link);
}
forwarders->fwdpolicy = fwdpolicy;
@@ -211,6 +226,11 @@ auto_detach(void *data, void *arg) {
while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
fwd = ISC_LIST_HEAD(forwarders->fwdrs);
ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
if (fwd->tlsname != NULL) {
dns_name_free(fwd->tlsname, fwdtable->mctx);
isc_mem_put(fwdtable->mctx, fwd->tlsname,
sizeof(*fwd->tlsname));
}
isc_mem_put(fwdtable->mctx, fwd, sizeof(*fwd));
}
isc_mem_put(fwdtable->mctx, forwarders, sizeof(*forwarders));

View File

@@ -25,6 +25,7 @@ ISC_LANG_BEGINDECLS
struct dns_forwarder {
isc_sockaddr_t addr;
dns_name_t *tlsname;
ISC_LINK(dns_forwarder_t) link;
};