Using nginx modules in kong

Hi,

I have a case where I need to use kong together with an nginx modules, such as nchan. So basically I would need to

  • load the nahcn library when kong starts
  • configure a public location for nchan in the same virtual server serving kong API (like the case: Serving both a website and your APIs from Kong
  • configure an internal end point that is accessible only from internal trusted services

I’d appreciate any help to clarify if this can be done and, if so, at the high level, how to achieve those listed above.

Hi,

Yes, doing what you described very much is of the real of the possible, although non-trivial.

load the nchan library when Kong starts

You will need to compile OpenResty for Kong yourself, as detailed in the “install from source” instructions (https://docs.konghq.com/install/source/) and link it against nchan, as developed in the installation section of the library’s “build from source” section: https://nchan.io/#install

You should have something like this:

$ ./configure \
  --with-pcre-jit \
  --with-ipv6 \
  --with-http_realip_module \
  --with-http_ssl_module \
  --with-http_stub_status_module \
  --with-http_v2_module \
  --add-module=path/to/nchan

You can also get fancy and build it as a dynamic module, but I won’t detail it here.

configure a public location for nchan in the same virtual server serving kong API

The resource you linked to is a good pointer for this. You can either:

  1. Create and maintain your own Nginx configuration template (the link you pointed to)
  2. Leverage dynamically injected Nginx directives if you are using Kong 0.14.0 or above (see https://docs.konghq.com/0.14.x/configuration#including-files-via-injected-nginx-directives)

Option 2. is nicer if you already use Kong 0.14.0, and you’d probably end-up with something like this:

$ export KONG_NGINX_PROXY_INCLUDE="/path/to/your/nginx-location.conf"

configure an internal end point that is accessible only from internal trusted services

Here, your nginx-location.conf file will be injected within Kong’s proxy server, and can be anything you want. How you protect the endpoint from untrusted services is up to you.

Hope that helps,

Thanks @thibaultcha for the details. Upon closer look, what I hope to achieve was to have the NCHAN URLs accessed behind Kong in the same nginx process. So not really the case where NCHAN URL is exposed independently from Kong.

For example, I would like to set up Kong and use a security plugin, such as JWT, to secure the NCHAN URL. Is that possible?

In that case, pretty much everything I described in my above message is still relevant. The final result is that a new, internal location block is injected into the nginx configuration.

What you’d need to be able to consume it from Kong itself would be a custom plugin, likely making a subrequest to this location. The plugin can run after the authentication and/or rate-limiting, ip-restriction plugins. See the ngx.location.capture API in the ngx_lua module documentation.

Hope that helps,

Thanks @thibaultcha. To be sure I understand what you said. I need to

  1. Configure NCHAN in a location block
  2. implement a custom plugin that calls the NCHAN location URI and in that plugin it uses ngx.location.capture

How’d I control the order of the plugin invocation so that this custom plugin is executed last?

NCHAN’s main purpose is to push server side events via a long lived HTTP connection from a client. That means what I hope to achieve is

  1. Client establish a long lived HTTP connection to the targeting URI defined in the NCHAN location block.
  2. Kong authenticate the request, as well as executing any additional plugins
  3. Kong calls NCHAN for it to return available events at that time
  4. NCHAN expects that the connection be present so that it can continue to send events

I am not sure how NCHAN would react to the ngx.location.capture call. It might not return the call right away.

If NCHAN returns right away with any available events at that time, would Kong still leave that connection open?

If NCHAN does not return right away, are there ways other than ngx.location.capture for me to consider?

Thanks again for the help!