Skip to content

Commit e4cc508

Browse files
fffoniondndx
andauthored
feat(tls) add new methods set_upstream_ssl_trusted_store, set_upstream_ssl_verify and set_upstream_ssl_verify_depth for dynamically overriding upstream TLS verification behavior of Nginx
This allows more flexibility when proxying to TLS enabled upstream servers in Nginx without sacrificing feature or performance. Co-authored-by: Datong Sun <[email protected]>
1 parent eff31f3 commit e4cc508

File tree

6 files changed

+931
-50
lines changed

6 files changed

+931
-50
lines changed

.ci/setup_env.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,6 @@ nginx -V
7171
resty -V
7272
luarocks --version
7373
openssl version
74+
75+
# Needed by tests of tls.set_upstream_trusted_store
76+
luarocks install lua-resty-openssl

README.md

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ Table of Contents
1414
* [resty.kong.tls.disable\_session\_reuse](#restykongtlsdisable_session_reuse)
1515
* [resty.kong.tls.get\_full\_client\_certificate\_chain](#restykongtlsget_full_client_certificate_chain)
1616
* [resty.kong.tls.set\_upstream\_cert\_and\_key](#restykongtlsset_upstream_cert_and_key)
17+
* [resty.kong.tls.set\_upstream\_ssl\_trusted\_store](#restykongtlsset_upstream_ssl_trusted_store)
18+
* [resty.kong.tls.set\_upstream\_ssl\_verify](#restykongtlsset_upstream_ssl_verify)
19+
* [resty.kong.tls.set\_upstream\_ssl\_verify\_depth](#restykongtlsset_upstream_ssl_verify_depth)
1720
* [resty.kong.tls.disable\_proxy\_ssl](#restykongtlsdisable_proxy_ssl)
1821
* [License](#license)
1922

@@ -134,6 +137,106 @@ previous ones.
134137

135138
[Back to TOC](#table-of-contents)
136139

140+
resty.kong.tls.set\_upstream\_ssl\_trusted\_store
141+
--------------------------------------------
142+
**syntax:** *ok, err = resty.kong.tls.set\_upstream\_ssl\_trusted\_store(store)*
143+
144+
**context:** *rewrite_by_lua&#42;, access_by_lua&#42;, balancer_by_lua&#42;*
145+
146+
**subsystems:** *http*
147+
148+
Set upstream ssl verification trusted store of current request. Global setting set by
149+
`proxy_ssl_trusted_certificate` will be overwritten for the current request.
150+
151+
`store` is a `X509_STORE*` cdata that can be created by
152+
[resty.openssl.x509.store.new](https://github.com/fffonion/lua-resty-openssl#storenew).
153+
154+
On success, this function returns `true` and future handshakes with upstream servers
155+
will be verified with given store. Otherwise `nil` and a string describing the
156+
error will be returned.
157+
158+
This function can be called multiple times in the same request. Later calls override
159+
previous ones.
160+
161+
Example:
162+
```lua
163+
local x509 = require("resty.openssl.x509")
164+
local crt, err = x509.new([[-----BEGIN CERTIFICATE-----
165+
...
166+
-----END CERTIFICATE-----]])
167+
if err then
168+
ngx.log(ngx.ERR, "failed to parse cert: ", err)
169+
ngx.exit(500)
170+
end
171+
local store = require("resty.openssl.x509.store")
172+
local st, err = store.new()
173+
if err then
174+
ngx.log(ngx.ERR, "failed to create store: ", err)
175+
ngx.exit(500)
176+
end
177+
local ok, err = st:add(crt)
178+
if err then
179+
ngx.log(ngx.ERR, "failed to add cert to store: ", err)
180+
ngx.exit(500)
181+
end
182+
-- st:add can be called multiple times, also accept a crl
183+
-- st:add(another_crt)
184+
-- st:add(crl)
185+
-- OR
186+
-- st:use_default() to load default CA bundle
187+
local tls = require("resty.kong.tls")
188+
local ok, err = tls.set_upstream_ssl_trusted_store(st.ctx)
189+
if err then
190+
ngx.log(ngx.ERR, "failed to set upstream trusted store: ", err)
191+
ngx.exit(500)
192+
end
193+
local ok, err = tls.set_upstream_ssl_verify(true)
194+
if err then
195+
ngx.log(ngx.ERR, "failed to set upstream ssl verify: ", err)
196+
ngx.exit(500)
197+
end
198+
```
199+
200+
[Back to TOC](#table-of-contents)
201+
202+
resty.kong.tls.set\_upstream\_ssl\_verify
203+
--------------------------------------------
204+
**syntax:** *ok, err = resty.kong.tls.set\_upstream\_ssl\_verify(verify)*
205+
206+
**context:** *rewrite_by_lua&#42;, access_by_lua&#42;, balancer_by_lua&#42;*
207+
208+
**subsystems:** *http*
209+
210+
Set upstream ssl verification enablement of current request to the given boolean
211+
argument `verify`. Global setting set by `proxy_ssl_verify` will be overwritten.
212+
213+
On success, this function returns `true`. Otherwise `nil` and a string
214+
describing the error will be returned.
215+
216+
This function can be called multiple times in the same request. Later calls override
217+
previous ones.
218+
219+
[Back to TOC](#table-of-contents)
220+
221+
resty.kong.tls.set\_upstream\_ssl\_verify\_depth
222+
--------------------------------------------
223+
**syntax:** *ok, err = resty.kong.tls.set\_upstream\_ssl\_verify\_depth(depth)*
224+
225+
**context:** *rewrite_by_lua&#42;, access_by_lua&#42;, balancer_by_lua&#42;*
226+
227+
**subsystems:** *http*
228+
229+
Set upstream ssl verification depth of current request to the given non-negative integer
230+
argument `depth`. Global setting set by `proxy_ssl_verify_depth` will be overwritten.
231+
232+
On success, this function returns `true`. Otherwise `nil` and a string
233+
describing the error will be returned.
234+
235+
This function can be called multiple times in the same request. Later calls override
236+
previous ones.
237+
238+
[Back to TOC](#table-of-contents)
239+
137240
resty.kong.tls.disable\_proxy\_ssl
138241
----------------------------------
139242
**syntax:** *ok, err = resty.kong.tls.disable_proxy_ssl()*
@@ -172,4 +275,3 @@ limitations under the License.
172275
```
173276

174277
[Back to TOC](#table-of-contents)
175-

lualib/resty/kong/tls.lua

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ if ngx.config.subsystem == "http" then
2929
const char *ngx_http_lua_kong_ffi_disable_session_reuse(ngx_http_request_t *r);
3030
int ngx_http_lua_kong_ffi_set_upstream_client_cert_and_key(ngx_http_request_t *r,
3131
void *_chain, void *_key);
32+
int ngx_http_lua_kong_ffi_set_upstream_ssl_trusted_store(ngx_http_request_t *r,
33+
void *_store);
34+
int ngx_http_lua_kong_ffi_set_upstream_ssl_verify(ngx_http_request_t *r,
35+
int verify);
36+
int ngx_http_lua_kong_ffi_set_upstream_ssl_verify_depth(ngx_http_request_t *r,
37+
int depth);
3238
]])
3339

3440
else
@@ -193,6 +199,82 @@ if ngx.config.subsystem == "http" then
193199

194200
error("unknown return code: " .. tostring(ret))
195201
end
202+
203+
function _M.set_upstream_ssl_trusted_store(store)
204+
if not ALLOWED_PHASES[get_phase()] then
205+
error("API disabled in the current context", 2)
206+
end
207+
208+
if type(store) ~= 'cdata' then
209+
error("store expects a cdata object but found " .. type(store), 2)
210+
end
211+
212+
local r = get_request()
213+
214+
local ret = C.ngx_http_lua_kong_ffi_set_upstream_ssl_trusted_store(
215+
r, store)
216+
if ret == NGX_OK then
217+
return true
218+
end
219+
220+
if ret == NGX_ERROR then
221+
return nil, "error while setting upstream trusted store"
222+
end
223+
224+
error("unknown return code: " .. tostring(ret))
225+
end
226+
227+
function _M.set_upstream_ssl_verify(verify)
228+
if not ALLOWED_PHASES[get_phase()] then
229+
error("API disabled in the current context", 2)
230+
end
231+
232+
if type(verify) ~= 'boolean' then
233+
error("verify expects a boolean but found " .. type(verify), 2)
234+
end
235+
236+
local r = get_request()
237+
238+
local ret = C.ngx_http_lua_kong_ffi_set_upstream_ssl_verify(
239+
r, verify)
240+
if ret == NGX_OK then
241+
return true
242+
end
243+
244+
if ret == NGX_ERROR then
245+
return nil, "error while setting upstream ssl verify mode"
246+
end
247+
248+
error("unknown return code: " .. tostring(ret))
249+
end
250+
251+
function _M.set_upstream_ssl_verify_depth(depth)
252+
if not ALLOWED_PHASES[get_phase()] then
253+
error("API disabled in the current context", 2)
254+
end
255+
256+
if type(depth) ~= 'number' then
257+
error("depth expects a number but found " .. type(depth), 2)
258+
end
259+
260+
if depth < 0 then
261+
error("depth expects a non-negative integer but found " .. tostring(depth), 2)
262+
end
263+
264+
local r = get_request()
265+
266+
local ret = C.ngx_http_lua_kong_ffi_set_upstream_ssl_verify_depth(
267+
r, depth)
268+
if ret == NGX_OK then
269+
return true
270+
end
271+
272+
if ret == NGX_ERROR then
273+
return nil, "error while setting upstream ssl verify depth"
274+
end
275+
276+
error("unknown return code: " .. tostring(ret))
277+
end
196278
end
197279

198280
else -- stream

0 commit comments

Comments
 (0)