Announcing NGINX Plus R28

Original: https://www.nginx.com/blog/nginx-plus-r28-released/

We’re happy to announce the availability of NGINX Plus Release 28 (R28). Based on NGINX Open Source, NGINX Plus is the only all-in-one software web server, load balancer, reverse proxy, content cache, and API gateway.

New and enhanced features in NGINX Plus R28 include:

Rounding out the release are new features and bug fixes inherited from NGINX Open Source and updates to the NGINX JavaScript module.

Important Changes in Behavior

Note: If you are upgrading from a release other than NGINX Plus R27, be sure to check the Important Changes in Behavior section in the announcement blogs for all releases between your current one and this one.

Changes to Platform Support

New operating systems and architectures supported:

Older operating systems removed:

Older operating systems and architectures deprecated and scheduled for removal in NGINX Plus R29:

New Features in Detail

Additional TLS Metrics

Observability of SSL/TLS events and errors is important when troubleshooting TLS‑related problems with proxy configuration, upstream servers, and clients. Since the introduction of the NGINX Plus API in NGINX Plus R13, NGINX Plus has collected three TLS metrics at the system‑wide level:

In NGINX Plus R27 and later, you can configure collection of the three metrics for individual upstream servers and virtual servers.

NGINX Plus R28 expands the set of TLS metrics with new counters for handshake errors and certificate validation failures in both HTTP and Stream modules (here we provide examples only for HTTP modules, but the available Stream metrics are similar). For details on configuring metrics collection for individual upstream servers and virtual servers, see the NGINX Plus R27 announcement blog.

Handshake Errors

Counters for the following handshake errors are new in NGINX Plus R28:

Certificate Verification Failures

Certificate verification failures are now reported in the new verify_failures section of API output when you configure certificate verification:

When a certificate verification failure occurs, the metric for the corresponding cause is incremented and the connection torn down. Note, however, that the basic handshakes counter is still incremented because these failures occur after the handshake succeeds.

The metrics for failed certificate validation are:

Sample Metrics Output

Here’s a set of sample TLS metrics for HTTP connections at the system‑wide level:

$ curl 127.0.0.1:8080/api/8/ssl
{
    "handshakes": 32,
    "session_reuses": 0,
    "handshakes_failed": 8,
    "no_common_protocol": 4,
    "no_common_cipher": 2,
    "handshake_timeout": 0,
    "peer_rejected_cert": 0,
    "verify_failures": {
        "no_cert": 0,
        "expired_cert": 2,
        "revoked_cert": 1,
        "hostname_mismatch": 2,
        "other": 1
    }
}

Here’s a set of sample metrics for connections between clients and the HTTP virtual server s9 (as noted previously, the hostname_mismatch counter is not collected for such connections):

$ curl 127.0.0.1:8080/api/8/http/server_zones/s9
{
    ...
    "ssl": {
        "handshakes": 0,
        "session_reuses": 0,
        "handshakes_failed": 1,
        "no_common_protocol": 0,
        "no_common_cipher": 1,
        "handshake_timeout": 0,
        "peer_rejected_cert": 0,
        "verify_failures": {
            "no_cert": 0,
            "expired_cert": 0,
            "revoked_cert": 0,
            "other": 0
        }
    }
    ...
}

Here’s a set of sample metrics for HTTP connections to servers in the u2 upstream group (as noted previously, the no_cert and no_common_cipher counters are not collected for such connections):

$ curl 127.0.0.1:8080/api/8/http/upstreams/u2
{
    "peers": [
        {
            "id": 0,
            "server": "127.0.0.1:8082",
            "name": "127.0.0.1:8082",
            ...
            "ssl": {
                "handshakes": 1,
                "session_reuses": 0,
                "handshakes_failed": 0,
                "no_common_protocol": 0,
                "handshake_timeout": 0,
                "peer_rejected_cert": 0,
                "verify_failures": {
                    "expired_cert": 1,
                    "revoked_cert": 0,
                    "hostname_mismatch": 0,
                    "other": 0
                }
            },
            ...
        }
    ],
}

NGINX Plus Dashboard Displays the Extended TLS Metrics

For NGINX Plus R28 and later, the live activity monitoring dashboard displays the new TLS metrics described above. This screenshot shows metrics for connections to clients. To view the new metrics, mouse over the value in the SSL > Handshakes failed column as shown.

Support for PROXY Protocol v2 TLVs in Cloud Private Services

The three leading cloud providers – Amazon Web Services (AWS), Google Cloud Platform (GCP), and Microsoft Azure – each offer a “private service” where you can enable external clients to access your services without exposing them on the public Internet. Each service makes use of a client identifier which is represented in a type-length-value (TLV) vector in a PROXY protocol v2 header. The service‑specific identifiers are:

By default these client identifiers are not passed to backend services. NGINX Plus R28 introduces modules for the http and stream contexts – ngx_http_proxy_protocol_vendor_module and ngx_stream_proxy_protocol_vendor_module – which decode the TLV and define a variable for forwarding the identifier to backend services.

For general information about how NGINX Plus uses the PROXY protocol to obtain IP addresses and other information about clients, see Accepting the PROXY Protocol in the NGINX Plus Admin Guide.

PROXY Protocol v2 Support for AWS

In AWS, the source IP address for traffic coming from clients through a Virtual Private Cloud (VPC) endpoint service is the private IP address of the Network Load Balancer node. If the backend application requires the real IP addresses and other identifiers for clients, they can be obtained from PROXY protocol v2 headers.

In AWS, a custom TLV vector encodes the VPC ID of the endpoint in the PROXY protocol v2 header PP2_SUBTYPE_AWS_VPCE_ID. (For more information, see the AWS documentation.)

Field Length (Octets) Description
Type 1 PP2_TYPE_AWS (0xEA)
Length 2 The length of value
Value 1 PP2_SUBTYPE_AWS_VPCE_ID (0x01)
Varies (value length minus 1) The ID of the endpoint

NGINX Plus R28 decodes the TLV and passes the endpoint ID to backend applications in the $proxy_protocol_tlv_aws_vpce_id variable.

Note: In the server block where you reference the $proxy_protocol_tlv_aws_vpce_id variable, you must also include the proxy_protocol parameter to the listen[HTTP][Stream] directive. For an example, see line 8 of proxy_protocol_v2.conf just below.

This sample configuration for AWS checks that the VPC ID is acceptable and if so passes it to the backend application as the second parameter to the add_header directive:

PROXY Protocol v2 Support for GCP

In GCP Private Service Connect, the source IP address for traffic coming from clients is an “address in one of the Private Service Connect subnets in the service producer’s VPC network”. If the backend application requires the real IP addresses and other identifiers for clients, they can be obtained from PROXY protocol v2 headers.

In GCP, a custom TLV vector encodes the unique (at the time) connection ID in the PROXY protocol v2 header pscConnectionId. (For more information, see the GCP documentation.)

Field Length (Bytes) Description
Type 1 0xE0 (PP2_TYPE_GCP)
Length 2 0x8 (8 bytes)
Value 8 The 8‑byte pscConnectionId in network order

NGINX Plus R28 decodes the TLV and passes the value of pscConnectionId to backend applications in the $proxy_protocol_tlv_gcp_conn_id variable.

Note: In the server block where you reference the $proxy_protocol_tlv_gcp_conn_id variable, you must also include the proxy_protocol parameter to the listen[HTTP][Stream] directive. For an example, see line 8 of proxy_protocol_v2.conf above.

PROXY Protocol v2 Support for Microsoft Azure

In Microsoft Azure Private Link, the source IP address for traffic coming from clients is the “network address translated (NAT) on the service provider side using the NAT IP [address] allocated from the provider’s virtual network”. If the backend application requires the real IP addresses and other identifiers for clients, they can be obtained from PROXY protocol v2 headers.

In Azure, a custom TLV vector encodes the client’s LinkID in the PROXY protocol v2 header PP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKID. (For more information, see the Azure documentation.)

Field Length (Octets) Description
Type 1 PP2_TYPE_AZURE (0xEE)
Length 2 Length of value
Value 1 PP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKID (0x01)
4 UINT32 (4 bytes) representing the LINKID of the private endpoint. Encoded in little‑endian format.

NGINX Plus R28 decodes the TLV and passes the LinkID to backend applications in the $proxy_protocol_tlv_azure_pel_id variable.

Note: In the server block where you reference the $proxy_protocol_tlv_azure_pel_id variable, you must also include the proxy_protocol parameter to the listen[HTTP][Stream] directive. For an example, see line 8 of proxy_protocol_v2.conf above.

Variable Support for the Sticky Cookie samesite Parameter

In previous NGINX Plus releases, three static values (strict, lax, and none) were acceptable for the samesite parameter to the sticky cookie directive. In NGINX Plus R28, the value can also be a variable.

By default (there is no samesite parameter), NGINX does not inject the SameSite attribute into the cookie. When the samesite parameter is a variable, the result depends on how the variable resolves at runtime:

This sample configuration sets the samesite attribute based on the value of the HTTP User-Agent header (this is good for legacy clients that don’t support the SameSite attribute):

Other Enhancements in NGINX Plus R28

Changes Inherited from NGINX Open Source

NGINX Plus R28 is based on NGINX Open Source 1.23.2. and inherits functional changes and bug fixes made since NGINX Plus R27 was released (in NGINX 1.23.0 through 1.23.2). Changes and bug fixes include:

For the full list of new features, changes, and bug fixes inherited from these releases, see the CHANGES file.

Changes to the NGINX JavaScript Module

NGINX Plus R28 incorporates changes and fixes made in versions 0.7.5 through 0.7.8 of the NGINX JavaScript module (njs). We have highlighted some of the most significant ones in Make Your NGINX Config Even More Modular and Reusable with njs 0.7.7 on our blog. For a full list, see the Changes file.

Upgrade or Try NGINX Plus

If you’re running NGINX Plus, we strongly encourage you to upgrade to NGINX Plus R28 as soon as possible. You’ll also pick up several additional fixes and improvements, and it will help NGINX to help you when you need to raise a support ticket.

If you haven’t tried NGINX Plus, we encourage you to try it out – for security, load balancing, and API gateway, or as a fully supported web server with enhanced monitoring and management APIs. You can get started today with a free 30-day trial.

Retrieved by Nick Shadrin from nginx.com website.