Skip to content

Commit 65daf1a

Browse files
committed
feature: implemented ssl_session_fetch_by_lua* and ssl_session_store_by_lua* config directives for doing (distributed) caching of SSL sessions (via SSL session IDs) for downstream connections.
thanks Zi Lin for the patches.
1 parent a5ac9fa commit 65daf1a

23 files changed

+3727
-238
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ src/timer.[ch]
154154
src/config.[ch]
155155
src/worker.[ch]
156156
src/certby.[ch]
157+
src/storeby.[ch]
158+
src/fetchby.[ch]
159+
src/ssl.[ch]
157160
src/ocsp.c
158161
src/lex.[ch]
159162
src/balancer.[ch]

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ script:
107107
- cd ..
108108
- tar zxf download-cache/openssl-$OPENSSL_VER.tar.gz
109109
- cd openssl-$OPENSSL_VER/
110+
- wget https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-$OPENSSL_VER-sess_set_get_cb_yield.patch
111+
- patch -p1 < openssl-$OPENSSL_VER-sess_set_get_cb_yield.patch
110112
- ./config shared --prefix=$OPENSSL_PREFIX -DPURIFY > build.log 2>&1 || (cat build.log && exit 1)
111113
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
112114
- sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1)

README.markdown

Lines changed: 193 additions & 79 deletions
Large diffs are not rendered by default.

config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,9 @@ HTTP_LUA_SRCS=" \
357357
$ngx_addon_dir/src/ngx_http_lua_ssl_ocsp.c \
358358
$ngx_addon_dir/src/ngx_http_lua_lex.c \
359359
$ngx_addon_dir/src/ngx_http_lua_balancer.c \
360+
$ngx_addon_dir/src/ngx_http_lua_ssl_session_storeby.c \
361+
$ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.c \
362+
$ngx_addon_dir/src/ngx_http_lua_ssl.c \
360363
"
361364

362365
HTTP_LUA_DEPS=" \
@@ -414,6 +417,9 @@ HTTP_LUA_DEPS=" \
414417
$ngx_addon_dir/src/ngx_http_lua_ssl_certby.h \
415418
$ngx_addon_dir/src/ngx_http_lua_lex.h \
416419
$ngx_addon_dir/src/ngx_http_lua_balancer.h \
420+
$ngx_addon_dir/src/ngx_http_lua_ssl_session_storeby.h \
421+
$ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.h \
422+
$ngx_addon_dir/src/ngx_http_lua_ssl.h \
417423
"
418424

419425
CFLAGS="$CFLAGS -DNDK_SET_VAR"

doc/HttpLuaModule.wiki

Lines changed: 177 additions & 79 deletions
Large diffs are not rendered by default.

src/ngx_http_lua_common.h

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,19 @@ typedef struct {
103103

104104

105105
/* must be within 16 bit */
106-
#define NGX_HTTP_LUA_CONTEXT_SET 0x001
107-
#define NGX_HTTP_LUA_CONTEXT_REWRITE 0x002
108-
#define NGX_HTTP_LUA_CONTEXT_ACCESS 0x004
109-
#define NGX_HTTP_LUA_CONTEXT_CONTENT 0x008
110-
#define NGX_HTTP_LUA_CONTEXT_LOG 0x010
111-
#define NGX_HTTP_LUA_CONTEXT_HEADER_FILTER 0x020
112-
#define NGX_HTTP_LUA_CONTEXT_BODY_FILTER 0x040
113-
#define NGX_HTTP_LUA_CONTEXT_TIMER 0x080
114-
#define NGX_HTTP_LUA_CONTEXT_INIT_WORKER 0x100
115-
#define NGX_HTTP_LUA_CONTEXT_BALANCER 0x200
116-
#define NGX_HTTP_LUA_CONTEXT_SSL_CERT 0x400
106+
#define NGX_HTTP_LUA_CONTEXT_SET 0x0001
107+
#define NGX_HTTP_LUA_CONTEXT_REWRITE 0x0002
108+
#define NGX_HTTP_LUA_CONTEXT_ACCESS 0x0004
109+
#define NGX_HTTP_LUA_CONTEXT_CONTENT 0x0008
110+
#define NGX_HTTP_LUA_CONTEXT_LOG 0x0010
111+
#define NGX_HTTP_LUA_CONTEXT_HEADER_FILTER 0x0020
112+
#define NGX_HTTP_LUA_CONTEXT_BODY_FILTER 0x0040
113+
#define NGX_HTTP_LUA_CONTEXT_TIMER 0x0080
114+
#define NGX_HTTP_LUA_CONTEXT_INIT_WORKER 0x0100
115+
#define NGX_HTTP_LUA_CONTEXT_BALANCER 0x0200
116+
#define NGX_HTTP_LUA_CONTEXT_SSL_CERT 0x0400
117+
#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE 0x0800
118+
#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH 0x1000
117119

118120

119121
#ifndef NGX_LUA_NO_FFI_API
@@ -204,10 +206,18 @@ struct ngx_http_lua_main_conf_s {
204206
union ngx_http_lua_srv_conf_u {
205207
#if (NGX_HTTP_SSL)
206208
struct {
207-
ngx_http_lua_srv_conf_handler_pt cert_handler;
208-
ngx_str_t cert_src;
209-
u_char *cert_src_key;
210-
} ssl;
209+
ngx_http_lua_srv_conf_handler_pt ssl_cert_handler;
210+
ngx_str_t ssl_cert_src;
211+
u_char *ssl_cert_src_key;
212+
213+
ngx_http_lua_srv_conf_handler_pt ssl_sess_store_handler;
214+
ngx_str_t ssl_sess_store_src;
215+
u_char *ssl_sess_store_src_key;
216+
217+
ngx_http_lua_srv_conf_handler_pt ssl_sess_fetch_handler;
218+
ngx_str_t ssl_sess_fetch_src;
219+
u_char *ssl_sess_fetch_src_key;
220+
} srv;
211221
#endif
212222

213223
struct {

src/ngx_http_lua_control.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,11 +318,16 @@ ngx_http_lua_ngx_exit(lua_State *L)
318318
| NGX_HTTP_LUA_CONTEXT_TIMER
319319
| NGX_HTTP_LUA_CONTEXT_HEADER_FILTER
320320
| NGX_HTTP_LUA_CONTEXT_BALANCER
321-
| NGX_HTTP_LUA_CONTEXT_SSL_CERT);
321+
| NGX_HTTP_LUA_CONTEXT_SSL_CERT
322+
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE
323+
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH);
322324

323325
rc = (ngx_int_t) luaL_checkinteger(L, 1);
324326

325-
if (ctx->context == NGX_HTTP_LUA_CONTEXT_SSL_CERT) {
327+
if (ctx->context & (NGX_HTTP_LUA_CONTEXT_SSL_CERT
328+
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE
329+
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH))
330+
{
326331

327332
#if (NGX_HTTP_SSL)
328333

@@ -332,6 +337,10 @@ ngx_http_lua_ngx_exit(lua_State *L)
332337
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
333338
"lua exit with code %i", rc);
334339

340+
if (ctx->context == NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE) {
341+
return 0;
342+
}
343+
335344
return lua_yield(L, 0);
336345

337346
#else

src/ngx_http_lua_module.c

Lines changed: 97 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "ngx_http_lua_semaphore.h"
2727
#include "ngx_http_lua_balancer.h"
2828
#include "ngx_http_lua_ssl_certby.h"
29+
#include "ngx_http_lua_ssl_session_storeby.h"
30+
#include "ngx_http_lua_ssl_session_fetchby.h"
2931

3032

3133
static void *ngx_http_lua_create_main_conf(ngx_conf_t *cf);
@@ -525,6 +527,34 @@ static ngx_command_t ngx_http_lua_cmds[] = {
525527
0,
526528
(void *) ngx_http_lua_ssl_cert_handler_file },
527529

530+
{ ngx_string("ssl_session_store_by_lua_block"),
531+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
532+
ngx_http_lua_ssl_sess_store_by_lua_block,
533+
NGX_HTTP_SRV_CONF_OFFSET,
534+
0,
535+
(void *) ngx_http_lua_ssl_sess_store_handler_inline },
536+
537+
{ ngx_string("ssl_session_store_by_lua_file"),
538+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
539+
ngx_http_lua_ssl_sess_store_by_lua,
540+
NGX_HTTP_SRV_CONF_OFFSET,
541+
0,
542+
(void *) ngx_http_lua_ssl_sess_store_handler_file },
543+
544+
{ ngx_string("ssl_session_fetch_by_lua_block"),
545+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
546+
ngx_http_lua_ssl_sess_fetch_by_lua_block,
547+
NGX_HTTP_SRV_CONF_OFFSET,
548+
0,
549+
(void *) ngx_http_lua_ssl_sess_fetch_handler_inline },
550+
551+
{ ngx_string("ssl_session_fetch_by_lua_file"),
552+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
553+
ngx_http_lua_ssl_sess_fetch_by_lua,
554+
NGX_HTTP_SRV_CONF_OFFSET,
555+
0,
556+
(void *) ngx_http_lua_ssl_sess_fetch_handler_file },
557+
528558
{ ngx_string("lua_ssl_verify_depth"),
529559
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
530560
ngx_conf_set_num_slot,
@@ -855,9 +885,18 @@ ngx_http_lua_create_srv_conf(ngx_conf_t *cf)
855885
}
856886

857887
/* set by ngx_pcalloc:
858-
* lscf->ssl.cert_handler = NULL;
859-
* lscf->ssl.cert_src = { 0, NULL };
860-
* lscf->ssl.cert_src_key = NULL;
888+
* lscf->srv.ssl_cert_handler = NULL;
889+
* lscf->srv.ssl_cert_src = { 0, NULL };
890+
* lscf->srv.ssl_cert_src_key = NULL;
891+
*
892+
* lscf->srv.ssl_session_store_handler = NULL;
893+
* lscf->srv.ssl_session_store_src = { 0, NULL };
894+
* lscf->srv.ssl_session_store_src_key = NULL;
895+
*
896+
* lscf->srv.ssl_session_fetch_handler = NULL;
897+
* lscf->srv.ssl_session_fetch_src = { 0, NULL };
898+
* lscf->srv.ssl_session_fetch_src_key = NULL;
899+
*
861900
* lscf->balancer.handler = NULL;
862901
* lscf->balancer.src = { 0, NULL };
863902
* lscf->balancer.src_key = NULL;
@@ -878,13 +917,13 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
878917

879918
dd("merge srv conf");
880919

881-
if (conf->ssl.cert_src.len == 0) {
882-
conf->ssl.cert_src = prev->ssl.cert_src;
883-
conf->ssl.cert_src_key = prev->ssl.cert_src_key;
884-
conf->ssl.cert_handler = prev->ssl.cert_handler;
920+
if (conf->srv.ssl_cert_src.len == 0) {
921+
conf->srv.ssl_cert_src = prev->srv.ssl_cert_src;
922+
conf->srv.ssl_cert_src_key = prev->srv.ssl_cert_src_key;
923+
conf->srv.ssl_cert_handler = prev->srv.ssl_cert_handler;
885924
}
886925

887-
if (conf->ssl.cert_src.len) {
926+
if (conf->srv.ssl_cert_src.len) {
888927
sscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module);
889928
if (sscf == NULL || sscf->ssl.ctx == NULL) {
890929
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
@@ -913,6 +952,56 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
913952

914953
# endif
915954

955+
#endif
956+
}
957+
958+
if (conf->srv.ssl_sess_store_src.len == 0) {
959+
conf->srv.ssl_sess_store_src = prev->srv.ssl_sess_store_src;
960+
conf->srv.ssl_sess_store_src_key = prev->srv.ssl_sess_store_src_key;
961+
conf->srv.ssl_sess_store_handler = prev->srv.ssl_sess_store_handler;
962+
}
963+
964+
if (conf->srv.ssl_sess_store_src.len) {
965+
sscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module);
966+
if (sscf == NULL || sscf->ssl.ctx == NULL) {
967+
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
968+
"no ssl configured for the server");
969+
970+
return NGX_CONF_ERROR;
971+
}
972+
973+
#ifdef LIBRESSL_VERSION_NUMBER
974+
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
975+
"LibreSSL does not support ssl_session_store_by_lua*");
976+
return NGX_CONF_ERROR;
977+
#else
978+
SSL_CTX_sess_set_new_cb(sscf->ssl.ctx,
979+
ngx_http_lua_ssl_sess_store_handler);
980+
#endif
981+
}
982+
983+
if (conf->srv.ssl_sess_fetch_src.len == 0) {
984+
conf->srv.ssl_sess_fetch_src = prev->srv.ssl_sess_fetch_src;
985+
conf->srv.ssl_sess_fetch_src_key = prev->srv.ssl_sess_fetch_src_key;
986+
conf->srv.ssl_sess_fetch_handler = prev->srv.ssl_sess_fetch_handler;
987+
}
988+
989+
if (conf->srv.ssl_sess_fetch_src.len) {
990+
sscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_ssl_module);
991+
if (sscf == NULL || sscf->ssl.ctx == NULL) {
992+
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
993+
"no ssl configured for the server");
994+
995+
return NGX_CONF_ERROR;
996+
}
997+
998+
#ifdef LIBRESSL_VERSION_NUMBER
999+
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
1000+
"LibreSSL does not support ssl_session_fetch_by_lua*");
1001+
return NGX_CONF_ERROR;
1002+
#else
1003+
SSL_CTX_sess_set_get_cb(sscf->ssl.ctx,
1004+
ngx_http_lua_ssl_sess_fetch_handler);
9161005
#endif
9171006
}
9181007

src/ngx_http_lua_phase.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,16 @@ ngx_http_lua_ngx_get_phase(lua_State *L)
8484
lua_pushliteral(L, "ssl_cert");
8585
break;
8686

87+
case NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE:
88+
lua_pushliteral(L, "ssl_session_store");
89+
break;
90+
91+
case NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH:
92+
lua_pushliteral(L, "ssl_session_fetch");
93+
break;
94+
8795
default:
88-
return luaL_error(L, "unknown phase: %d", (int) ctx->context);
96+
return luaL_error(L, "unknown phase: %#x", (int) ctx->context);
8997
}
9098

9199
return 1;

src/ngx_http_lua_sleep.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ ngx_http_lua_ngx_sleep(lua_State *L)
5656
| NGX_HTTP_LUA_CONTEXT_ACCESS
5757
| NGX_HTTP_LUA_CONTEXT_CONTENT
5858
| NGX_HTTP_LUA_CONTEXT_TIMER
59-
| NGX_HTTP_LUA_CONTEXT_SSL_CERT);
59+
| NGX_HTTP_LUA_CONTEXT_SSL_CERT
60+
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH);
6061

6162
coctx = ctx->cur_co_ctx;
6263
if (coctx == NULL) {

src/ngx_http_lua_socket_tcp.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,8 @@ ngx_http_lua_socket_tcp(lua_State *L)
386386
| NGX_HTTP_LUA_CONTEXT_ACCESS
387387
| NGX_HTTP_LUA_CONTEXT_CONTENT
388388
| NGX_HTTP_LUA_CONTEXT_TIMER
389-
| NGX_HTTP_LUA_CONTEXT_SSL_CERT);
389+
| NGX_HTTP_LUA_CONTEXT_SSL_CERT
390+
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH);
390391

391392
lua_createtable(L, 3 /* narr */, 1 /* nrec */);
392393
lua_pushlightuserdata(L, &ngx_http_lua_tcp_socket_metatable_key);
@@ -444,7 +445,8 @@ ngx_http_lua_socket_tcp_connect(lua_State *L)
444445
| NGX_HTTP_LUA_CONTEXT_ACCESS
445446
| NGX_HTTP_LUA_CONTEXT_CONTENT
446447
| NGX_HTTP_LUA_CONTEXT_TIMER
447-
| NGX_HTTP_LUA_CONTEXT_SSL_CERT);
448+
| NGX_HTTP_LUA_CONTEXT_SSL_CERT
449+
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH);
448450

449451
luaL_checktype(L, 1, LUA_TTABLE);
450452

src/ngx_http_lua_ssl.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
/*
3+
* Copyright (C) Yichun Zhang (agentzh)
4+
*/
5+
6+
7+
#ifndef DDEBUG
8+
#define DDEBUG 0
9+
#endif
10+
#include "ddebug.h"
11+
12+
13+
#if (NGX_HTTP_SSL)
14+
15+
16+
int ngx_http_lua_ssl_ctx_index = -1;
17+
18+
19+
ngx_int_t
20+
ngx_http_lua_ssl_init(ngx_log_t *log)
21+
{
22+
if (ngx_http_lua_ssl_ctx_index == -1) {
23+
ngx_http_lua_ssl_ctx_index = SSL_get_ex_new_index(0, NULL, NULL,
24+
NULL, NULL);
25+
26+
if (ngx_http_lua_ssl_ctx_index == -1) {
27+
ngx_ssl_error(NGX_LOG_ALERT, log, 0,
28+
"lua: SSL_get_ex_new_index() for ctx failed");
29+
return NGX_ERROR;
30+
}
31+
}
32+
33+
return NGX_OK;
34+
}
35+
36+
37+
#endif /* NGX_HTTP_SSL */

src/ngx_http_lua_ssl.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
/*
3+
* Copyright (C) Yichun Zhang (agentzh)
4+
*/
5+
6+
7+
#ifndef _NGX_HTTP_LUA_SSL_H_INCLUDED_
8+
#define _NGX_HTTP_LUA_SSL_H_INCLUDED_
9+
10+
11+
#include "ngx_http_lua_common.h"
12+
13+
14+
#if (NGX_HTTP_SSL)
15+
typedef struct {
16+
ngx_connection_t *connection; /* original true connection */
17+
ngx_http_request_t *request; /* fake request */
18+
ngx_pool_cleanup_pt *cleanup;
19+
20+
ngx_ssl_session_t *session; /* retrurn value for openssl's
21+
* session_get_cb */
22+
23+
ngx_str_t session_id;
24+
25+
int exit_code; /* exit code for openssl's
26+
set_cert_cb callback */
27+
28+
unsigned done:1;
29+
unsigned aborted:1;
30+
31+
unsigned entered_cert_handler:1;
32+
unsigned entered_sess_fetch_handler:1;
33+
} ngx_http_lua_ssl_ctx_t;
34+
#endif
35+
36+
37+
ngx_int_t ngx_http_lua_ssl_init(ngx_log_t *log);
38+
39+
40+
extern int ngx_http_lua_ssl_ctx_index;
41+
42+
43+
#endif /* _NGX_HTTP_LUA_SSL_H_INCLUDED_ */

0 commit comments

Comments
 (0)