Is it possible to implement OIDC in front of Nginx Stream with OpenResty?

1.1k Views Asked by At

I would like to know if it is possible to use the OpenResty OIDC module as an authentication proxy within an NGINX stream configuration.

(I don't have acccess to NGINX Plus unfortunately)

I have used NGINX with Stream configurations in the past to proxy access to upstream tcp resources and it works like a charm.

I am currently looking at implementing an OIDC proxy in front of various resources, both static html and dynamic apps, because we have an in-house OIDC IDAM provider. I came across OpenResty, and in particular the lua-resty-oidc module, and thanks to some wonderful guides, (https://medium.com/@technospace/nginx-as-an-openid-connect-rp-with-wso2-identity-server-part-1-b9a63f9bef0a , https://developers.redhat.com/blog/2018/10/08/configuring-nginx-keycloak-oauth-oidc/ ), I got this working in no time for static pages, using an http server nginx config.

I can't get it working for stream configurations though. It looks like the stream module is enabled as standard for OpenResty, but from digging around I don't think the 'access_by_lua_block' function is allowed in the stream context.

This may simply not be supported, which is fair enough when begging off other people's great work, but I wondered if there was any intention to include suport within OpenResty / lua-resty-oidc in the future, or whether anyone knew of a good workaround.

This was my naive attempt to get it working but the server complains about the 'access_by_lua_block' command at run time.

2019/08/22 08:20:44 [emerg] 1#1: "access_by_lua_block" directive is not allowed here in /usr/local/openresty/nginx/conf/nginx.conf:49
nginx: [emerg] "access_by_lua_block" directive is not allowed here in /usr/local/openresty/nginx/conf/nginx.conf:49
events {
  worker_connections 1024;
}

stream {

  lua_package_path "/usr/local/openresty/?.lua;;";  

  resolver 168.63.129.16;  

  lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
  lua_ssl_verify_depth 5;  

  # cache for discovery metadata documents
  lua_shared_dict discovery 1m;
  # cache for JWKs
  lua_shared_dict jwks 1m;  

  upstream geyser {

    server geyser-api.com:3838;

  }

  server {

    listen 443 ssl;    

    ssl_certificate /usr/local/openresty/nginx/ssl/nginx.crt;
    ssl_certificate_key /usr/local/openresty/nginx/ssl/nginx.key;    

    access_by_lua_block {

        local opts = {
           redirect_uri_path = "/redirect_uri",
           discovery = "https://oidc.provider/discovery",
           client_id = "XXXXXXXXXXX",
           client_secret = "XXXXXXXXXXX",
           ssl_verify = "no",
           scope = "openid",
           redirect_uri_scheme = "https",
        }

        local res, err = require("resty.openidc").authenticate(opts)

        if err then
          ngx.status = 500
          ngx.say(err)
          ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
        end

        ngx.req.set_header("X-USER", res.id_token.sub)
    }

    proxy_pass geyser;

  }
}

Anyone have any advice?

1

There are 1 best solutions below

1
On

i don't think that's possible.
However to be sure, you should try creating an issue on the official github
https://github.com/zmartzone/lua-resty-openidc/issues
They helped me solve a similar issue before