Add 'proxy' option to 'listen-on' statement

This commit extends "listen-on" statement with "proxy" options that
allows one to enable PROXYv2 support on a dedicated listener. It can
have the following values:

- "plain" to send PROXYv2 headers without encryption, even in the case
of encrypted transports.
- "encrypted" to send PROXYv2 headers encrypted right after the TLS
handshake.
This commit is contained in:
Artem Boldariev
2023-10-30 17:03:30 +02:00
parent c9d526d84d
commit f650d3eb63
9 changed files with 168 additions and 42 deletions

View File

@@ -701,7 +701,8 @@ cfg_acl_fromconfig(const cfg_obj_t *acl_data, const cfg_obj_t *cctx,
if (strcasecmp(cfg_obj_asstring(obj_transport),
"udp") == 0)
{
transports = isc_nm_udpsocket;
transports = isc_nm_udpsocket |
isc_nm_proxyudpsocket;
encrypted = false;
} else if (strcasecmp(cfg_obj_asstring(obj_transport),
"tcp") == 0)
@@ -713,7 +714,8 @@ cfg_acl_fromconfig(const cfg_obj_t *acl_data, const cfg_obj_t *cctx,
{
/* Good ol' DNS over port 53 */
transports = isc_nm_streamdnssocket |
isc_nm_udpsocket;
isc_nm_udpsocket |
isc_nm_proxyudpsocket;
encrypted = false;
} else if (strcasecmp(cfg_obj_asstring(obj_transport),
"tls") == 0)

View File

@@ -1033,6 +1033,7 @@ check_listener(const cfg_obj_t *listener, const cfg_obj_t *config,
const cfg_obj_t *tlsobj = NULL, *httpobj = NULL;
const cfg_obj_t *portobj = NULL;
const cfg_obj_t *http_server = NULL;
const cfg_obj_t *proxyobj = NULL;
bool do_tls = false, no_tls = false;
dns_acl_t *acl = NULL;
@@ -1097,6 +1098,36 @@ check_listener(const cfg_obj_t *listener, const cfg_obj_t *config,
}
}
proxyobj = cfg_tuple_get(ltup, "proxy");
if (proxyobj != NULL && cfg_obj_isstring(proxyobj)) {
const char *proxyval = cfg_obj_asstring(proxyobj);
if (proxyval == NULL ||
(strcasecmp(proxyval, "encrypted") != 0 &&
strcasecmp(proxyval, "plain") != 0))
{
cfg_obj_log(proxyobj, logctx, ISC_LOG_ERROR,
"'proxy' must have one of the following "
"values: 'plain', 'encrypted'");
if (result == ISC_R_SUCCESS) {
result = ISC_R_FAILURE;
}
}
if (proxyval != NULL &&
strcasecmp(proxyval, "encrypted") == 0 && !do_tls)
{
cfg_obj_log(proxyobj, logctx, ISC_LOG_ERROR,
"'proxy encrypted' can be used only when "
"encryption is enabled by setting 'tls' to "
"a defined value or to 'ephemeral'");
if (result == ISC_R_SUCCESS) {
result = ISC_R_FAILURE;
}
}
}
tresult = cfg_acl_fromconfig(cfg_tuple_get(listener, "acl"), config,
logctx, actx, mctx, 0, &acl);
if (result == ISC_R_SUCCESS) {

View File

@@ -150,6 +150,11 @@ static cfg_type_t cfg_type_zone;
static cfg_tuplefielddef_t listenon_tuple_fields[] = {
{ "port", &cfg_type_optional_port, 0 },
/*
* Let's follow the protocols encapsulation order (lower->upper), at
* least roughly.
*/
{ "proxy", &cfg_type_astring, CFG_CLAUSEFLAG_EXPERIMENTAL },
{ "tls", &cfg_type_astring, 0 },
#if HAVE_LIBNGHTTP2
{ "http", &cfg_type_astring, 0 },