[nginx] Upstream: optimized use of SSL contexts (ticket #1234).

Sergey Kandaurov pluknet at nginx.com
Wed Jun 29 12:05:26 UTC 2022


details:   https://hg.nginx.org/nginx/rev/9d98d524bd02
branches:  
changeset: 8053:9d98d524bd02
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Wed Jun 29 02:47:45 2022 +0300
description:
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, grpc, and stream proxy.

diffstat:

 src/http/modules/ngx_http_grpc_module.c  |  66 +++++++++++++++++++++++++++---
 src/http/modules/ngx_http_proxy_module.c |  68 ++++++++++++++++++++++++++++---
 src/http/modules/ngx_http_uwsgi_module.c |  66 +++++++++++++++++++++++++++---
 src/stream/ngx_stream_proxy_module.c     |  64 +++++++++++++++++++++++++++--
 4 files changed, 236 insertions(+), 28 deletions(-)

diffs (431 lines):

diff -r e210c8942a54 -r 9d98d524bd02 src/http/modules/ngx_http_grpc_module.c
--- a/src/http/modules/ngx_http_grpc_module.c	Wed Jun 29 02:47:38 2022 +0300
+++ b/src/http/modules/ngx_http_grpc_module.c	Wed Jun 29 02:47:45 2022 +0300
@@ -209,6 +209,8 @@ static char *ngx_http_grpc_ssl_password_
     ngx_command_t *cmd, void *conf);
 static char *ngx_http_grpc_ssl_conf_command_check(ngx_conf_t *cf, void *post,
     void *data);
+static ngx_int_t ngx_http_grpc_merge_ssl(ngx_conf_t *cf,
+    ngx_http_grpc_loc_conf_t *conf, ngx_http_grpc_loc_conf_t *prev);
 static ngx_int_t ngx_http_grpc_set_ssl(ngx_conf_t *cf,
     ngx_http_grpc_loc_conf_t *glcf);
 #endif
@@ -562,7 +564,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://");
@@ -4463,6 +4465,10 @@ ngx_http_grpc_merge_loc_conf(ngx_conf_t 
 
 #if (NGX_HTTP_SSL)
 
+    if (ngx_http_grpc_merge_ssl(cf, conf, prev) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
     ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
                               prev->upstream.ssl_session_reuse, 1);
 
@@ -4524,7 +4530,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,17 +4880,63 @@ ngx_http_grpc_ssl_conf_command_check(ngx
 
 
 static ngx_int_t
+ngx_http_grpc_merge_ssl(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *conf,
+    ngx_http_grpc_loc_conf_t *prev)
+{
+    ngx_uint_t  preserve;
+
+    if (conf->ssl_protocols == 0
+        && conf->ssl_ciphers.data == NULL
+        && conf->upstream.ssl_certificate == NGX_CONF_UNSET_PTR
+        && conf->upstream.ssl_certificate_key == NGX_CONF_UNSET_PTR
+        && conf->upstream.ssl_passwords == NGX_CONF_UNSET_PTR
+        && conf->upstream.ssl_verify == NGX_CONF_UNSET
+        && conf->ssl_verify_depth == NGX_CONF_UNSET_UINT
+        && conf->ssl_trusted_certificate.data == NULL
+        && conf->ssl_crl.data == NULL
+        && conf->upstream.ssl_session_reuse == NGX_CONF_UNSET
+        && conf->ssl_conf_commands == NGX_CONF_UNSET_PTR)
+    {
+        if (prev->upstream.ssl) {
+            conf->upstream.ssl = prev->upstream.ssl;
+            return NGX_OK;
+        }
+
+        preserve = 1;
+
+    } else {
+        preserve = 0;
+    }
+
+    conf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
+    if (conf->upstream.ssl == NULL) {
+        return NGX_ERROR;
+    }
+
+    conf->upstream.ssl->log = cf->log;
+
+    /*
+     * special handling to preserve conf->upstream.ssl
+     * in the "http" section to inherit it to all servers
+     */
+
+    if (preserve) {
+        prev->upstream.ssl = conf->upstream.ssl;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_grpc_set_ssl(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *glcf)
 {
     ngx_pool_cleanup_t  *cln;
 
-    glcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
-    if (glcf->upstream.ssl == NULL) {
-        return NGX_ERROR;
+    if (glcf->upstream.ssl->ctx) {
+        return NGX_OK;
     }
 
-    glcf->upstream.ssl->log = cf->log;
-
     if (ngx_ssl_create(glcf->upstream.ssl, glcf->ssl_protocols, NULL)
         != NGX_OK)
     {
diff -r e210c8942a54 -r 9d98d524bd02 src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c	Wed Jun 29 02:47:38 2022 +0300
+++ b/src/http/modules/ngx_http_proxy_module.c	Wed Jun 29 02:47:45 2022 +0300
@@ -236,6 +236,8 @@ static ngx_int_t ngx_http_proxy_rewrite_
     ngx_http_proxy_rewrite_t *pr, ngx_str_t *regex, ngx_uint_t caseless);
 
 #if (NGX_HTTP_SSL)
+static ngx_int_t ngx_http_proxy_merge_ssl(ngx_conf_t *cf,
+    ngx_http_proxy_loc_conf_t *conf, ngx_http_proxy_loc_conf_t *prev);
 static ngx_int_t ngx_http_proxy_set_ssl(ngx_conf_t *cf,
     ngx_http_proxy_loc_conf_t *plcf);
 #endif
@@ -959,7 +961,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 {
@@ -3724,6 +3726,10 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
 
 #if (NGX_HTTP_SSL)
 
+    if (ngx_http_proxy_merge_ssl(cf, conf, prev) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
     ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
                               prev->upstream.ssl_session_reuse, 1);
 
@@ -3857,7 +3863,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,16 +4929,62 @@ ngx_http_proxy_ssl_conf_command_check(ng
 
 
 static ngx_int_t
+ngx_http_proxy_merge_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
+    ngx_http_proxy_loc_conf_t *prev)
+{
+    ngx_uint_t  preserve;
+
+    if (conf->ssl_protocols == 0
+        && conf->ssl_ciphers.data == NULL
+        && conf->upstream.ssl_certificate == NGX_CONF_UNSET_PTR
+        && conf->upstream.ssl_certificate_key == NGX_CONF_UNSET_PTR
+        && conf->upstream.ssl_passwords == NGX_CONF_UNSET_PTR
+        && conf->upstream.ssl_verify == NGX_CONF_UNSET
+        && conf->ssl_verify_depth == NGX_CONF_UNSET_UINT
+        && conf->ssl_trusted_certificate.data == NULL
+        && conf->ssl_crl.data == NULL
+        && conf->upstream.ssl_session_reuse == NGX_CONF_UNSET
+        && conf->ssl_conf_commands == NGX_CONF_UNSET_PTR)
+    {
+        if (prev->upstream.ssl) {
+            conf->upstream.ssl = prev->upstream.ssl;
+            return NGX_OK;
+        }
+
+        preserve = 1;
+
+    } else {
+        preserve = 0;
+    }
+
+    conf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
+    if (conf->upstream.ssl == NULL) {
+        return NGX_ERROR;
+    }
+
+    conf->upstream.ssl->log = cf->log;
+
+    /*
+     * special handling to preserve conf->upstream.ssl
+     * in the "http" section to inherit it to all servers
+     */
+
+    if (preserve) {
+        prev->upstream.ssl = conf->upstream.ssl;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf)
 {
     ngx_pool_cleanup_t  *cln;
 
-    plcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
-    if (plcf->upstream.ssl == NULL) {
-        return NGX_ERROR;
-    }
-
-    plcf->upstream.ssl->log = cf->log;
+    if (plcf->upstream.ssl->ctx) {
+        return NGX_OK;
+    }
 
     if (ngx_ssl_create(plcf->upstream.ssl, plcf->ssl_protocols, NULL)
         != NGX_OK)
diff -r e210c8942a54 -r 9d98d524bd02 src/http/modules/ngx_http_uwsgi_module.c
--- a/src/http/modules/ngx_http_uwsgi_module.c	Wed Jun 29 02:47:38 2022 +0300
+++ b/src/http/modules/ngx_http_uwsgi_module.c	Wed Jun 29 02:47:45 2022 +0300
@@ -96,6 +96,8 @@ static char *ngx_http_uwsgi_ssl_password
     ngx_command_t *cmd, void *conf);
 static char *ngx_http_uwsgi_ssl_conf_command_check(ngx_conf_t *cf, void *post,
     void *data);
+static ngx_int_t ngx_http_uwsgi_merge_ssl(ngx_conf_t *cf,
+    ngx_http_uwsgi_loc_conf_t *conf, ngx_http_uwsgi_loc_conf_t *prev);
 static ngx_int_t ngx_http_uwsgi_set_ssl(ngx_conf_t *cf,
     ngx_http_uwsgi_loc_conf_t *uwcf);
 #endif
@@ -668,7 +670,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://");
@@ -1865,6 +1867,10 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t
 
 #if (NGX_HTTP_SSL)
 
+    if (ngx_http_uwsgi_merge_ssl(cf, conf, prev) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
     ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
                               prev->upstream.ssl_session_reuse, 1);
 
@@ -1927,7 +1933,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,17 +2461,63 @@ ngx_http_uwsgi_ssl_conf_command_check(ng
 
 
 static ngx_int_t
+ngx_http_uwsgi_merge_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
+    ngx_http_uwsgi_loc_conf_t *prev)
+{
+    ngx_uint_t  preserve;
+
+    if (conf->ssl_protocols == 0
+        && conf->ssl_ciphers.data == NULL
+        && conf->upstream.ssl_certificate == NGX_CONF_UNSET_PTR
+        && conf->upstream.ssl_certificate_key == NGX_CONF_UNSET_PTR
+        && conf->upstream.ssl_passwords == NGX_CONF_UNSET_PTR
+        && conf->upstream.ssl_verify == NGX_CONF_UNSET
+        && conf->ssl_verify_depth == NGX_CONF_UNSET_UINT
+        && conf->ssl_trusted_certificate.data == NULL
+        && conf->ssl_crl.data == NULL
+        && conf->upstream.ssl_session_reuse == NGX_CONF_UNSET
+        && conf->ssl_conf_commands == NGX_CONF_UNSET_PTR)
+    {
+        if (prev->upstream.ssl) {
+            conf->upstream.ssl = prev->upstream.ssl;
+            return NGX_OK;
+        }
+
+        preserve = 1;
+
+    } else {
+        preserve = 0;
+    }
+
+    conf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
+    if (conf->upstream.ssl == NULL) {
+        return NGX_ERROR;
+    }
+
+    conf->upstream.ssl->log = cf->log;
+
+    /*
+     * special handling to preserve conf->upstream.ssl
+     * in the "http" section to inherit it to all servers
+     */
+
+    if (preserve) {
+        prev->upstream.ssl = conf->upstream.ssl;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
 {
     ngx_pool_cleanup_t  *cln;
 
-    uwcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
-    if (uwcf->upstream.ssl == NULL) {
-        return NGX_ERROR;
+    if (uwcf->upstream.ssl->ctx) {
+        return NGX_OK;
     }
 
-    uwcf->upstream.ssl->log = cf->log;
-
     if (ngx_ssl_create(uwcf->upstream.ssl, uwcf->ssl_protocols, NULL)
         != NGX_OK)
     {
diff -r e210c8942a54 -r 9d98d524bd02 src/stream/ngx_stream_proxy_module.c
--- a/src/stream/ngx_stream_proxy_module.c	Wed Jun 29 02:47:38 2022 +0300
+++ b/src/stream/ngx_stream_proxy_module.c	Wed Jun 29 02:47:45 2022 +0300
@@ -103,6 +103,8 @@ static void ngx_stream_proxy_ssl_handsha
 static void ngx_stream_proxy_ssl_save_session(ngx_connection_t *c);
 static ngx_int_t ngx_stream_proxy_ssl_name(ngx_stream_session_t *s);
 static ngx_int_t ngx_stream_proxy_ssl_certificate(ngx_stream_session_t *s);
+static ngx_int_t ngx_stream_proxy_merge_ssl(ngx_conf_t *cf,
+    ngx_stream_proxy_srv_conf_t *conf, ngx_stream_proxy_srv_conf_t *prev);
 static ngx_int_t ngx_stream_proxy_set_ssl(ngx_conf_t *cf,
     ngx_stream_proxy_srv_conf_t *pscf);
 
@@ -801,7 +803,7 @@ ngx_stream_proxy_init_upstream(ngx_strea
 
 #if (NGX_STREAM_SSL)
 
-    if (pc->type == SOCK_STREAM && pscf->ssl) {
+    if (pc->type == SOCK_STREAM && pscf->ssl_enable) {
 
         if (u->proxy_protocol) {
             if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) {
@@ -2150,6 +2152,10 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf
 
 #if (NGX_STREAM_SSL)
 
+    if (ngx_stream_proxy_merge_ssl(cf, conf, prev) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
     ngx_conf_merge_value(conf->ssl_enable, prev->ssl_enable, 0);
 
     ngx_conf_merge_value(conf->ssl_session_reuse,
@@ -2199,17 +2205,63 @@ ngx_stream_proxy_merge_srv_conf(ngx_conf
 #if (NGX_STREAM_SSL)
 
 static ngx_int_t
+ngx_stream_proxy_merge_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *conf,
+    ngx_stream_proxy_srv_conf_t *prev)
+{
+    ngx_uint_t  preserve;
+
+    if (conf->ssl_protocols == 0
+        && conf->ssl_ciphers.data == NULL
+        && conf->ssl_certificate == NGX_CONF_UNSET_PTR
+        && conf->ssl_certificate_key == NGX_CONF_UNSET_PTR
+        && conf->ssl_passwords == NGX_CONF_UNSET_PTR
+        && conf->ssl_verify == NGX_CONF_UNSET
+        && conf->ssl_verify_depth == NGX_CONF_UNSET_UINT
+        && conf->ssl_trusted_certificate.data == NULL
+        && conf->ssl_crl.data == NULL
+        && conf->ssl_session_reuse == NGX_CONF_UNSET
+        && conf->ssl_conf_commands == NGX_CONF_UNSET_PTR)
+    {
+        if (prev->ssl) {
+            conf->ssl = prev->ssl;
+            return NGX_OK;
+        }
+
+        preserve = 1;
+
+    } else {
+        preserve = 0;
+    }
+
+    conf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
+    if (conf->ssl == NULL) {
+        return NGX_ERROR;
+    }
+
+    conf->ssl->log = cf->log;
+
+    /*
+     * special handling to preserve conf->ssl
+     * in the "stream" section to inherit it to all servers
+     */
+
+    if (preserve) {
+        prev->ssl = conf->ssl;
+    }
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
 {
     ngx_pool_cleanup_t  *cln;
 
-    pscf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
-    if (pscf->ssl == NULL) {
-        return NGX_ERROR;
+    if (pscf->ssl->ctx) {
+        return NGX_OK;
     }
 
-    pscf->ssl->log = cf->log;
-
     if (ngx_ssl_create(pscf->ssl, pscf->ssl_protocols, NULL) != NGX_OK) {
         return NGX_ERROR;
     }



More information about the nginx-devel mailing list