Caching is enabled with proxy_ssl_certificate_cache and friends.
Co-authored-by: Aleksei Bavshin <a.bavshin@nginx.com>
void *conf);
#if (NGX_HTTP_SSL)
+static char *ngx_http_grpc_ssl_certificate_cache(ngx_conf_t *cf,
+ ngx_command_t *cmd, void *conf);
static char *ngx_http_grpc_ssl_password_file(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);
static char *ngx_http_grpc_ssl_conf_command_check(ngx_conf_t *cf, void *post,
offsetof(ngx_http_grpc_loc_conf_t, upstream.ssl_certificate_key),
NULL },
+ { ngx_string("grpc_ssl_certificate_cache"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
+ ngx_http_grpc_ssl_certificate_cache,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
{ ngx_string("grpc_ssl_password_file"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_grpc_ssl_password_file,
conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
conf->upstream.ssl_certificate = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_certificate_key = NGX_CONF_UNSET_PTR;
+ conf->upstream.ssl_certificate_cache = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_passwords = NGX_CONF_UNSET_PTR;
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
#endif
prev->upstream.ssl_certificate, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_key,
prev->upstream.ssl_certificate_key, NULL);
+ ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_cache,
+ prev->upstream.ssl_certificate_cache, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_passwords,
prev->upstream.ssl_passwords, NULL);
#if (NGX_HTTP_SSL)
+static char *
+ngx_http_grpc_ssl_certificate_cache(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf)
+{
+ ngx_http_grpc_loc_conf_t *plcf = conf;
+
+ time_t inactive, valid;
+ ngx_str_t *value, s;
+ ngx_int_t max;
+ ngx_uint_t i;
+
+ if (plcf->upstream.ssl_certificate_cache != NGX_CONF_UNSET_PTR) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ max = 0;
+ inactive = 10;
+ valid = 60;
+
+ for (i = 1; i < cf->args->nelts; i++) {
+
+ if (ngx_strncmp(value[i].data, "max=", 4) == 0) {
+
+ max = ngx_atoi(value[i].data + 4, value[i].len - 4);
+ if (max <= 0) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
+
+ s.len = value[i].len - 9;
+ s.data = value[i].data + 9;
+
+ inactive = ngx_parse_time(&s, 1);
+ if (inactive == (time_t) NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "valid=", 6) == 0) {
+
+ s.len = value[i].len - 6;
+ s.data = value[i].data + 6;
+
+ valid = ngx_parse_time(&s, 1);
+ if (valid == (time_t) NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strcmp(value[i].data, "off") == 0) {
+
+ plcf->upstream.ssl_certificate_cache = NULL;
+
+ continue;
+ }
+
+ failed:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (plcf->upstream.ssl_certificate_cache == NULL) {
+ return NGX_CONF_OK;
+ }
+
+ if (max == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"grpc_ssl_certificate_cache\" must have "
+ "the \"max\" parameter");
+ return NGX_CONF_ERROR;
+ }
+
+ plcf->upstream.ssl_certificate_cache = ngx_ssl_cache_init(cf->pool, max,
+ valid, inactive);
+ if (plcf->upstream.ssl_certificate_cache == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
static char *
ngx_http_grpc_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
void *conf);
#endif
#if (NGX_HTTP_SSL)
+static char *ngx_http_proxy_ssl_certificate_cache(ngx_conf_t *cf,
+ ngx_command_t *cmd, void *conf);
static char *ngx_http_proxy_ssl_password_file(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);
#endif
offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_certificate_key),
NULL },
+ { ngx_string("proxy_ssl_certificate_cache"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
+ ngx_http_proxy_ssl_certificate_cache,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
{ ngx_string("proxy_ssl_password_file"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_proxy_ssl_password_file,
conf->upstream.ssl_verify = NGX_CONF_UNSET;
conf->upstream.ssl_certificate = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_certificate_key = NGX_CONF_UNSET_PTR;
+ conf->upstream.ssl_certificate_cache = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_passwords = NGX_CONF_UNSET_PTR;
conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
prev->upstream.ssl_certificate, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_key,
prev->upstream.ssl_certificate_key, NULL);
+ ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_cache,
+ prev->upstream.ssl_certificate_cache, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_passwords,
prev->upstream.ssl_passwords, NULL);
#if (NGX_HTTP_SSL)
+static char *
+ngx_http_proxy_ssl_certificate_cache(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf)
+{
+ ngx_http_proxy_loc_conf_t *plcf = conf;
+
+ time_t inactive, valid;
+ ngx_str_t *value, s;
+ ngx_int_t max;
+ ngx_uint_t i;
+
+ if (plcf->upstream.ssl_certificate_cache != NGX_CONF_UNSET_PTR) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ max = 0;
+ inactive = 10;
+ valid = 60;
+
+ for (i = 1; i < cf->args->nelts; i++) {
+
+ if (ngx_strncmp(value[i].data, "max=", 4) == 0) {
+
+ max = ngx_atoi(value[i].data + 4, value[i].len - 4);
+ if (max <= 0) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
+
+ s.len = value[i].len - 9;
+ s.data = value[i].data + 9;
+
+ inactive = ngx_parse_time(&s, 1);
+ if (inactive == (time_t) NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "valid=", 6) == 0) {
+
+ s.len = value[i].len - 6;
+ s.data = value[i].data + 6;
+
+ valid = ngx_parse_time(&s, 1);
+ if (valid == (time_t) NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strcmp(value[i].data, "off") == 0) {
+
+ plcf->upstream.ssl_certificate_cache = NULL;
+
+ continue;
+ }
+
+ failed:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (plcf->upstream.ssl_certificate_cache == NULL) {
+ return NGX_CONF_OK;
+ }
+
+ if (max == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"proxy_ssl_certificate_cache\" must have "
+ "the \"max\" parameter");
+ return NGX_CONF_ERROR;
+ }
+
+ plcf->upstream.ssl_certificate_cache = ngx_ssl_cache_init(cf->pool, max,
+ valid, inactive);
+ if (plcf->upstream.ssl_certificate_cache == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
static char *
ngx_http_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
#endif
#if (NGX_HTTP_SSL)
+static char *ngx_http_uwsgi_ssl_certificate_cache(ngx_conf_t *cf,
+ ngx_command_t *cmd, void *conf);
static char *ngx_http_uwsgi_ssl_password_file(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);
static char *ngx_http_uwsgi_ssl_conf_command_check(ngx_conf_t *cf, void *post,
offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_certificate_key),
NULL },
+ { ngx_string("uwsgi_ssl_certificate_cache"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
+ ngx_http_uwsgi_ssl_certificate_cache,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
{ ngx_string("uwsgi_ssl_password_file"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_uwsgi_ssl_password_file,
conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
conf->upstream.ssl_certificate = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_certificate_key = NGX_CONF_UNSET_PTR;
+ conf->upstream.ssl_certificate_cache = NGX_CONF_UNSET_PTR;
conf->upstream.ssl_passwords = NGX_CONF_UNSET_PTR;
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
#endif
prev->upstream.ssl_certificate, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_key,
prev->upstream.ssl_certificate_key, NULL);
+ ngx_conf_merge_ptr_value(conf->upstream.ssl_certificate_cache,
+ prev->upstream.ssl_certificate_cache, NULL);
ngx_conf_merge_ptr_value(conf->upstream.ssl_passwords,
prev->upstream.ssl_passwords, NULL);
#if (NGX_HTTP_SSL)
+static char *
+ngx_http_uwsgi_ssl_certificate_cache(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf)
+{
+ ngx_http_uwsgi_loc_conf_t *plcf = conf;
+
+ time_t inactive, valid;
+ ngx_str_t *value, s;
+ ngx_int_t max;
+ ngx_uint_t i;
+
+ if (plcf->upstream.ssl_certificate_cache != NGX_CONF_UNSET_PTR) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ max = 0;
+ inactive = 10;
+ valid = 60;
+
+ for (i = 1; i < cf->args->nelts; i++) {
+
+ if (ngx_strncmp(value[i].data, "max=", 4) == 0) {
+
+ max = ngx_atoi(value[i].data + 4, value[i].len - 4);
+ if (max <= 0) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
+
+ s.len = value[i].len - 9;
+ s.data = value[i].data + 9;
+
+ inactive = ngx_parse_time(&s, 1);
+ if (inactive == (time_t) NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "valid=", 6) == 0) {
+
+ s.len = value[i].len - 6;
+ s.data = value[i].data + 6;
+
+ valid = ngx_parse_time(&s, 1);
+ if (valid == (time_t) NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strcmp(value[i].data, "off") == 0) {
+
+ plcf->upstream.ssl_certificate_cache = NULL;
+
+ continue;
+ }
+
+ failed:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (plcf->upstream.ssl_certificate_cache == NULL) {
+ return NGX_CONF_OK;
+ }
+
+ if (max == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"uwsgi_ssl_certificate_cache\" must have "
+ "the \"max\" parameter");
+ return NGX_CONF_ERROR;
+ }
+
+ plcf->upstream.ssl_certificate_cache = ngx_ssl_cache_init(cf->pool, max,
+ valid, inactive);
+ if (plcf->upstream.ssl_certificate_cache == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
static char *
ngx_http_uwsgi_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http upstream ssl key: \"%s\"", key.data);
- if (ngx_ssl_connection_certificate(c, r->pool, &cert, &key, NULL,
+ if (ngx_ssl_connection_certificate(c, r->pool, &cert, &key,
+ u->conf->ssl_certificate_cache,
u->conf->ssl_passwords)
!= NGX_OK)
{
ngx_http_complex_value_t *ssl_certificate;
ngx_http_complex_value_t *ssl_certificate_key;
+ ngx_ssl_cache_t *ssl_certificate_cache;
ngx_array_t *ssl_passwords;
#endif
ngx_str_t ssl_crl;
ngx_stream_complex_value_t *ssl_certificate;
ngx_stream_complex_value_t *ssl_certificate_key;
+ ngx_ssl_cache_t *ssl_certificate_cache;
ngx_array_t *ssl_passwords;
ngx_array_t *ssl_conf_commands;
#if (NGX_STREAM_SSL)
static ngx_int_t ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s);
+static char *ngx_stream_proxy_ssl_certificate_cache(ngx_conf_t *cf,
+ ngx_command_t *cmd, void *conf);
static char *ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);
static char *ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post,
offsetof(ngx_stream_proxy_srv_conf_t, ssl_certificate_key),
NULL },
+ { ngx_string("proxy_ssl_certificate_cache"),
+ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE123,
+ ngx_stream_proxy_ssl_certificate_cache,
+ NGX_STREAM_SRV_CONF_OFFSET,
+ 0,
+ NULL },
+
{ ngx_string("proxy_ssl_password_file"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
ngx_stream_proxy_ssl_password_file,
}
+static char *
+ngx_stream_proxy_ssl_certificate_cache(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf)
+{
+ ngx_stream_proxy_srv_conf_t *pscf = conf;
+
+ time_t inactive, valid;
+ ngx_str_t *value, s;
+ ngx_int_t max;
+ ngx_uint_t i;
+
+ if (pscf->ssl_certificate_cache != NGX_CONF_UNSET_PTR) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ max = 0;
+ inactive = 10;
+ valid = 60;
+
+ for (i = 1; i < cf->args->nelts; i++) {
+
+ if (ngx_strncmp(value[i].data, "max=", 4) == 0) {
+
+ max = ngx_atoi(value[i].data + 4, value[i].len - 4);
+ if (max <= 0) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
+
+ s.len = value[i].len - 9;
+ s.data = value[i].data + 9;
+
+ inactive = ngx_parse_time(&s, 1);
+ if (inactive == (time_t) NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strncmp(value[i].data, "valid=", 6) == 0) {
+
+ s.len = value[i].len - 6;
+ s.data = value[i].data + 6;
+
+ valid = ngx_parse_time(&s, 1);
+ if (valid == (time_t) NGX_ERROR) {
+ goto failed;
+ }
+
+ continue;
+ }
+
+ if (ngx_strcmp(value[i].data, "off") == 0) {
+
+ pscf->ssl_certificate_cache = NULL;
+
+ continue;
+ }
+
+ failed:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (pscf->ssl_certificate_cache == NULL) {
+ return NGX_CONF_OK;
+ }
+
+ if (max == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"proxy_ssl_certificate_cache\" must have "
+ "the \"max\" parameter");
+ return NGX_CONF_ERROR;
+ }
+
+ pscf->ssl_certificate_cache = ngx_ssl_cache_init(cf->pool, max, valid,
+ inactive);
+ if (pscf->ssl_certificate_cache == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
static char *
ngx_stream_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
"stream upstream ssl key: \"%s\"", key.data);
- if (ngx_ssl_connection_certificate(c, c->pool, &cert, &key, NULL,
+ if (ngx_ssl_connection_certificate(c, c->pool, &cert, &key,
+ pscf->ssl_certificate_cache,
pscf->ssl_passwords)
!= NGX_OK)
{
conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
conf->ssl_certificate = NGX_CONF_UNSET_PTR;
conf->ssl_certificate_key = NGX_CONF_UNSET_PTR;
+ conf->ssl_certificate_cache = NGX_CONF_UNSET_PTR;
conf->ssl_passwords = NGX_CONF_UNSET_PTR;
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
#endif
ngx_conf_merge_ptr_value(conf->ssl_certificate_key,
prev->ssl_certificate_key, NULL);
+ ngx_conf_merge_ptr_value(conf->ssl_certificate_cache,
+ prev->ssl_certificate_cache, NULL);
+
ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
ngx_conf_merge_ptr_value(conf->ssl_conf_commands,