# HG changeset patch # User Vladimir Homutov # Date 1600199086 -10800 # Node ID 7621ffaa79b3d039582e3d929bbca60027207f62 # Parent 02ee77f8d53df0f2a799dfb0b5c169968ec71ee1 SSL: added the "ssl_keys_file" directive. diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -255,6 +255,50 @@ ngx_ssl_init(ngx_log_t *log) } +void +ngx_ssl_keylogger(const ngx_ssl_conn_t *ssl_conn, const char *line) +{ + u_char *p; + size_t len; + ssize_t n; + ngx_connection_t *c; + ngx_ssl_connection_t *sc; + + if (line == NULL) { + return; + } + + len = ngx_strlen(line); + + if (len == 0) { + return; + } + + c = ngx_ssl_get_connection(ssl_conn); + sc = c->ssl; + + p = ngx_alloc(len + 1, c->log); + if (p == NULL) { + return; + } + + ngx_memcpy(p, line, len); + p[len] = '\n'; + + n = ngx_write_fd(sc->keylog->fd, p, len + 1); + if (n == -1) { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, + ngx_write_fd_n " to \"%s\" failed", + sc->keylog->name.data); + + } else if ((size_t) n != len + 1) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz", + sc->keylog->name.data, n, len + 1); + } +} + + ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data) { @@ -1516,6 +1560,8 @@ ngx_ssl_create_connection(ngx_ssl_t *ssl return NGX_ERROR; } + sc->keylog = ssl->keylog; + sc->buffer = ((flags & NGX_SSL_BUFFER) != 0); sc->buffer_size = ssl->buffer_size; diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -78,6 +78,7 @@ struct ngx_ssl_s { SSL_CTX *ctx; ngx_log_t *log; size_t buffer_size; + ngx_open_file_t *keylog; }; @@ -100,6 +101,7 @@ struct ngx_ssl_connection_s { ngx_ssl_ocsp_t *ocsp; u_char early_buf; + ngx_open_file_t *keylog; unsigned handshaked:1; unsigned renegotiation:1; @@ -296,6 +298,7 @@ ngx_int_t ngx_ssl_shutdown(ngx_connectio void ngx_cdecl ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...); void ngx_ssl_cleanup_ctx(void *data); +void ngx_ssl_keylogger(const ngx_ssl_conn_t *ssl, const char *line); extern int ngx_ssl_connection_index; diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -119,6 +119,13 @@ static ngx_command_t ngx_http_ssl_comma 0, NULL }, + { ngx_string("ssl_keys_file"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_ssl_srv_conf_t, keys_file), + NULL }, + { ngx_string("ssl_dhparam"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -605,6 +612,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t * sscf->trusted_certificate = { 0, NULL }; * sscf->crl = { 0, NULL }; * sscf->ciphers = { 0, NULL }; + * sscf->keys_file = { 0, NULL }; * sscf->shm_zone = NULL; * sscf->ocsp_responder = { 0, NULL }; * sscf->stapling_file = { 0, NULL }; @@ -676,6 +684,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL); + ngx_conf_merge_str_value(conf->keys_file, prev->keys_file, ""); + ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, ""); ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate, @@ -912,6 +922,17 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * return NGX_CONF_ERROR; } + if (conf->keys_file.len) { + + conf->ssl.keylog = ngx_conf_open_file(cf->cycle, &conf->keys_file); + + if (conf->ssl.keylog == NULL) { + return NGX_CONF_ERROR; + } + + SSL_CTX_set_keylog_callback(conf->ssl.ctx, ngx_ssl_keylogger); + } + if (conf->stapling) { if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file, diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h --- a/src/http/modules/ngx_http_ssl_module.h +++ b/src/http/modules/ngx_http_ssl_module.h @@ -36,6 +36,8 @@ typedef struct { ngx_array_t *certificates; ngx_array_t *certificate_keys; + ngx_str_t keys_file; + ngx_array_t *certificate_values; ngx_array_t *certificate_key_values;