Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,8 @@ Directives
* [ssl_session_fetch_by_lua_file](#ssl_session_fetch_by_lua_file)
* [ssl_session_store_by_lua_block](#ssl_session_store_by_lua_block)
* [ssl_session_store_by_lua_file](#ssl_session_store_by_lua_file)
* [proxy_ssl_verify_by_lua_block](#proxy_ssl_verify_by_lua_block)
* [proxy_ssl_verify_by_lua_file](#proxy_ssl_verify_by_lua_file)
* [lua_shared_dict](#lua_shared_dict)
* [lua_socket_connect_timeout](#lua_socket_connect_timeout)
* [lua_socket_send_timeout](#lua_socket_send_timeout)
Expand All @@ -1188,6 +1190,7 @@ Directives
* [lua_ssl_verify_depth](#lua_ssl_verify_depth)
* [lua_ssl_key_log](#lua_ssl_key_log)
* [lua_ssl_conf_command](#lua_ssl_conf_command)
* [lua_upstream_skip_openssl_default_verify](#lua_upstream_skip_openssl_default_verify)
* [lua_http10_buffering](#lua_http10_buffering)
* [rewrite_by_lua_no_postpone](#rewrite_by_lua_no_postpone)
* [access_by_lua_no_postpone](#access_by_lua_no_postpone)
Expand Down Expand Up @@ -3156,6 +3159,84 @@ Note that: this directive is only allowed to used in **http context** from the `

[Back to TOC](#directives)

proxy_ssl_verify_by_lua_block
-----------------------------

**syntax:** *proxy_ssl_verify_by_lua_block { lua-script }*

**context:** *location*

**phase:** *right-after-server-certificate-message-was-processed*

This directive runs user Lua code when Nginx is about to post-process the SSL server certificate message for the upstream SSL (https) connections.

It is particularly useful to parse upstream server certificate and do some custom operations in pure lua.

The [ngx.ssl.proxysslverify](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslverify.md) Lua modules provided by the [lua-resty-core](https://github.com/openresty/lua-resty-core/#readme)
library are particularly useful in this context.

Below is a trivial example using the
[ngx.ssl.proxysslverify](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslverify.md) module
at the same time:

```nginx
server {
listen 443 ssl;
server_name test.com;
ssl_certificate /path/to/cert.crt;
ssl_certificate_key /path/to/key.key;
location /t {
proxy_ssl_certificate /path/to/cert.crt;
proxy_ssl_certificate_key /path/to/key.key;
proxy_pass https://upstream;
proxy_ssl_verify_by_lua_block {
local proxy_ssl_vfy = require "ngx.ssl.proxysslverify"
local cert = proxy_ssl_vfy.get_verify_cert()
-- ocsp to verify cert
-- check crl
proxy_ssl_vfy.set_verify_result()
...
}
}
...
}
```

See more information in the [ngx.ssl.proxysslverify](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslverify.md)
Lua modules' official documentation.

Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does the
[ngx.exit](#ngxexit) call with an error code like `ngx.ERROR`.

This Lua code execution context *does* support yielding, so Lua APIs that may yield
(like cosockets, sleeping, and "light threads")
are enabled in this context

Note, `ngx.ctx` in proxy_ssl_verify_by_lua_block is belonging to upstream connection, not downstream connection, so it's different from `ngx.ctx` in contexts like ssl_certificate_by_lua etc.

This directive requires OpenSSL 3.0.2 or greater.

[Back to TOC](#directives)

proxy_ssl_verify_by_lua_file
----------------------------

**syntax:** *proxy_ssl_verify_by_lua_file <path-to-lua-script-file>*

**context:** *location*

**phase:** *right-after-server-certificate-message-was-processed*

Equivalent to [proxy_ssl_verify_by_lua_block](#proxy_ssl_verify_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is v0.5.0rc32?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied from other places in this README.markdown, please search it!


When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.

[Back to TOC](#directives)

lua_shared_dict
---------------

Expand Down Expand Up @@ -3490,6 +3571,21 @@ This directive was first introduced in the `v0.10.21` release.



[Back to TOC](#directives)

lua_upstream_skip_openssl_default_verify
--------------------

**syntax:** *lua_upstream_skip_openssl_default_verify on|off*

**default:** *lua_upstream_skip_openssl_default_verify off*

**context:** *location, location-if*

When using proxy_ssl_verify_by_lua directive, `lua_upstream_skip_openssl_default_verify` controls whether to skip default openssl's verify function, that means using pure Lua code to verify upstream server certificate.

This directive is turned `off` by default.

[Back to TOC](#directives)

lua_http10_buffering
Expand Down
2 changes: 2 additions & 0 deletions config
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ HTTP_LUA_SRCS=" \
$ngx_addon_dir/src/ngx_http_lua_ssl_session_storeby.c \
$ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.c \
$ngx_addon_dir/src/ngx_http_lua_ssl.c \
$ngx_addon_dir/src/ngx_http_lua_proxy_ssl_verifyby.c \
$ngx_addon_dir/src/ngx_http_lua_log_ringbuf.c \
$ngx_addon_dir/src/ngx_http_lua_input_filters.c \
$ngx_addon_dir/src/ngx_http_lua_pipe.c \
Expand Down Expand Up @@ -359,6 +360,7 @@ HTTP_LUA_DEPS=" \
$ngx_addon_dir/src/ngx_http_lua_ssl_session_storeby.h \
$ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.h \
$ngx_addon_dir/src/ngx_http_lua_ssl.h \
$ngx_addon_dir/src/ngx_http_lua_proxy_ssl_verifyby.h \
$ngx_addon_dir/src/ngx_http_lua_log_ringbuf.h \
$ngx_addon_dir/src/ngx_http_lua_input_filters.h \
$ngx_addon_dir/src/ngx_http_lua_pipe.h \
Expand Down
13 changes: 13 additions & 0 deletions doc/HttpLuaModule.wiki
Original file line number Diff line number Diff line change
Expand Up @@ -2960,6 +2960,19 @@ Note though that configuring OpenSSL directly with <code>lua_ssl_conf_command</c

This directive was first introduced in the <code>v0.10.21</code> release.

== lua_upstream_skip_openssl_default_verify ==

'''syntax:''' ''lua_upstream_skip_openssl_default_verify on|off''

'''default:''' ''lua_upstream_skip_openssl_default_verify off''

'''context:''' ''location, location-if''

When using proxy_ssl_verify_by_lua directive, `lua_upstream_skip_openssl_default_verify` controls whether to skip default openssl's verify function, that means using pure Lua code to verify upstream server certificate.

This directive is turned <code>off</code> by default.

[Back to TOC](#directives)


== lua_http10_buffering ==
Expand Down
53 changes: 33 additions & 20 deletions src/ngx_http_lua_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,23 +131,24 @@ typedef struct {
(NGX_HTTP_LUA_FILE_TAG_LEN + 2 * MD5_DIGEST_LENGTH)


/* must be within 16 bit */
#define NGX_HTTP_LUA_CONTEXT_SET 0x0001
#define NGX_HTTP_LUA_CONTEXT_REWRITE 0x0002
#define NGX_HTTP_LUA_CONTEXT_ACCESS 0x0004
#define NGX_HTTP_LUA_CONTEXT_CONTENT 0x0008
#define NGX_HTTP_LUA_CONTEXT_LOG 0x0010
#define NGX_HTTP_LUA_CONTEXT_HEADER_FILTER 0x0020
#define NGX_HTTP_LUA_CONTEXT_BODY_FILTER 0x0040
#define NGX_HTTP_LUA_CONTEXT_TIMER 0x0080
#define NGX_HTTP_LUA_CONTEXT_INIT_WORKER 0x0100
#define NGX_HTTP_LUA_CONTEXT_BALANCER 0x0200
#define NGX_HTTP_LUA_CONTEXT_SSL_CERT 0x0400
#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE 0x0800
#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH 0x1000
#define NGX_HTTP_LUA_CONTEXT_EXIT_WORKER 0x2000
#define NGX_HTTP_LUA_CONTEXT_SSL_CLIENT_HELLO 0x4000
#define NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE 0x8000
/* must be within 32 bits */
#define NGX_HTTP_LUA_CONTEXT_SET 0x00000001
#define NGX_HTTP_LUA_CONTEXT_REWRITE 0x00000002
#define NGX_HTTP_LUA_CONTEXT_ACCESS 0x00000004
#define NGX_HTTP_LUA_CONTEXT_CONTENT 0x00000008
#define NGX_HTTP_LUA_CONTEXT_LOG 0x00000010
#define NGX_HTTP_LUA_CONTEXT_HEADER_FILTER 0x00000020
#define NGX_HTTP_LUA_CONTEXT_BODY_FILTER 0x00000040
#define NGX_HTTP_LUA_CONTEXT_TIMER 0x00000080
#define NGX_HTTP_LUA_CONTEXT_INIT_WORKER 0x00000100
#define NGX_HTTP_LUA_CONTEXT_BALANCER 0x00000200
#define NGX_HTTP_LUA_CONTEXT_SSL_CERT 0x00000400
#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE 0x00000800
#define NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH 0x00001000
#define NGX_HTTP_LUA_CONTEXT_EXIT_WORKER 0x00002000
#define NGX_HTTP_LUA_CONTEXT_SSL_CLIENT_HELLO 0x00004000
#define NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE 0x00008000
#define NGX_HTTP_LUA_CONTEXT_PROXY_SSL_VERIFY 0x00010000


#define NGX_HTTP_LUA_FFI_NO_REQ_CTX -100
Expand All @@ -171,6 +172,8 @@ typedef struct ngx_http_lua_srv_conf_s ngx_http_lua_srv_conf_t;

typedef struct ngx_http_lua_main_conf_s ngx_http_lua_main_conf_t;

typedef struct ngx_http_lua_loc_conf_s ngx_http_lua_loc_conf_t;

typedef struct ngx_http_lua_header_val_s ngx_http_lua_header_val_t;

typedef struct ngx_http_lua_posted_thread_s ngx_http_lua_posted_thread_t;
Expand All @@ -184,6 +187,9 @@ typedef ngx_int_t (*ngx_http_lua_main_conf_handler_pt)(ngx_log_t *log,
typedef ngx_int_t (*ngx_http_lua_srv_conf_handler_pt)(ngx_http_request_t *r,
ngx_http_lua_srv_conf_t *lscf, lua_State *L);

typedef ngx_int_t (*ngx_http_lua_loc_conf_handler_pt)(ngx_http_request_t *r,
ngx_http_lua_loc_conf_t *llcf, lua_State *L);

typedef ngx_int_t (*ngx_http_lua_set_header_pt)(ngx_http_request_t *r,
ngx_http_lua_header_val_t *hv, ngx_str_t *value);

Expand Down Expand Up @@ -369,7 +375,7 @@ struct ngx_http_lua_srv_conf_s {
};


typedef struct {
struct ngx_http_lua_loc_conf_s {
#if (NGX_HTTP_SSL)
ngx_ssl_t *ssl; /* shared by SSL cosockets */
ngx_array_t *ssl_certificates;
Expand All @@ -383,6 +389,13 @@ typedef struct {
#if (nginx_version >= 1019004)
ngx_array_t *ssl_conf_commands;
#endif

ngx_http_lua_loc_conf_handler_pt proxy_ssl_verify_handler;
ngx_str_t proxy_ssl_verify_src;
u_char *proxy_ssl_verify_src_key;
u_char *proxy_ssl_verify_chunkname;
int proxy_ssl_verify_src_ref;
ngx_flag_t upstream_skip_openssl_default_verify;
#endif

ngx_flag_t force_read_body; /* whether force request body to
Expand Down Expand Up @@ -464,7 +477,7 @@ typedef struct {
ngx_flag_t log_socket_errors;
ngx_flag_t check_client_abort;
ngx_flag_t use_default_type;
} ngx_http_lua_loc_conf_t;
};


typedef enum {
Expand Down Expand Up @@ -628,7 +641,7 @@ typedef struct ngx_http_lua_ctx_s {

int uthreads; /* number of active user threads */

uint16_t context; /* the current running directive context
uint32_t context; /* the current running directive context
(or running phase) for the current
Lua chunk */

Expand Down
4 changes: 3 additions & 1 deletion src/ngx_http_lua_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ ngx_http_lua_ffi_exit(ngx_http_request_t *r, int status, u_char *err,
| NGX_HTTP_LUA_CONTEXT_TIMER
| NGX_HTTP_LUA_CONTEXT_HEADER_FILTER
| NGX_HTTP_LUA_CONTEXT_BALANCER
| NGX_HTTP_LUA_CONTEXT_PROXY_SSL_VERIFY
| NGX_HTTP_LUA_CONTEXT_SSL_CLIENT_HELLO
| NGX_HTTP_LUA_CONTEXT_SSL_CERT
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE
Expand All @@ -394,7 +395,8 @@ ngx_http_lua_ffi_exit(ngx_http_request_t *r, int status, u_char *err,
return NGX_ERROR;
}

if (ctx->context & (NGX_HTTP_LUA_CONTEXT_SSL_CERT
if (ctx->context & (NGX_HTTP_LUA_CONTEXT_PROXY_SSL_VERIFY
| NGX_HTTP_LUA_CONTEXT_SSL_CERT
| NGX_HTTP_LUA_CONTEXT_SSL_CLIENT_HELLO
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_STORE
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH))
Expand Down
47 changes: 47 additions & 0 deletions src/ngx_http_lua_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "ngx_http_lua_ssl_certby.h"
#include "ngx_http_lua_ssl_session_storeby.h"
#include "ngx_http_lua_ssl_session_fetchby.h"
#include "ngx_http_lua_proxy_ssl_verifyby.h"
#include "ngx_http_lua_headers.h"
#include "ngx_http_lua_headers_out.h"
#if !(NGX_WIN32)
Expand Down Expand Up @@ -660,6 +661,28 @@ static ngx_command_t ngx_http_lua_cmds[] = {
0,
(void *) ngx_http_lua_ssl_sess_fetch_handler_file },

/* same context as proxy_pass directive */
{ ngx_string("proxy_ssl_verify_by_lua_block"),
NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_http_lua_proxy_ssl_verify_by_lua_block,
NGX_HTTP_LOC_CONF_OFFSET,
0,
(void *) ngx_http_lua_proxy_ssl_verify_handler_inline },

{ ngx_string("proxy_ssl_verify_by_lua_file"),
NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
ngx_http_lua_proxy_ssl_verify_by_lua,
NGX_HTTP_LOC_CONF_OFFSET,
0,
(void *) ngx_http_lua_proxy_ssl_verify_handler_file },

{ ngx_string("lua_upstream_skip_openssl_default_verify"),
NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_lua_loc_conf_t, upstream_skip_openssl_default_verify),
NULL },

{ ngx_string("lua_ssl_verify_depth"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
Expand Down Expand Up @@ -1446,6 +1469,11 @@ ngx_http_lua_create_loc_conf(ngx_conf_t *cf)
* conf->ssl_trusted_certificate = { 0, NULL };
* conf->ssl_crl = { 0, NULL };
* conf->ssl_key_log = { 0, NULL };
*
* conf->proxy_ssl_verify_handler = NULL;
* conf->proxy_ssl_verify_src = { 0, NULL };
* conf->proxy_ssl_verify_chunkname = NULL;
* conf->proxy_ssl_verify_src_key = NULL;
*/

conf->force_read_body = NGX_CONF_UNSET;
Expand Down Expand Up @@ -1479,6 +1507,8 @@ ngx_http_lua_create_loc_conf(ngx_conf_t *cf)
#if (nginx_version >= 1019004)
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
#endif
conf->proxy_ssl_verify_src_ref = LUA_REFNIL;
conf->upstream_skip_openssl_default_verify = NGX_CONF_UNSET;
#endif

return conf;
Expand Down Expand Up @@ -1573,6 +1603,23 @@ ngx_http_lua_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
NULL);
#endif

if (conf->proxy_ssl_verify_src.len == 0) {
conf->proxy_ssl_verify_src = prev->proxy_ssl_verify_src;
conf->proxy_ssl_verify_handler = prev->proxy_ssl_verify_handler;
conf->proxy_ssl_verify_src_ref = prev->proxy_ssl_verify_src_ref;
conf->proxy_ssl_verify_src_key = prev->proxy_ssl_verify_src_key;
conf->proxy_ssl_verify_chunkname = prev->proxy_ssl_verify_chunkname;
}

if (conf->proxy_ssl_verify_src.len) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a macro in th patch to test if the patch has been applied.

if (ngx_http_lua_proxy_ssl_verify_set_callback(cf) != NGX_OK) {
return NGX_CONF_ERROR;
}
}

ngx_conf_merge_value(conf->upstream_skip_openssl_default_verify,
prev->upstream_skip_openssl_default_verify, 0);

if (ngx_http_lua_set_ssl(cf, conf) != NGX_OK) {
return NGX_CONF_ERROR;
}
Expand Down
Loading