SSL: caching certificates and certificate keys with variables.

A new directive "ssl_certificate_cache max=N [valid=time] [inactive=time]"
enables caching of SSL certificate chain and secret key objects specified
by "ssl_certificate" and "ssl_certificate_key" directives with variables.

Co-authored-by: Aleksei Bavshin <a.bavshin@nginx.com>
This commit is contained in:
Sergey Kandaurov 2024-10-29 16:25:11 +04:00 committed by pluknet
parent 7677d5646a
commit 0e756d67aa
10 changed files with 481 additions and 68 deletions

View File

@ -562,15 +562,16 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
ngx_int_t
ngx_ssl_connection_certificate(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords)
ngx_str_t *cert, ngx_str_t *key, ngx_ssl_cache_t *cache,
ngx_array_t *passwords)
{
char *err;
X509 *x509;
EVP_PKEY *pkey;
STACK_OF(X509) *chain;
chain = ngx_ssl_cache_connection_fetch(pool, NGX_SSL_CACHE_CERT, &err,
cert, NULL);
chain = ngx_ssl_cache_connection_fetch(cache, pool, NGX_SSL_CACHE_CERT,
&err, cert, NULL);
if (chain == NULL) {
if (err != NULL) {
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
@ -610,8 +611,8 @@ ngx_ssl_connection_certificate(ngx_connection_t *c, ngx_pool_t *pool,
#endif
pkey = ngx_ssl_cache_connection_fetch(pool, NGX_SSL_CACHE_PKEY, &err,
key, passwords);
pkey = ngx_ssl_cache_connection_fetch(cache, pool, NGX_SSL_CACHE_PKEY,
&err, key, passwords);
if (pkey == NULL) {
if (err != NULL) {
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,

View File

@ -83,7 +83,8 @@
#endif
typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t;
typedef struct ngx_ssl_cache_s ngx_ssl_cache_t;
typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t;
struct ngx_ssl_s {
@ -214,7 +215,8 @@ ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords);
ngx_int_t ngx_ssl_connection_certificate(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords);
ngx_str_t *cert, ngx_str_t *key, ngx_ssl_cache_t *cache,
ngx_array_t *passwords);
ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
ngx_uint_t prefer_server_ciphers);
@ -237,10 +239,12 @@ ngx_int_t ngx_ssl_ocsp_get_status(ngx_connection_t *c, const char **s);
void ngx_ssl_ocsp_cleanup(ngx_connection_t *c);
ngx_int_t ngx_ssl_ocsp_cache_init(ngx_shm_zone_t *shm_zone, void *data);
ngx_ssl_cache_t *ngx_ssl_cache_init(ngx_pool_t *pool, ngx_uint_t max,
time_t valid, time_t inactive);
void *ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
ngx_str_t *path, void *data);
void *ngx_ssl_cache_connection_fetch(ngx_pool_t *pool, ngx_uint_t index,
char **err, ngx_str_t *path, void *data);
void *ngx_ssl_cache_connection_fetch(ngx_ssl_cache_t *cache, ngx_pool_t *pool,
ngx_uint_t index, char **err, ngx_str_t *path, void *data);
ngx_array_t *ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file);
ngx_array_t *ngx_ssl_preserve_passwords(ngx_conf_t *cf,

View File

@ -46,21 +46,31 @@ typedef struct {
typedef struct {
ngx_rbtree_node_t node;
ngx_queue_t queue;
ngx_ssl_cache_key_t id;
ngx_ssl_cache_type_t *type;
void *value;
time_t created;
time_t accessed;
time_t mtime;
ngx_file_uniq_t uniq;
} ngx_ssl_cache_node_t;
typedef struct {
struct ngx_ssl_cache_s {
ngx_rbtree_t rbtree;
ngx_rbtree_node_t sentinel;
ngx_queue_t expire_queue;
ngx_flag_t inheritable;
} ngx_ssl_cache_t;
ngx_uint_t current;
ngx_uint_t max;
time_t valid;
time_t inactive;
};
typedef struct {
@ -73,6 +83,8 @@ static ngx_int_t ngx_ssl_cache_init_key(ngx_pool_t *pool, ngx_uint_t index,
ngx_str_t *path, ngx_ssl_cache_key_t *id);
static ngx_ssl_cache_node_t *ngx_ssl_cache_lookup(ngx_ssl_cache_t *cache,
ngx_ssl_cache_type_t *type, ngx_ssl_cache_key_t *id, uint32_t hash);
static void ngx_ssl_cache_expire(ngx_ssl_cache_t *cache, ngx_uint_t n,
ngx_log_t *log);
static void *ngx_ssl_cache_cert_create(ngx_ssl_cache_key_t *id, char **err,
void *data);
@ -101,6 +113,8 @@ static char *ngx_openssl_cache_init_conf(ngx_cycle_t *cycle, void *conf);
static void ngx_ssl_cache_cleanup(void *data);
static void ngx_ssl_cache_node_insert(ngx_rbtree_node_t *temp,
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
static void ngx_ssl_cache_node_free(ngx_rbtree_t *rbtree,
ngx_ssl_cache_node_t *cn);
static ngx_command_t ngx_openssl_cache_commands[] = {
@ -260,6 +274,8 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
ngx_cpystrn(cn->id.data, id.data, id.len + 1);
ngx_queue_init(&cn->queue);
ngx_rbtree_insert(&cache->rbtree, &cn->node);
return type->ref(err, cn->value);
@ -267,10 +283,15 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
void *
ngx_ssl_cache_connection_fetch(ngx_pool_t *pool, ngx_uint_t index, char **err,
ngx_str_t *path, void *data)
ngx_ssl_cache_connection_fetch(ngx_ssl_cache_t *cache, ngx_pool_t *pool,
ngx_uint_t index, char **err, ngx_str_t *path, void *data)
{
ngx_ssl_cache_key_t id;
void *value;
time_t now;
uint32_t hash;
ngx_ssl_cache_key_t id;
ngx_ssl_cache_type_t *type;
ngx_ssl_cache_node_t *cn;
*err = NULL;
@ -278,7 +299,89 @@ ngx_ssl_cache_connection_fetch(ngx_pool_t *pool, ngx_uint_t index, char **err,
return NULL;
}
return ngx_ssl_cache_types[index].create(&id, err, &data);
type = &ngx_ssl_cache_types[index];
if (cache == NULL) {
return type->create(&id, err, &data);
}
now = ngx_time();
hash = ngx_murmur_hash2(id.data, id.len);
cn = ngx_ssl_cache_lookup(cache, type, &id, hash);
if (cn != NULL) {
ngx_queue_remove(&cn->queue);
if (id.type == NGX_SSL_CACHE_DATA) {
goto found;
}
if (now - cn->created > cache->valid) {
ngx_log_debug1(NGX_LOG_DEBUG_CORE, pool->log, 0,
"update cached ssl object: %s", cn->id.data);
type->free(cn->value);
value = type->create(&id, err, &data);
if (value == NULL || data == NGX_SSL_CACHE_DISABLED) {
ngx_rbtree_delete(&cache->rbtree, &cn->node);
cache->current--;
ngx_free(cn);
return value;
}
cn->value = value;
cn->created = now;
}
goto found;
}
value = type->create(&id, err, &data);
if (value == NULL || data == NGX_SSL_CACHE_DISABLED) {
return value;
}
cn = ngx_alloc(sizeof(ngx_ssl_cache_node_t) + id.len + 1, pool->log);
if (cn == NULL) {
type->free(value);
return NULL;
}
cn->node.key = hash;
cn->id.data = (u_char *)(cn + 1);
cn->id.len = id.len;
cn->id.type = id.type;
cn->type = type;
cn->value = value;
cn->created = now;
ngx_cpystrn(cn->id.data, id.data, id.len + 1);
ngx_ssl_cache_expire(cache, 1, pool->log);
if (cache->current >= cache->max) {
ngx_ssl_cache_expire(cache, 0, pool->log);
}
ngx_rbtree_insert(&cache->rbtree, &cn->node);
cache->current++;
found:
cn->accessed = now;
ngx_queue_insert_head(&cache->expire_queue, &cn->queue);
return type->ref(err, cn->value);
}
@ -365,6 +468,37 @@ ngx_ssl_cache_lookup(ngx_ssl_cache_t *cache, ngx_ssl_cache_type_t *type,
}
static void
ngx_ssl_cache_expire(ngx_ssl_cache_t *cache, ngx_uint_t n,
ngx_log_t *log)
{
time_t now;
ngx_queue_t *q;
ngx_ssl_cache_node_t *cn;
now = ngx_time();
while (n < 3) {
if (ngx_queue_empty(&cache->expire_queue)) {
return;
}
q = ngx_queue_last(&cache->expire_queue);
cn = ngx_queue_data(q, ngx_ssl_cache_node_t, queue);
if (n++ != 0 && now - cn->accessed <= cache->inactive) {
return;
}
ngx_ssl_cache_node_free(&cache->rbtree, cn);
cache->current--;
}
}
static void *
ngx_ssl_cache_cert_create(ngx_ssl_cache_key_t *id, char **err, void *data)
{
@ -822,27 +956,15 @@ ngx_ssl_cache_create_bio(ngx_ssl_cache_key_t *id, char **err)
static void *
ngx_openssl_cache_create_conf(ngx_cycle_t *cycle)
{
ngx_ssl_cache_t *cache;
ngx_pool_cleanup_t *cln;
ngx_ssl_cache_t *cache;
cache = ngx_pcalloc(cycle->pool, sizeof(ngx_ssl_cache_t));
cache = ngx_ssl_cache_init(cycle->pool, 0, 0, 0);
if (cache == NULL) {
return NULL;
}
cache->inheritable = NGX_CONF_UNSET;
cln = ngx_pool_cleanup_add(cycle->pool, 0);
if (cln == NULL) {
return NULL;
}
cln->handler = ngx_ssl_cache_cleanup;
cln->data = cache;
ngx_rbtree_init(&cache->rbtree, &cache->sentinel,
ngx_ssl_cache_node_insert);
return cache;
}
@ -858,6 +980,39 @@ ngx_openssl_cache_init_conf(ngx_cycle_t *cycle, void *conf)
}
ngx_ssl_cache_t *
ngx_ssl_cache_init(ngx_pool_t *pool, ngx_uint_t max, time_t valid,
time_t inactive)
{
ngx_ssl_cache_t *cache;
ngx_pool_cleanup_t *cln;
cache = ngx_pcalloc(pool, sizeof(ngx_ssl_cache_t));
if (cache == NULL) {
return NULL;
}
ngx_rbtree_init(&cache->rbtree, &cache->sentinel,
ngx_ssl_cache_node_insert);
ngx_queue_init(&cache->expire_queue);
cache->max = max;
cache->valid = valid;
cache->inactive = inactive;
cln = ngx_pool_cleanup_add(pool, 0);
if (cln == NULL) {
return NULL;
}
cln->handler = ngx_ssl_cache_cleanup;
cln->data = cache;
return cache;
}
static void
ngx_ssl_cache_cleanup(void *data)
{
@ -873,12 +1028,47 @@ ngx_ssl_cache_cleanup(void *data)
return;
}
for (node = ngx_rbtree_min(tree->root, tree->sentinel);
node;
node = ngx_rbtree_next(tree, node))
{
node = ngx_rbtree_min(tree->root, tree->sentinel);
while (node != NULL) {
cn = ngx_rbtree_data(node, ngx_ssl_cache_node_t, node);
cn->type->free(cn->value);
node = ngx_rbtree_next(tree, node);
ngx_ssl_cache_node_free(tree, cn);
if (cache->max) {
cache->current--;
}
}
if (cache->current) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
"%ui items still left in ssl cache",
cache->current);
}
if (!ngx_queue_empty(&cache->expire_queue)) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
"queue still is not empty in ssl cache");
}
}
static void
ngx_ssl_cache_node_free(ngx_rbtree_t *rbtree, ngx_ssl_cache_node_t *cn)
{
cn->type->free(cn->value);
ngx_rbtree_delete(rbtree, &cn->node);
if (!ngx_queue_empty(&cn->queue)) {
ngx_queue_remove(&cn->queue);
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
"delete cached ssl object: %s", cn->id.data);
ngx_free(cn);
}
}

View File

@ -43,6 +43,8 @@ static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf,
static ngx_int_t ngx_http_ssl_compile_certificates(ngx_conf_t *cf,
ngx_http_ssl_srv_conf_t *conf);
static char *ngx_http_ssl_certificate_cache(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
@ -108,6 +110,13 @@ static ngx_command_t ngx_http_ssl_commands[] = {
offsetof(ngx_http_ssl_srv_conf_t, certificate_keys),
NULL },
{ ngx_string("ssl_certificate_cache"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE123,
ngx_http_ssl_certificate_cache,
NGX_HTTP_SRV_CONF_OFFSET,
0,
NULL },
{ ngx_string("ssl_password_file"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
ngx_http_ssl_password_file,
@ -619,6 +628,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
sscf->verify_depth = NGX_CONF_UNSET_UINT;
sscf->certificates = NGX_CONF_UNSET_PTR;
sscf->certificate_keys = NGX_CONF_UNSET_PTR;
sscf->certificate_cache = NGX_CONF_UNSET_PTR;
sscf->passwords = NGX_CONF_UNSET_PTR;
sscf->conf_commands = NGX_CONF_UNSET_PTR;
sscf->builtin_session_cache = NGX_CONF_UNSET;
@ -664,6 +674,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys,
NULL);
ngx_conf_merge_ptr_value(conf->certificate_cache, prev->certificate_cache,
NULL);
ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
@ -984,6 +997,99 @@ found:
}
static char *
ngx_http_ssl_certificate_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_ssl_srv_conf_t *sscf = conf;
time_t inactive, valid;
ngx_str_t *value, s;
ngx_int_t max;
ngx_uint_t i;
if (sscf->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) {
sscf->certificate_cache = NULL;
continue;
}
failed:
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%V\"", &value[i]);
return NGX_CONF_ERROR;
}
if (sscf->certificate_cache == NULL) {
return NGX_CONF_OK;
}
if (max == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"ssl_certificate_cache\" must have "
"the \"max\" parameter");
return NGX_CONF_ERROR;
}
sscf->certificate_cache = ngx_ssl_cache_init(cf->pool, max, valid,
inactive);
if (sscf->certificate_cache == NULL) {
return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
static char *
ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{

View File

@ -38,6 +38,8 @@ typedef struct {
ngx_array_t *certificate_values;
ngx_array_t *certificate_key_values;
ngx_ssl_cache_t *certificate_cache;
ngx_str_t dhparam;
ngx_str_t ecdh_curve;
ngx_str_t client_certificate;

View File

@ -1054,6 +1054,7 @@ ngx_http_ssl_certificate(ngx_ssl_conn_t *ssl_conn, void *arg)
"ssl key: \"%s\"", key.data);
if (ngx_ssl_connection_certificate(c, r->pool, &cert, &key,
sscf->certificate_cache,
sscf->passwords)
!= NGX_OK)
{

View File

@ -2018,7 +2018,7 @@ ngx_http_upstream_ssl_certificate(ngx_http_request_t *r,
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,
if (ngx_ssl_connection_certificate(c, r->pool, &cert, &key, NULL,
u->conf->ssl_passwords)
!= NGX_OK)
{

View File

@ -1324,7 +1324,7 @@ ngx_stream_proxy_ssl_certificate(ngx_stream_session_t *s)
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,
if (ngx_ssl_connection_certificate(c, c->pool, &cert, &key, NULL,
pscf->ssl_passwords)
!= NGX_OK)
{

View File

@ -47,6 +47,8 @@ static char *ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent,
static ngx_int_t ngx_stream_ssl_compile_certificates(ngx_conf_t *cf,
ngx_stream_ssl_srv_conf_t *conf);
static char *ngx_stream_ssl_certificate_cache(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);
static char *ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
@ -117,6 +119,13 @@ static ngx_command_t ngx_stream_ssl_commands[] = {
offsetof(ngx_stream_ssl_srv_conf_t, certificate_keys),
NULL },
{ ngx_string("ssl_certificate_cache"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE123,
ngx_stream_ssl_certificate_cache,
NGX_STREAM_SRV_CONF_OFFSET,
0,
NULL },
{ ngx_string("ssl_password_file"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
ngx_stream_ssl_password_file,
@ -718,6 +727,7 @@ ngx_stream_ssl_certificate(ngx_ssl_conn_t *ssl_conn, void *arg)
"ssl key: \"%s\"", key.data);
if (ngx_ssl_connection_certificate(c, c->pool, &cert, &key,
sscf->certificate_cache,
sscf->passwords)
!= NGX_OK)
{
@ -844,6 +854,7 @@ ngx_stream_ssl_create_srv_conf(ngx_conf_t *cf)
sscf->handshake_timeout = NGX_CONF_UNSET_MSEC;
sscf->certificates = NGX_CONF_UNSET_PTR;
sscf->certificate_keys = NGX_CONF_UNSET_PTR;
sscf->certificate_cache = NGX_CONF_UNSET_PTR;
sscf->passwords = NGX_CONF_UNSET_PTR;
sscf->conf_commands = NGX_CONF_UNSET_PTR;
sscf->prefer_server_ciphers = NGX_CONF_UNSET;
@ -892,6 +903,9 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys,
NULL);
ngx_conf_merge_ptr_value(conf->certificate_cache, prev->certificate_cache,
NULL);
ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
@ -1202,6 +1216,99 @@ found:
}
static char *
ngx_stream_ssl_certificate_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_stream_ssl_srv_conf_t *sscf = conf;
time_t inactive, valid;
ngx_str_t *value, s;
ngx_int_t max;
ngx_uint_t i;
if (sscf->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) {
sscf->certificate_cache = NULL;
continue;
}
failed:
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%V\"", &value[i]);
return NGX_CONF_ERROR;
}
if (sscf->certificate_cache == NULL) {
return NGX_CONF_OK;
}
if (max == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"ssl_certificate_cache\" must have "
"the \"max\" parameter");
return NGX_CONF_ERROR;
}
sscf->certificate_cache = ngx_ssl_cache_init(cf->pool, max, valid,
inactive);
if (sscf->certificate_cache == NULL) {
return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
static char *
ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{

View File

@ -15,53 +15,55 @@
typedef struct {
ngx_msec_t handshake_timeout;
ngx_msec_t handshake_timeout;
ngx_flag_t prefer_server_ciphers;
ngx_flag_t reject_handshake;
ngx_flag_t prefer_server_ciphers;
ngx_flag_t reject_handshake;
ngx_ssl_t ssl;
ngx_ssl_t ssl;
ngx_uint_t protocols;
ngx_uint_t protocols;
ngx_uint_t verify;
ngx_uint_t verify_depth;
ngx_uint_t verify;
ngx_uint_t verify_depth;
ssize_t builtin_session_cache;
ssize_t builtin_session_cache;
time_t session_timeout;
time_t session_timeout;
ngx_array_t *certificates;
ngx_array_t *certificate_keys;
ngx_array_t *certificates;
ngx_array_t *certificate_keys;
ngx_array_t *certificate_values;
ngx_array_t *certificate_key_values;
ngx_array_t *certificate_values;
ngx_array_t *certificate_key_values;
ngx_str_t dhparam;
ngx_str_t ecdh_curve;
ngx_str_t client_certificate;
ngx_str_t trusted_certificate;
ngx_str_t crl;
ngx_str_t alpn;
ngx_ssl_cache_t *certificate_cache;
ngx_str_t ciphers;
ngx_str_t dhparam;
ngx_str_t ecdh_curve;
ngx_str_t client_certificate;
ngx_str_t trusted_certificate;
ngx_str_t crl;
ngx_str_t alpn;
ngx_array_t *passwords;
ngx_array_t *conf_commands;
ngx_str_t ciphers;
ngx_shm_zone_t *shm_zone;
ngx_array_t *passwords;
ngx_array_t *conf_commands;
ngx_flag_t session_tickets;
ngx_array_t *session_ticket_keys;
ngx_shm_zone_t *shm_zone;
ngx_uint_t ocsp;
ngx_str_t ocsp_responder;
ngx_shm_zone_t *ocsp_cache_zone;
ngx_flag_t session_tickets;
ngx_array_t *session_ticket_keys;
ngx_flag_t stapling;
ngx_flag_t stapling_verify;
ngx_str_t stapling_file;
ngx_str_t stapling_responder;
ngx_uint_t ocsp;
ngx_str_t ocsp_responder;
ngx_shm_zone_t *ocsp_cache_zone;
ngx_flag_t stapling;
ngx_flag_t stapling_verify;
ngx_str_t stapling_file;
ngx_str_t stapling_responder;
} ngx_stream_ssl_srv_conf_t;