nginx / njs-acme

Nginx NJS module runtime to work with ACME providers like Let's Encrypt for automated no-reload TLS certificate issue/renewal.
Apache License 2.0
57 stars 9 forks source link

Use NJS Shared Dict to store cert/key in memory #18

Closed ivanitskiy closed 1 year ago

ivanitskiy commented 1 year ago

NJS 0.8.0 introduced a new functionality called shared dict: https://mailman.nginx.org/pipermail/nginx-announce/2023/A3O7JLCSI6DYGIYQA4XCXLJEUW2EGIHS.html

This would allow us to store certs in memory and avoid reading cert/key from disk on each SSL handshake using js_set like we do now in the example config:

    js_set $dynamic_ssl_cert acme.js_cert;
    js_set $dynamic_ssl_key acme.js_key;

We can persist cert/key on disk and store it in memory to improve performance:

Details about shared dict:

- shared dictionaries:
A shared dictionary keeps the key-value pairs shared between worker
processes. This allows to cache data in memory and share it between
workers.

: example.conf:
:   # Creates a 1Mb dictionary with string values,
:   # removes key-value pairs after 60 seconds of inactivity:
:   js_shared_dict_zone zone=foo:1M timeout=60s;
:
:   # Creates a 512Kb dictionary with string values,
:   # forcibly removes oldest key-value pairs when the zone is overflowed:
:   js_shared_dict_zone zone=bar:512K timeout=30s evict;
:
:   # Creates a 32Kb permanent dictionary with numeric values:
:   js_shared_dict_zone zone=num:32k type=number;
:
: example.js:
:    function get(r) {
:        r.return(200, ngx.shared.foo.get(r.args.key));
:    }
:
:    function set(r) {
:        r.return(200, ngx.shared.foo.set(r.args.key, r.args.value));
:    }
:
:    function delete(r) {
:        r.return(200, ngx.shared.bar.delete(r.args.key));
:    }
:
:    function increment(r) {
:        r.return(200, ngx.shared.num.incr(r.args.key, 2));
:    }

Expected behavior

The proposed change in acme.js_cert and acme.js_key:

Your environment

min required version NJS 0.8.0

Additional context

We currently read files (cert and key) from disk on each SSL handshake in the reference implementation. In NginxPlus is already possible to use the KV feature to store cert/key in memory as of today. Shared Dict is a sunset of KV functionality for the Nginx OSS version.