NGINX.COM
Web Server Load Balancing with NGINX Plus

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 and status 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 the groups 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 the Administrator 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 code 403 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:

  1. 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.
  2. 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.

Hero image

Learn how to deploy, configure, manage, secure, and monitor your Kubernetes Ingress controller with NGINX to deliver apps and APIs on-premises and in the cloud.



About The Author

Liam Crilly

Sr Director, Product Management

About F5 NGINX

F5, Inc. is the company behind NGINX, the popular open source project. We offer a suite of technologies for developing and delivering modern applications. Together with F5, our combined solution bridges the gap between NetOps and DevOps, with multi-cloud application services that span from code to customer.

Learn more at nginx.com or join the conversation by following @nginx on Twitter.