I am trying to find a way to make a secure GET request from within my nginx/lua module out to a server to check an ingress call's authentication. There seems to be very little out there on how to do this. My current attempts center around using resty.http and the following.
-- Create http client
local httpc = http.new();
httpc:set_timeout(500)
ngx.log(ngx.DEBUG, '**** Connect with TLS ****');
ok, err = httpc:connect(my_server, port);
my_server however requires a cert, ca, and key on input, but again, not sure how to do that, using ["ca"] = myca.pem; etc... does not work. If I set
lua_ssl_trusted_certificate=myca.pem
the request fails with the following:
2018/02/23 19:22:17 [crit] 19#0: *4 SSL_shutdown() failed (SSL: error:140E0197:SSL routines:SSL_shutdown:shutdown while in init), client: 127.0.0.1, server: my_server
I have looked at https://github.com/brunoos/luasec/archive/luasec-0.6, but frankly could not get it to compile clean on my alpine linux container. Not sure what module to use or how to proceed at this point, any ideas?
UPDATE Additional information based on comments and an answer I have received. Attempts to use openresty pintsized lua-resty-http with https failed, there is just no way currently to get cert/key/ca mutual TLS flow to work. Using the answer below I was able to configure an upstream proxy call to my backend application microservice to correctly service the requests. My proxy.conf file snippets to get this to work look like the followwing. Note: the upstream server has to match the CN in the certificates, otherwise it will not work, or at least I got nothing by certificate failures indicating such.
http {
# Upstream backend for services
upstream apimy {
server apimy:3003;
}
...
location /api/analytics/token-info {
internal; # Specifies that a given location can only be used for internal requests
set $bearerToken $arg_token;
set $args "";
proxy_pass_request_headers on;
proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
proxy_ssl_ciphers HIGH:!aNULL:!MD5;
proxy_ssl_certificate /etc/certs/analytics_proxy_client_public.cert.pem;
proxy_ssl_certificate_key /etc/certs/analytics_proxy_client_private.key.pem;
proxy_ssl_trusted_certificate /etc/certs/analytics_proxy_client_ca.cert.pem;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
proxy_ssl_session_reuse off;
proxy_set_header Host apimy;
proxy_set_header Content-Type "application/json";
proxy_set_header Accept "application/json";
proxy_set_header Authorization "Bearer $bearerToken";
proxy_pass https://apimy/api/analytics/token-info; # trailing slash
}
Another note, for whatever I could not get the bearerToken to work passing it in as a vars from the lua side, I had to pass it in as an arg, then clear out the args after that so any others did not get passed into the call. My lua code that calls the path.
-- Connect --
ngx.log(ngx.DEBUG, '**** Connect with TLS ****');
res = ngx.location.capture('/api/analytics/token-info',
{
method = ngx.HTTP_POST,
body = json.encode(query),
args = {
token = accessToken;
}
})