SSL contexts reuse across locations
Maxim Dounin
mdounin at mdounin.ru
Fri Jun 17 01:51:19 UTC 2022
Hello!
On Thu, Jun 16, 2022 at 08:26:48AM +0000, Pavel Pautov via nginx-devel wrote:
> Looks like, we've made a full circle then... I've replied to
> that suggestion already and in last e-mail (with patch) I note
> that moving additional logic into the ngx_http_proxy_set_ssl()
> has its own drawbacks, but I can certainly move more stuff into
> it.
>
> So do you envision something like "ngx_http_proxy_set_ssl(cf,
> conf, prev, reuse_ssl)"? As previously we've established that
> directives merging stays out of ngx_http_proxy_set_ssl (and
> reuse_ssl calculation has to happen before it).
I don't think further attempts to explain how to write readable
code worth the effort.
Please see the patch below. Review and testing appreciated.
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1655429915 -10800
# Fri Jun 17 04:38:35 2022 +0300
# Node ID e4a0eeb3edba037f0d090023a2242bda2f8dcb03
# Parent e23a385cd0ec866a3eb1d8c9c956991e1ed50d78
Upstream: optimized use of SSL contexts (ticket #1234).
To ensure optimal use of memory, SSL contexts for proxying are now
inherited from previous levels as long as relevant proxy_ssl_* directives
are not redefined.
Further, when no proxy_ssl_* directives are redefined in a server block,
we now preserve plcf->upstream.ssl in the "http" section configuration
to inherit it to all servers.
Similar changes made in uwsgi and grpc.
diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c
--- a/src/http/modules/ngx_http_grpc_module.c
+++ b/src/http/modules/ngx_http_grpc_module.c
@@ -210,7 +210,7 @@ static char *ngx_http_grpc_ssl_password_
static char *ngx_http_grpc_ssl_conf_command_check(ngx_conf_t *cf, void *post,
void *data);
static ngx_int_t ngx_http_grpc_set_ssl(ngx_conf_t *cf,
- ngx_http_grpc_loc_conf_t *glcf);
+ ngx_http_grpc_loc_conf_t *glcf, ngx_http_grpc_loc_conf_t *prev);
#endif
@@ -562,7 +562,7 @@ ngx_http_grpc_handler(ngx_http_request_t
ctx->host = glcf->host;
#if (NGX_HTTP_SSL)
- u->ssl = (glcf->upstream.ssl != NULL);
+ u->ssl = glcf->ssl;
if (u->ssl) {
ngx_str_set(&u->schema, "grpcs://");
@@ -4495,7 +4495,7 @@ ngx_http_grpc_merge_loc_conf(ngx_conf_t
ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
prev->ssl_conf_commands, NULL);
- if (conf->ssl && ngx_http_grpc_set_ssl(cf, conf) != NGX_OK) {
+ if (ngx_http_grpc_set_ssl(cf, conf, prev) != NGX_OK) {
return NGX_CONF_ERROR;
}
@@ -4524,7 +4524,7 @@ ngx_http_grpc_merge_loc_conf(ngx_conf_t
conf->grpc_values = prev->grpc_values;
#if (NGX_HTTP_SSL)
- conf->upstream.ssl = prev->upstream.ssl;
+ conf->ssl = prev->ssl;
#endif
}
@@ -4874,10 +4874,37 @@ ngx_http_grpc_ssl_conf_command_check(ngx
static ngx_int_t
-ngx_http_grpc_set_ssl(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *glcf)
+ngx_http_grpc_set_ssl(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *glcf,
+ ngx_http_grpc_loc_conf_t *prev)
{
+ ngx_uint_t preserve;
ngx_pool_cleanup_t *cln;
+ if (glcf->ssl_protocols == prev->ssl_protocols
+ && glcf->ssl_ciphers.data == prev->ssl_ciphers.data
+ && glcf->upstream.ssl_certificate == prev->upstream.ssl_certificate
+ && glcf->upstream.ssl_certificate_key
+ == prev->upstream.ssl_certificate_key
+ && glcf->upstream.ssl_passwords == prev->upstream.ssl_passwords
+ && glcf->upstream.ssl_verify == prev->upstream.ssl_verify
+ && glcf->ssl_verify_depth == prev->ssl_verify_depth
+ && glcf->ssl_trusted_certificate.data
+ == prev->ssl_trusted_certificate.data
+ && glcf->ssl_crl.data == prev->ssl_crl.data
+ && glcf->upstream.ssl_session_reuse == prev->upstream.ssl_session_reuse
+ && glcf->ssl_conf_commands == prev->ssl_conf_commands)
+ {
+ if (prev->upstream.ssl) {
+ glcf->upstream.ssl = prev->upstream.ssl;
+ return NGX_OK;
+ }
+
+ preserve = 1;
+
+ } else {
+ preserve = 0;
+ }
+
glcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
if (glcf->upstream.ssl == NULL) {
return NGX_ERROR;
@@ -4984,6 +5011,15 @@ ngx_http_grpc_set_ssl(ngx_conf_t *cf, ng
return NGX_ERROR;
}
+ /*
+ * special handling to preserve glcf->upstream.ssl
+ * in the "http" section to inherit it to all servers
+ */
+
+ if (preserve) {
+ prev->upstream.ssl = glcf->upstream.ssl;
+ }
+
return NGX_OK;
}
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -237,7 +237,7 @@ static ngx_int_t ngx_http_proxy_rewrite_
#if (NGX_HTTP_SSL)
static ngx_int_t ngx_http_proxy_set_ssl(ngx_conf_t *cf,
- ngx_http_proxy_loc_conf_t *plcf);
+ ngx_http_proxy_loc_conf_t *plcf, ngx_http_proxy_loc_conf_t *prev);
#endif
static void ngx_http_proxy_set_vars(ngx_url_t *u, ngx_http_proxy_vars_t *v);
@@ -959,7 +959,7 @@ ngx_http_proxy_handler(ngx_http_request_
ctx->vars = plcf->vars;
u->schema = plcf->vars.schema;
#if (NGX_HTTP_SSL)
- u->ssl = (plcf->upstream.ssl != NULL);
+ u->ssl = plcf->ssl;
#endif
} else {
@@ -3756,7 +3756,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
prev->ssl_conf_commands, NULL);
- if (conf->ssl && ngx_http_proxy_set_ssl(cf, conf) != NGX_OK) {
+ if (ngx_http_proxy_set_ssl(cf, conf, prev) != NGX_OK) {
return NGX_CONF_ERROR;
}
@@ -3857,7 +3857,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
conf->proxy_values = prev->proxy_values;
#if (NGX_HTTP_SSL)
- conf->upstream.ssl = prev->upstream.ssl;
+ conf->ssl = prev->ssl;
#endif
}
@@ -4923,10 +4923,37 @@ ngx_http_proxy_ssl_conf_command_check(ng
static ngx_int_t
-ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf)
+ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf,
+ ngx_http_proxy_loc_conf_t *prev)
{
+ ngx_uint_t preserve;
ngx_pool_cleanup_t *cln;
+ if (plcf->ssl_protocols == prev->ssl_protocols
+ && plcf->ssl_ciphers.data == prev->ssl_ciphers.data
+ && plcf->upstream.ssl_certificate == prev->upstream.ssl_certificate
+ && plcf->upstream.ssl_certificate_key
+ == prev->upstream.ssl_certificate_key
+ && plcf->upstream.ssl_passwords == prev->upstream.ssl_passwords
+ && plcf->upstream.ssl_verify == prev->upstream.ssl_verify
+ && plcf->ssl_verify_depth == prev->ssl_verify_depth
+ && plcf->ssl_trusted_certificate.data
+ == prev->ssl_trusted_certificate.data
+ && plcf->ssl_crl.data == prev->ssl_crl.data
+ && plcf->upstream.ssl_session_reuse == prev->upstream.ssl_session_reuse
+ && plcf->ssl_conf_commands == prev->ssl_conf_commands)
+ {
+ if (prev->upstream.ssl) {
+ plcf->upstream.ssl = prev->upstream.ssl;
+ return NGX_OK;
+ }
+
+ preserve = 1;
+
+ } else {
+ preserve = 0;
+ }
+
plcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
if (plcf->upstream.ssl == NULL) {
return NGX_ERROR;
@@ -5020,6 +5047,15 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n
return NGX_ERROR;
}
+ /*
+ * special handling to preserve plcf->upstream.ssl
+ * in the "http" section to inherit it to all servers
+ */
+
+ if (preserve) {
+ prev->upstream.ssl = plcf->upstream.ssl;
+ }
+
return NGX_OK;
}
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -97,7 +97,7 @@ static char *ngx_http_uwsgi_ssl_password
static char *ngx_http_uwsgi_ssl_conf_command_check(ngx_conf_t *cf, void *post,
void *data);
static ngx_int_t ngx_http_uwsgi_set_ssl(ngx_conf_t *cf,
- ngx_http_uwsgi_loc_conf_t *uwcf);
+ ngx_http_uwsgi_loc_conf_t *uwcf, ngx_http_uwsgi_loc_conf_t *prev);
#endif
@@ -668,7 +668,7 @@ ngx_http_uwsgi_handler(ngx_http_request_
if (uwcf->uwsgi_lengths == NULL) {
#if (NGX_HTTP_SSL)
- u->ssl = (uwcf->upstream.ssl != NULL);
+ u->ssl = uwcf->ssl;
if (u->ssl) {
ngx_str_set(&u->schema, "suwsgi://");
@@ -1897,7 +1897,7 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t
ngx_conf_merge_ptr_value(conf->ssl_conf_commands,
prev->ssl_conf_commands, NULL);
- if (conf->ssl && ngx_http_uwsgi_set_ssl(cf, conf) != NGX_OK) {
+ if (ngx_http_uwsgi_set_ssl(cf, conf, prev) != NGX_OK) {
return NGX_CONF_ERROR;
}
@@ -1927,7 +1927,7 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t
conf->uwsgi_values = prev->uwsgi_values;
#if (NGX_HTTP_SSL)
- conf->upstream.ssl = prev->upstream.ssl;
+ conf->ssl = prev->ssl;
#endif
}
@@ -2455,10 +2455,37 @@ ngx_http_uwsgi_ssl_conf_command_check(ng
static ngx_int_t
-ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
+ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf,
+ ngx_http_uwsgi_loc_conf_t *prev)
{
+ ngx_uint_t preserve;
ngx_pool_cleanup_t *cln;
+ if (uwcf->ssl_protocols == prev->ssl_protocols
+ && uwcf->ssl_ciphers.data == prev->ssl_ciphers.data
+ && uwcf->upstream.ssl_certificate == prev->upstream.ssl_certificate
+ && uwcf->upstream.ssl_certificate_key
+ == prev->upstream.ssl_certificate_key
+ && uwcf->upstream.ssl_passwords == prev->upstream.ssl_passwords
+ && uwcf->upstream.ssl_verify == prev->upstream.ssl_verify
+ && uwcf->ssl_verify_depth == prev->ssl_verify_depth
+ && uwcf->ssl_trusted_certificate.data
+ == prev->ssl_trusted_certificate.data
+ && uwcf->ssl_crl.data == prev->ssl_crl.data
+ && uwcf->upstream.ssl_session_reuse == prev->upstream.ssl_session_reuse
+ && uwcf->ssl_conf_commands == prev->ssl_conf_commands)
+ {
+ if (prev->upstream.ssl) {
+ uwcf->upstream.ssl = prev->upstream.ssl;
+ return NGX_OK;
+ }
+
+ preserve = 1;
+
+ } else {
+ preserve = 0;
+ }
+
uwcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
if (uwcf->upstream.ssl == NULL) {
return NGX_ERROR;
@@ -2552,6 +2579,15 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, n
return NGX_ERROR;
}
+ /*
+ * special handling to preserve uwcf->upstream.ssl
+ * in the "http" section to inherit it to all servers
+ */
+
+ if (preserve) {
+ prev->upstream.ssl = uwcf->upstream.ssl;
+ }
+
return NGX_OK;
}
--
Maxim Dounin
http://mdounin.ru/
More information about the nginx-devel
mailing list