We’re pleased to announce that NGINX Plus Release 14 (R14) is now available to our NGINX Plus subscribers. NGINX Plus is the only all‑in‑one load balancer, content cache, and web server. It’s based on NGINX Open Source, and adds exclusive features along with award‑winning 24‑hour support. NGINX Plus R14 includes new security and clustering enhancements.
With NGINX Plus, you can enforce access controls using JSON Web Tokens (JWTs). NGINX Plus R14 adds support for nested JWT claims, so you can can grant or deny access based on group membership information nested inside a JWT. Native JWT authentication support, first introduced in NGINX Plus R10, enables NGINX Plus to be used as an authentication gateway for your APIs and applications.
Additional NGINX Plus R14 features include:
- Extended clustering support (technology preview) – We invite you to test a preview of new functionality for sharing state information across the NGINX Plus instances in a cluster. In the preview, state for the sticky learn session persistence method is shared. In future releases, we’ll be expanding clustering support to other NGINX Plus features.
- Longer JWT key sizes – In addition to support for nested JWT claims and array data, longer key sizes (up to 512 bits) are now supported for JWT signing algorithms. This provides more security and flexibility when validating JWTs.
- Stream key‑value store and API – The powerful key‑value store and API introduced in Release 13 for HTTP applications is extended to TCP and UDP applications in the
stream
context. - Enhancements to the NGINX JavaScript module – The module, which enables you to run JavaScript code on NGINX Plus, now has additional language support for the JSON object. [The module was formerly called nginScript.] This lets you parse and extract information from JSON responses received from backend APIs natively and use Node.js‑style methods to access your filesystem. The module also now provides backtraces for a wide range of exception and error objects when they occur, to facilitate debugging and troubleshooting.
- More features – NGINX Plus also features an updated live activity monitoring dashboard, a new SSL variable, and upstream server draining.
Changes in Behavior
- The NGINX Plus API has been upgraded to version 2. Check the API compatibility documentation if you’re considering using new NGINX Plus API features.
- The APIs in the Upstream-Conf and extended Status modules (enabled with the
upstream_conf
andstatus
directives) have been deprecated as of NGINX Plus R13. They have been superseded by the new NGINX Plus API, which is used by the updated live activity monitoring dashboard included in R14. - NGINX Plus is now available for Ubuntu 17.10 (Artful Aardvark).
- NGINX Plus is no longer supported on Debian 7 (Wheezy).
NGINX Plus R14 Features in Detail
JWT Enhancements
Deployers of APIs and microservices are turning to the JSON Web Token (JWT, pronounced “jot”) standard for its simplicity and flexibility. A JWT is a compact and highly portable means of exchanging identity information. You can obtain JWTs from a number of issuers, including Okta, OneLogin, and homegrown solutions. NGINX Plus can then grant or deny access based on whether or not the user or API client has presented a valid JWT.
NGINX Plus R14 adds support for nested JWT claims and array data, as well as longer key sizes for JWT signing algorithms. This provides more flexibility and greater security when validating JWTs.
Support for Nested JWT Claims and Array Data
A JWT payload can contain additional “nested” information about the user, such as group membership, which can be used to authorize access to a resource. This helps avoid the need to query a database multiple times to authorize user requests.
Consider the following JWT payload:
{
"exp": 1513429677,
"sub": "xample@example.com",
"aud": "nginx",
"attributes": {
"name": "Xavier Ample",
"room": "A123",
"dept": "Demonstrations"
},
"groups": [
"Administrator",
"Foobar",
"Bazpub"
]
}
In the above JWT, attributes
is a “nested claim” object and groups
is an array. You can use the following configuration snippet to pass the name
value from the attributes
object to the backend and to deny access to users who are not in the Administrator
group.
auth_jwt_claim_set $jwt_groups groups; # Array value will join as comma-separated values
auth_jwt_claim_set $jwt_real_name attributes name; # This value is two levels deep
map $jwt_groups $isAdmin {
"~\bAdministrator\b" 1; # Appears within word boundaries (\b) of CSV list
default 0;
}
server {
listen 443 ssl;
#ssl_*; # Config for SSL/TLS termination
auth_jwt "closed site";
auth_jwt_key_file jwk.json;
location / {
proxy_set_header X-RealName $jwt_real_name; # Pass real name as header
proxy_set_header X-Subject $jwt_claim_sub; # L1 claims set automatically
proxy_pass http://my_backend;
}
location /admin {
if ( $isAdmin = 0 ) {
return 403; # Forbidden
}
proxy_pass http://my_backend;
}
}
Here are more details on how this configuration works:
- Using the
auth_jwt_claim_set
directive, we set the$jwt_groups
NGINX variable to thegroups
array defined in the JWT. The values in the array are separated by commas and assigned to$jwt_groups
. - Using the
map
directive, we search through the list of groups for theAdministrator
keyword. If it’s present, the user is deemed an administrator and$isAdmin
is set to 1. Otherwise$isAdmin
is set to 0. - The
location
block for the /admin URI checks the$isAdmin
variable. If 0, NGINX returns status code403
Forbidden
back to the client.
With NGINX Plus R14, you can also create variables from nested JWT claims. The variables can then be put into HTTP headers before proxying them to backend servers.
In the example above, we use the auth_jwt_claim_set
directive to set the $jwt_real_name
NGINX variable to the value of the name
object within the attributes
claim. The proxy_set_header
directive sets the X-RealName
HTTP header to the value of the name
object and proxies the request to my_backend
.
For more information on all the configuration directives available for use to authenticate JWTs with NGINX Plus, see the reference documentation.
Longer Key Sizes for JWT Signing Algorithms
NGINX Plus R14 now supports 256‑bit, 384‑bit, and 512‑bit signing keys for stronger signature validation and easier integration with identity and access management (IAM) products that use longer signing keys by default. The longer signing keys are available for all supported signature algorithms:
- HMAC with SHA‑2 (“HS”)
- RSA PKCS #1 with SHA‑2 (“RS”)
- Elliptic Curve Digital Signature Algorithm (“ES”)
For example, you can configure NGINX Plus R14 to only accept JSON web tokens signed with the RS512 algorithm:
server {
listen 443 ssl;
#ssl_*; # Config for SSL/TLS termination
auth_jwt "closed site";
auth_jwt_key_file jwk.json;
location / {
if ( $jwt_header_alg != RS512 ) {
return 401;
}
proxy_pass http://my_backend;
}
}
In this case, NGINX Plus does not proxy requests if the JWT has not been signed with the RS512 algorithm, and returns status code 401
Unauthorized
to the client that issued the request.
Note: JWT support is exclusive to NGINX Plus.
Key-Value Store and API for Stream Module
NGINX Plus R13 introduced the Key‑Value Store module for HTTP, allowing you to create, modify, and purge key‑value pairs in one or more shared memory zones on the fly. One great use case for the key‑value store API is using it with fail2ban to create a dynamic IP denylist.
NGINX Plus R14 adds the Key‑Value Store module for Stream, making the same key‑value pair capabilities available for TCP and UDP applications as for HTTP apps.
Dynamically reconfiguring the key‑value store in the stream
context is implemented in NGINX Plus R14 as part of the NGINX Plus API.
Note: The key‑value store and API are exclusive to NGINX Plus.
Enhancements to the NGINX JavaScript Module
The NGINX JavaScript module (formerly called nginScript) is a JavaScript‑based scripting language for NGINX Plus. In NGINX Plus R14, the capabilities of NGINX JavaScript have been extended to further improve programmability. The updated NGINX JavaScript dynamic module package provides the following new enhancements.
JSON Object Support
The JavaScript JSON object is now available as a native object in NGINX JavaScript. This provides a more convenient way to manage complex data structures, and also enables NGINX JavaScript to parse and manipulate JSON responses received from backend APIs.
The following njs
shell example demonstrates how to parse and extract JSON data using built‑in object syntax.
$ njs
interactive njscript
v.<Tab> -> the properties and prototype methods of v.
type console.help() for more information
>> var my_data = '{"colors":[{"name":"red","fancy":"brick dust"}, {"name":"blue","fancy":"sea spray"}]}';
>> var my_object = JSON.parse(my_data);
>> my_object.colors[1].fancy;
sea spray
>>
Filesystem Access
Node.js, the most popular server‑side JavaScript implementation, provides built‑in methods for accessing the OS filesystem (client‑side JavaScript doesn’t allow filesystem access). With NGINX Plus R14, you can now use Node.js filesystem methods in NGINX JavaScript to read and write files, enabling you to customize your application delivery workflow. The following operations are permitted:
- Read –
fs.readFile
,fs.readFileSync
- Write –
fs.writeFile
,fs.writeFileSync
- Append –
fs.appendFile
,fs.appendFileSync
This NGINX JavaScript shell example shows how NGINX JavaScript can be used to read file contents into a variable.
$ njs
interactive njscript
v.<Tab> -> the properties and prototype methods of v.
type console.help() for more information
>> var fs = require('fs');
>> var tz = fs.readFileSync('/etc/timezone');
>> tz
Europe/London
>>
Error Objects and Backtraces
To further help developers with debugging and troubleshooting, a wide range of error objects is now available:
Error
EvalError
InternalError
RangeError
ReferenceError
SyntaxError
TypeError
URIError
Additionally, NGINX JavaScript now provides backtraces for errors and exceptions. The following entry from the error log shows a simple backtrace for a failed system operation.
2017/12/12 01:52:08 [error] 43441#43441: *10 js exception: Error: No such file or directory
at native (native)
at my_function (:1)
at main (native)
, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "localhost:80"
Learn how to get started with NGINX JavaScript on our blog.
NGINX Plus Dashboard Using the NGINX Plus API
NGINX Plus R13 introduced the NGINX Plus API, providing access to real‑time monitoring and metrics in a JSON format. In NGINX Plus R14, the built‑in live activity monitoring dashboard now uses the NGINX Plus API, providing more than 80 monitoring metrics to the user in real time.
The dynamic reconfiguration and extended status APIs used by the dashboard in previous versions of NGINX Plus are deprecated. The APIs are still available in this release and will be included in NGINX Plus R15. They will be removed entirely with NGINX Plus R16, so we encourage you to update your configurations now.
Configuration for the deprecated dashboard looks like this:
location /status { # DEPRECATED
status; # DEPRECATED
# directives controlling access, such as 'allow' and 'deny'
}
location = /status.html { # DEPRECATED
root /usr/share/nginx/html; # DEPRECATED
}
To migrate your existing NGINX Plus instances to the new NGINX Plus dashboard, replace the previous snippet with this:
location /api {
api write=on;
# directives controlling access, such as 'allow' and 'deny'
}
location = /dashboard.html {
root /usr/share/nginx/html;
}
# Redirect requests made to the old dashboard
location = /status.html {
return 301 /dashboard.html;
}
As shown in the snippets, we strongly recommend that you limit access to the API, for example with allow
and deny
directives. Be sure to migrate existing access controls from the /status
location to the /api
location.
For more information about the new NGINX Plus API, see the NGINX Plus R13 announcement.
Note: The built‑in dashboard is exclusive to NGINX Plus.
Draining Upstream Servers in Configuration File
When taking a server offline, you can improve the user experience by allowing existing sessions to complete while preventing new sessions from being established. The server does not go offline until there are no active sessions remaining. This is referred to as draining the server. You can do this dynamically with the NGINX Plus API by sending a PATCH
request that includes {"drain":true}
to the API resource for the relevant server.
NGINX Plus R14 extends this functionality to file‑based configuration by providing a drain
parameter to the upstream server
directive.
upstream my_backend {
server 10.0.0.1;
server 10.0.0.2;
server 10.0.0.3 drain;
}
When you reload the NGINX Plus configuration, the upstream server with IP 10.0.0.3 goes into draining mode. You can later completely decommision the server by removing the corresponding server
directive or replacing the draining
parameter with down
.
Clustering Support for Sticky Learn (Technology Preview)
With NGINX Plus R14, we’re pleased to announce a technology preview of a forthcoming capability for sharing state across a cluster of NGINX Plus instances. The technology preview implements the sticky learn method of session persistence to demonstrate the benefits of sharing session data that would otherwise be individually managed by each instance.
The technology preview is provided as a separate installable package and is available on request. Please contact your NGINX sales representative for access.
Notes:
- The sticky learn clustering functionality is in preview status and as such is not suitable for use in production. If state sharing across a cluster is an important requirement for your environment, we encourage you to test the technology preview and provide feedback to NGINX on how well it meets your needs.
- Technology preview packages are available for CentOS/RHEL/Oracle Linux 7, Debian 8 and 9, and Ubuntu 16.04, 16.10, and 17.10.
Note: Clustering support and sticky‑learn session persistence are both exclusive to NGINX Plus.
Additional Features
NGINX Plus R14 also includes the following enhancements:
- Resolver state persistence across reloads – One way to dynamically reconfigure the set of servers in an upstream group is to use a hostname or domain as the parameter to the
server
directive; DNS resolves the name periodically and NGINX Plus automatically uses the revised set of servers (see the NGINX Plus Admin Guide). NGINX Plus now retains the DNS records for the hostname or domain name across an NGINX Plus reload. Previously, the name had to be re‑resolved after a reload, meaning that requests that arrived before resolution completed could not be serviced. - New SSL client certificate variable – The
$ssl_client_escaped_cert
variable is a new embedded NGINX variable providing you a safe and convenient way to encode your client certificates in an HTTP header so you can send them to your backend applications. The variable is URL‑encoded.
Upgrade or Try NGINX Plus
NGINX Plus R14 includes improved authentication capabilities for your client applications, additional clustering capabilities, NGINX JavaScript enhancements, and notable bug fixes. In particular, NGINX Plus R13 introduced a bug for active health checks whereby an old worker process might perform health checks indefinitely. This has been resolved with NGINX Plus R14.
If you’re running NGINX Plus, we strongly encourage you to upgrade to Release 14 as soon as possible. You’ll pick up a number of fixes and improvements, and upgrading will help NGINX to help you when you need to raise a support ticket. Installation and upgrade instructions are available at the customer portal.
Please carefully review the new features and changes in behavior described in this blog post before proceeding with the upgrade.
If you haven’t tried NGINX Plus, we encourage you to try it out – for web acceleration, load balancing, and application delivery, or as a fully supported web server with enhanced monitoring and management APIs. You can get started for free today with a 30‑day evaluation. See for yourself how NGINX Plus can help you deliver and scale your applications.