Search code examples
sslnginxluassl-certificateopenresty

Set client ssl cert variables as request headers of the message in openresty


I am trying to create a router for internal testing. I am using openresty image RESTY_CONFIG_OPTIONS_MORE. As the messages we are sending from the client are binary and don't have any request headers, we are trying to extract the issuer and serial number from the cert and set them as request headers. We want to use these headers to route to our test server as opposed to production depending on the header values.

My dockerfile grabs it like so:

ENV RESTY_CONFIG_OPTIONS_MORE "--with-ngx_http_ssl_module"

I have already tried the following in the server block but it did not work:

rewrite_by_lua_block {
        ngx.req.set_header("x-issuer", ngx.var.ssl_client_i_dn)
    }

The author has mentioned that the envsubst utility is included in all images except alpine and windows. Is that relevant to my issue in any way?

If just appending the config options will not work, which do you think is the best option?

  1. Use nginx-ssl-variables looks like it does exactly what we want it to do: https://github.com/Seb35/nginx-ssl-variables
  2. Modify openresty code to build our own image that enhances ngx.ocsp module to make the cert available as ngx.var.ssl_client_raw_cert in rewrite_by_lua_block
  3. Modify openresty code to build our own image that overwrites the SSL handshake
  4. Some combination of the above
  5. Other?

Solution

  • ngx_http_ssl_module is installed in official OpenResty docker image by default. You don't need to care about RESTY_CONFIG_OPTIONS_MORE.

    IMO the best solution would be using nginx-ssl-variables as reference implementation and set variables you need, for example:

    set_by_lua_block $ssl_client_issuer {
            if ngx.var.https == "on" then
                return require("openssl").x509.read(ngx.var.ssl_client_raw_cert):issuer():oneline()
            end
            return nil
    }
    

    You will need to install lua-openssl. IMO the simplest way to install that module is to include into your Dockerfile (built from an image with luarocks support):

    RUN luarocks install openssl --server=https://rocks.moonscript.org/dev