Skip to content

Commit eb00232

Browse files
Merge branch 'main' of github.com:api7/apisix-nginx-module into 12711
2 parents e17b5f9 + 8ed17e7 commit eb00232

File tree

8 files changed

+634
-10
lines changed

8 files changed

+634
-10
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ jobs:
3030
run: |
3131
sudo apt install -y cpanminus build-essential libncurses5-dev libreadline-dev libssl-dev perl luarocks libpcre3 libpcre3-dev zlib1g-dev
3232
sudo luarocks install lua-resty-http > build.log 2>&1 || (cat build.log && exit 1)
33+
sudo luarocks install lua-resty-openssl > build.log 2>&1 || (cat build.log && exit 1)
3334
3435
- name: Before install
3536
run: |

lib/resty/apisix/upstream.lua

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
local ffi = require("ffi")
22
local base = require("resty.core.base")
33
local get_request = base.get_request
4+
local get_phase = ngx.get_phase
45
local C = ffi.C
56
local NGX_ERROR = ngx.ERROR
7+
local NGX_OK = ngx.OK
68

79

810
base.allows_subsystem("http")
911

1012

1113
ffi.cdef([[
1214
typedef intptr_t ngx_int_t;
13-
ngx_int_t
14-
ngx_http_apisix_upstream_set_cert_and_key(ngx_http_request_t *r, void *cert, void *key);
15+
ngx_int_t ngx_http_apisix_upstream_set_cert_and_key(ngx_http_request_t *r, void *cert, void *key);
16+
ngx_int_t ngx_http_apisix_upstream_set_ssl_trusted_store(ngx_http_request_t *r, void *store);
17+
int ngx_http_apisix_upstream_set_ssl_verify(ngx_http_request_t *r, int verify);
1518
]])
1619
local _M = {}
1720

@@ -30,5 +33,77 @@ function _M.set_cert_and_key(cert, key)
3033
return true
3134
end
3235

36+
local set_ssl_trusted_store
37+
do
38+
local ALLOWED_PHASES = {
39+
['rewrite'] = true,
40+
['balancer'] = true,
41+
['access'] = true,
42+
['preread'] = true,
43+
}
44+
45+
local openssl_x509_store = require "resty.openssl.x509.store"
46+
function set_ssl_trusted_store(store)
47+
if not ALLOWED_PHASES[get_phase()] then
48+
error("API disabled in the current context", 2)
49+
end
50+
51+
if not openssl_x509_store.istype(store) then
52+
error("store expects a resty.openssl.x509.store" ..
53+
" object but get " .. type(store), 2)
54+
end
55+
56+
local r = get_request()
57+
58+
local ret = C.ngx_http_apisix_upstream_set_ssl_trusted_store(
59+
r, store.ctx)
60+
if ret == NGX_OK then
61+
return true
62+
end
63+
64+
if ret == NGX_ERROR then
65+
return nil, "error while setting upstream trusted store"
66+
end
67+
68+
error("unknown return code: " .. tostring(ret))
69+
end
70+
end
71+
_M.set_ssl_trusted_store = set_ssl_trusted_store
72+
73+
74+
local set_ssl_verify
75+
do
76+
local ALLOWED_PHASES = {
77+
['rewrite'] = true,
78+
['balancer'] = true,
79+
['access'] = true,
80+
['preread'] = true,
81+
}
82+
function set_ssl_verify(verify)
83+
if not ALLOWED_PHASES[get_phase()] then
84+
error("API disabled in the current context", 2)
85+
end
86+
87+
if type(verify) ~= 'boolean' then
88+
error("verify expects a boolean but found " .. type(verify), 2)
89+
end
90+
91+
local r = get_request()
92+
93+
local ret = C.ngx_http_apisix_upstream_set_ssl_verify(
94+
r, verify)
95+
if ret == NGX_OK then
96+
return true
97+
end
98+
99+
if ret == NGX_ERROR then
100+
return nil, "error while setting upstream ssl verify mode"
101+
end
102+
103+
error("unknown return code: " .. tostring(ret))
104+
end
105+
end
106+
_M.set_ssl_verify = set_ssl_verify
107+
33108

34109
return _M

patch/1.21.4/nginx-upstream_mtls.patch

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
diff --git src/http/ngx_http_upstream.c src/http/ngx_http_upstream.c
2-
index 76045c4..cee3e2a 100644
2+
index 04d813a..c812242 100644
33
--- src/http/ngx_http_upstream.c
44
+++ src/http/ngx_http_upstream.c
55
@@ -8,6 +8,9 @@
@@ -10,9 +10,22 @@ index 76045c4..cee3e2a 100644
1010
+#include <ngx_http_apisix_module.h>
1111
+#endif
1212

13-
#if (T_NGX_MULTI_UPSTREAM)
14-
#include <ngx_http_multi_upstream_module.h>
15-
@@ -1766,6 +1769,10 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
13+
14+
#if (NGX_HTTP_CACHE)
15+
@@ -1697,8 +1700,11 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
16+
NGX_HTTP_INTERNAL_SERVER_ERROR);
17+
return;
18+
}
19+
-
20+
+#if (NGX_HTTP_APISIX)
21+
+ if (u->conf->ssl_server_name || ngx_http_apisix_get_upstream_ssl_verify(r, u->conf->ssl_verify)) {
22+
+#else
23+
if (u->conf->ssl_server_name || u->conf->ssl_verify) {
24+
+#endif
25+
if (ngx_http_upstream_ssl_name(r, u, c) != NGX_OK) {
26+
ngx_http_upstream_finalize_request(r, u,
27+
NGX_HTTP_INTERNAL_SERVER_ERROR);
28+
@@ -1738,6 +1744,10 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
1629

1730
r->connection->log->action = "SSL handshaking to upstream";
1831

@@ -23,3 +36,15 @@ index 76045c4..cee3e2a 100644
2336
rc = ngx_ssl_handshake(c);
2437

2538
if (rc == NGX_AGAIN) {
39+
@@ -1785,7 +1795,11 @@ ngx_http_upstream_ssl_handshake(ngx_http_request_t *r, ngx_http_upstream_t *u,
40+
41+
if (c->ssl->handshaked) {
42+
43+
+#if (NGX_HTTP_APISIX)
44+
+ if (ngx_http_apisix_get_upstream_ssl_verify(r, u->conf->ssl_verify)) {
45+
+#else
46+
if (u->conf->ssl_verify) {
47+
+#endif
48+
rc = SSL_get_verify_result(c->ssl->connection);
49+
50+
if (rc != X509_V_OK) {

patch/1.25.3.1/nginx-upstream_mtls.patch

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
diff --git src/http/ngx_http_upstream.c src/http/ngx_http_upstream.c
2-
index 2be233c..78474f3 100644
2+
index 2be233c..06bbbb9 100644
33
--- src/http/ngx_http_upstream.c
44
+++ src/http/ngx_http_upstream.c
55
@@ -8,6 +8,9 @@
@@ -12,7 +12,20 @@ index 2be233c..78474f3 100644
1212

1313

1414
#if (NGX_HTTP_CACHE)
15-
@@ -1756,6 +1759,10 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
15+
@@ -1713,8 +1716,11 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
16+
NGX_HTTP_INTERNAL_SERVER_ERROR);
17+
return;
18+
}
19+
-
20+
+#if (NGX_HTTP_APISIX)
21+
+ if (u->conf->ssl_server_name || ngx_http_apisix_get_upstream_ssl_verify(r, u->conf->ssl_verify)) {
22+
+#else
23+
if (u->conf->ssl_server_name || u->conf->ssl_verify) {
24+
+#endif
25+
if (ngx_http_upstream_ssl_name(r, u, c) != NGX_OK) {
26+
ngx_http_upstream_finalize_request(r, u,
27+
NGX_HTTP_INTERNAL_SERVER_ERROR);
28+
@@ -1756,6 +1762,10 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
1629

1730
r->connection->log->action = "SSL handshaking to upstream";
1831

@@ -23,3 +36,15 @@ index 2be233c..78474f3 100644
2336
rc = ngx_ssl_handshake(c);
2437

2538
if (rc == NGX_AGAIN) {
39+
@@ -1803,7 +1813,11 @@ ngx_http_upstream_ssl_handshake(ngx_http_request_t *r, ngx_http_upstream_t *u,
40+
41+
if (c->ssl->handshaked) {
42+
43+
+#if (NGX_HTTP_APISIX)
44+
+ if (ngx_http_apisix_get_upstream_ssl_verify(r, u->conf->ssl_verify)) {
45+
+#else
46+
if (u->conf->ssl_verify) {
47+
+#endif
48+
rc = SSL_get_verify_result(c->ssl->connection);
49+
50+
if (rc != X509_V_OK) {

src/ngx_http_apisix_module.c

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,15 @@ ngx_http_apisix_cleanup_cert_and_key(ngx_http_apisix_ctx_t *ctx)
158158
ctx->upstream_pkey = NULL;
159159
}
160160
}
161+
162+
static void
163+
ngx_http_apisix_cleanup_trusted_store(ngx_http_apisix_ctx_t *ctx)
164+
{
165+
if (ctx->upstream_trusted_store != NULL) {
166+
X509_STORE_free(ctx->upstream_trusted_store);
167+
ctx->upstream_trusted_store = NULL;
168+
}
169+
}
161170
#endif
162171

163172

@@ -168,6 +177,7 @@ ngx_http_apisix_cleanup(void *data)
168177

169178
#if (NGX_HTTP_SSL)
170179
ngx_http_apisix_cleanup_cert_and_key(ctx);
180+
ngx_http_apisix_cleanup_trusted_store(ctx);
171181
#endif
172182
}
173183

@@ -250,6 +260,41 @@ ngx_http_apisix_upstream_set_cert_and_key(ngx_http_request_t *r,
250260
return NGX_ERROR;
251261
}
252262

263+
ngx_int_t
264+
ngx_http_apisix_upstream_set_ssl_trusted_store(ngx_http_request_t *r, void *data)
265+
{
266+
X509_STORE *store = data;
267+
ngx_http_apisix_ctx_t *ctx;
268+
269+
if (store == NULL) {
270+
return NGX_ERROR;
271+
}
272+
273+
ctx = ngx_http_apisix_get_module_ctx(r);
274+
275+
if (ctx == NULL) {
276+
return NGX_ERROR;
277+
}
278+
279+
if (ctx->upstream_trusted_store != NULL) {
280+
ngx_http_apisix_cleanup_trusted_store(ctx);
281+
}
282+
283+
if (X509_STORE_up_ref(store) == 0) {
284+
goto failed;
285+
}
286+
287+
ctx->upstream_trusted_store = store;
288+
289+
return NGX_OK;
290+
291+
failed:
292+
293+
ngx_http_apisix_flush_ssl_error();
294+
295+
return NGX_ERROR;
296+
}
297+
253298

254299
void
255300
ngx_http_apisix_set_upstream_ssl(ngx_http_request_t *r, ngx_connection_t *c)
@@ -258,6 +303,7 @@ ngx_http_apisix_set_upstream_ssl(ngx_http_request_t *r, ngx_connection_t *c)
258303
ngx_http_apisix_ctx_t *ctx;
259304
STACK_OF(X509) *cert;
260305
EVP_PKEY *pkey;
306+
X509_STORE *store;
261307
X509 *x509;
262308
#ifdef OPENSSL_IS_BORINGSSL
263309
size_t i;
@@ -275,8 +321,9 @@ ngx_http_apisix_set_upstream_ssl(ngx_http_request_t *r, ngx_connection_t *c)
275321
}
276322

277323
if (ctx->upstream_cert != NULL) {
278-
cert = ctx->upstream_cert;
279-
pkey = ctx->upstream_pkey;
324+
cert = ctx->upstream_cert;
325+
pkey = ctx->upstream_pkey;
326+
store = ctx->upstream_trusted_store;
280327

281328
if (sk_X509_num(cert) < 1) {
282329
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
@@ -317,6 +364,17 @@ ngx_http_apisix_set_upstream_ssl(ngx_http_request_t *r, ngx_connection_t *c)
317364
"SSL_use_PrivateKey() failed");
318365
goto failed;
319366
}
367+
368+
if (store != NULL) {
369+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
370+
"overriding upstream SSL trusted store");
371+
372+
if (SSL_set1_verify_cert_store(sc, store) == 0) {
373+
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
374+
"SSL_set1_verify_cert_store() failed");
375+
goto failed;
376+
}
377+
}
320378
}
321379

322380
return;
@@ -325,6 +383,42 @@ ngx_http_apisix_set_upstream_ssl(ngx_http_request_t *r, ngx_connection_t *c)
325383

326384
ngx_http_apisix_flush_ssl_error();
327385
}
386+
387+
388+
int
389+
ngx_http_apisix_upstream_set_ssl_verify(ngx_http_request_t *r, int verify)
390+
{
391+
ngx_http_apisix_ctx_t *ctx;
392+
393+
ctx = ngx_http_apisix_get_module_ctx(r);
394+
395+
if (ctx == NULL) {
396+
return NGX_ERROR;
397+
}
398+
399+
ctx->upstream_ssl_verify_set = 1;
400+
ctx->upstream_ssl_verify = verify;
401+
402+
return NGX_OK;
403+
}
404+
405+
ngx_flag_t
406+
ngx_http_apisix_get_upstream_ssl_verify(ngx_http_request_t *r, ngx_flag_t proxy_ssl_verify)
407+
{
408+
ngx_http_apisix_ctx_t *ctx;
409+
410+
ctx = ngx_http_apisix_get_module_ctx(r);
411+
412+
if (ctx == NULL) {
413+
return proxy_ssl_verify;
414+
}
415+
416+
if (!ctx->upstream_ssl_verify_set) {
417+
return proxy_ssl_verify;
418+
}
419+
420+
return ctx->upstream_ssl_verify;
421+
}
328422
#endif
329423

330424

src/ngx_http_apisix_module.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ typedef struct {
2222
typedef struct {
2323
STACK_OF(X509) *upstream_cert;
2424
EVP_PKEY *upstream_pkey;
25+
X509_STORE *upstream_trusted_store;
2526

2627
off_t client_max_body_size;
2728

@@ -34,10 +35,13 @@ typedef struct {
3435
unsigned request_header_set:1;
3536
unsigned header_filter_by_lua_skipped:1;
3637
unsigned body_filter_by_lua_skipped:1;
38+
unsigned upstream_ssl_verify:1;
39+
unsigned upstream_ssl_verify_set:1;
3740
} ngx_http_apisix_ctx_t;
3841

3942

4043
void ngx_http_apisix_set_upstream_ssl(ngx_http_request_t *r, ngx_connection_t *c);
44+
ngx_flag_t ngx_http_apisix_get_upstream_ssl_verify(ngx_http_request_t *r, ngx_flag_t proxy_ssl_verify);
4145

4246
ngx_flag_t ngx_http_apisix_delay_client_max_body_check(ngx_http_request_t *r);
4347
off_t ngx_http_apisix_client_max_body_size(ngx_http_request_t *r);

0 commit comments

Comments
 (0)