BLOG | NGINX

NGINX Plus R28の発表

NGINX-Part-of-F5-horiz-black-type-RGB
Robert Haynes サムネール
Robert Haynes
Published November 29, 2022

 

NGINX Plus Release 28 (R28)の提供を開始することをお知らせします。NGINX Plusは、NGINXオープンソースをベースにした、唯一のオールインワン・ソフトウェアWebサーバー、ロードバランサー、リバースプロキシ、コンテンツキャッシュ、およびAPIゲートウェイです。

NGINX Plus R28の新機能は以下の通りです。

  • 追加のTLSメトリクス – NGINX Plus R28は、システム全体、クライアントサイド、およびサーバーサイドのレベルで追加のTLS統計を収集し、プロキシ設定におけるSSL/TLS関連のエラーやクライアントやアップストリームサーバーへの接続のトラブルシューティングを行う際に重要となる情報を提供します。

    NGINX Plusのライブアクティビティモニタリングダッシュボードが更新され、新しいSSLセッションに関するデータが表示されます。

  • クラウドプライベートサービスにおけるPROXYプロトコルv2 TLVのサポート – AWS、Google Cloud Platform、およびMicrosoft Azureの「プライベートサービス」を介して外部クライアントにリソースを利用できるようにする場合、デフォルトではPROXYプロトコルv2ヘッダーのType-Length-Value(TLV)で示されるサービス固有のクライアント識別子はバックエンドサービスに渡されません。NGINX Plus R28では、TLVをデコードし、クライアント識別子をバックエンドサービスに転送するための変数を定義し、httpおよびstreamコンテキスト用のモジュールを提供します。
  • スティッキークッキーsamesiteパラメータの変数サポート – NGINX Plus R28では、sticky cookieディレクティブへのsamesiteパラメータの値を変数にすることができます。この改善により、トラフィックの管理が容易になり、セキュリティも向上します。

その他NGINX Open Sourceから引き継いだ新機能とバグフィックス、そしてNGINX JavaScriptモジュールのアップデートを提供します。

重要な動作の変化

注:NGINX Plus R27以外のリリースからアップグレードする場合、現在利用中のリリースから今回のリリースまで、ブログで紹介されている「重要な動作の変化」の項目を必ず確認してください。

プラットフォーム対応の変更

新たに以下のプラットフォームがサポートされます。

 

  • AlmaLinux 8 and 9 (x86_64, aarch64)
  • Alpine 3.17 (x86_64, arm64)
  • Oracle Linux 9 (x86_64)
  • Rocky Linux 8 and 9 (x86_64, aarch64)

以下プラットフォームはサポート対象外となります。

  • Debian 10 (2022/8 にEOL)

以下プラットフォームはNGINX Plus R29でサポート対象外となる予定です。

  • Alpine 3.13 (2022/11/1にEOL予定)

新機能の詳細

追加のTLSメトリクス

SSL/TLSイベントとエラーを観測できるようにすることは、プロキシ設定、アップストリームサーバー、クライアントのTLSに関連する問題のトラブルシューティングを行う際に重要となります。NGINX Plus R13でNGINX Plus APIが導入されて以来、NGINX Plusはシステム全体のレベルで3つのTLSメトリクスを収集しています。

  • handshakes – SSLハンドシェイクに成功した回数
  • handshakes_failed – SSL ハンドシェイクの失敗数 (SSL ハンドシェイクの後に起こる証明書の検証の失敗は含まない)
  • session_reuses – SSL セッションの再利用回数

NGINX Plus R27<.htmla>以降では、個々のアップストリームサーバーおよび仮想サーバーに対して3つのメトリクスの収集を設定することができます。

NGINX Plus R28では、HTTPモジュールとStreamモジュールの両方でハンドシェイクエラーと証明書検証の失敗の新しいカウンターによりTLSのメトリクスを拡張します(ここではHTTPモジュールについてのみ例を示しますが、Streamのメトリクスについても同様です)。個々のアップストリームサーバーおよび仮想サーバーに対するメトリクス収集に関する設定の詳細は、NGINX Plus R27<.htmla>の発表ブログ<.htmla>を参照してください。

Handshakeエラー

NGINX Plus R28では、以下のハンドシェイクエラーのカウンターが新しく追加されました。

  • handshake_timeout – ハンドシェイクタイムアウトによるハンドシェイク失敗の数
  • no_common_cipher – ハンドシェイクの当事者間で共通の暗号がないためにハンドシェイクに失敗した回数(アップストリームサーバーへの接続では適用されず値は収集の対象外となります)
  • no_common_protocol – 当事者間で共通のプロトコルがないために発生したハンドシェイクの失敗の数
  • peer_rejected_cert – NGINX Plusが提示した証明書を相手が拒否、そして適切に警告メッセージの提供を行い、ハンドシェイクが失敗した数

証明書の検証の失敗

証明書の検証を設定する際に、新たなAPIの出力としてverify_failuresセクションで証明書検証の失敗が報告されるようになりました。

証明書検証の失敗が発生すると、対応する原因のメトリクスがインクリメントされ、接続が切断されます。ただし、これらの失敗はハンドシェイクが成功した後に発生するため、基本的なhandshakesのカウンターは依然としてインクリメントされることに注意してください。

証明書の検証に失敗した場合のメトリクスは次のとおりです。

  • expired_cert – 対応から期限切れの証明書を提示された
  • hostname_mismatch – サーバー証明書でホスト名が一致しない(クライアントへの接続は収集の対象外となります)
  • no_cert – クライアントが要求される証明書の提示を行わなかった(アップストリームサーバーへの接続は収集の対象外となります)
  • revoked_cert – 対抗から執行された証明書が提示された
  • other – 証明書の検証におけるその他の失敗に関するカウンター

メトリクスのサンプル出力

システム全体のレベルでのHTTP接続におけるTLSメトリクスのサンプルです。

$ 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
    }
}

クライアントとHTTP仮想サーバー「s9」間の接続におけるメトリクスのサンプルです(先述の通りこれらの接続ではhostname_mismatchカウンターは収集されません)。

$ 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
        }
    }
    ...
}

アップストリームグループ「u2」のサーバーへのHTTP接続のサンプルメトリクスです(前述のとおり、no_certおよびno_common_cipherカウンターは、これら接続では収集されません)。

$ 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に表示される拡張されたTLSメトリクス

NGINX Plus R28以降では、ライブアクティビティを表示するダッシュボードに、上記の新しいTLSメトリクスが表示されます。このスクリーンショットは、クライアントへの接続のメトリクスを表示しています。新しいメトリクスを表示するには、図のようにSSL > Handshakes failedの列の値にマウスオーバーします。

クラウドプライベートサービスにおけるPROXYプロトコルv2 TLSのサポート

業界を牽引する3大クラウドプロバイダー -Amazon Web Services(AWS)、Google Cloud Platform(GCP)、Microsoft Azure- は、それぞれ「プライベートサービス」を提供しており、パブリックインターネットに公開せずに外部のクライアントがサービスにアクセスできるようにするサービスを提供します。各サービスは、PROXYプロトコルv2ヘッダーのTLV(type-length-value)で表現されるクライアント識別子を利用します。サービス固有の識別子は以下の通りです。

デフォルトでは、これらのクライアント識別子はバックエンドサービスに渡されません。NGINX Plus R28では、httpおよびstreamコンテキスト用のモジュールとしてngx_http_proxy_protocol_vendor_moduleおよびngx_stream_proxy_protocol_vendor_moduleが導入されており、TLV をデコードしてバックエンドサービスに識別子を転送するための変数が定義されます。

NGINX PlusがPROXYプロトコルを使用してIPアドレスやクライアントに関するその他の情報を取得する方法についての一般的な情報は、NGINX Plus Admin Guideの「Accepting the PROXY Protocol」を参照してください。

AWSでのPROXYプロトコルv2のサポート

AWSでは、Virtual Private Cloud(VPC)エンドポイントサービスを経由してクライアントから来るトラフィックの送信元IPアドレスは、Network Load BalancerノードのプライベートIPアドレスとなります。バックエンドアプリケーションがクライアントの実際のIPアドレスやその他の識別子を必要とする場合、PROXYプロトコルv2ヘッダーから取得することができます。

AWSでは、PROXYプロトコルv2ヘッダーのPP2_SUBTYPE_AWS_VPCE_IDに含まれるエンドポイントのVPC IDをカスタムTLV形式でエンコードしています。(詳細については、AWSのドキュメントを参照してください)。

フィールド 長さ(オクテット) 説明
タイプ 1 PP2_TYPE_AWS (0xEA)
長さ 2 値の長さ
1 PP2_SUBTYPE_AWS_VPCE_ID (0x01)
様々な値(値の長さマイナス1) エンドポイントのID

NGINX Plus R28はTLVをデコードし、エンドポイントIDを$proxy_protocol_tlv_aws_vpce_id変数でバックエンドアプリケーションに渡します。

注:$proxy_protocol_tlv_aws_vpce_id変数を参照するserverブロックでは、listen[HTTP][Stream]ディレクティブにproxy_protocolパラメータも含める必要があります。例として、下記のproxy_protocol_v2.confの8行目を参照ください。

このAWSの設定例では、VPC IDを確認し、問題なければadd_headerディレクティブの2番目のパラメータとしてバックエンドアプリケーションに渡しています。

 

GCPでのPROXYプロトコルv2のサポート

GCP Private Service Connectでは、クライアントからのトラフィックの送信元IPアドレスは「サービスのVPCネットワーク内のPrivate Service Connectサブネットの1つのアドレス」となります。バックエンドアプリケーションがクライアントの実IPアドレスやその他の識別子を必要とする場合、PROXYプロトコルv2ヘッダーから取得することができます。

GCPでは、カスタムTLVによって、PROXYプロトコルv2ヘッダpscConnectionIdの一意の(その時点の)接続IDがエンコードされます (詳細については、GCP documentationを参照してください)。

フィールド 長さ(オクテット) 説明
タイプ 1 0xE0 (PP2_TYPE_GCP)
長さ 2 0x8 (8バイト)
8 ネットワーク順の8バイトのpscConnectionId

NGINX Plus R28はTLVをデコードし、pscConnectionIdの値を$proxy_protocol_tlv_gcp_conn_id変数を用いてバックエンドアプリケーションに渡します。

注:$proxy_protocol_tlv_gcp_conn_id変数を参照するserverブロックでは、listen[HTTP][Stream]指令にproxy_protocolパラメータも含める必要があります。例として、上記のproxy_protocol_v2.confの8行目を参照してください。

Microsoft AzureでのPROXYプロトコルv2のサポート

Microsoft Azure Private Linkでは、クライアントからのトラフィックの送信元IPアドレスは、「プロバイダの仮想ネットワークから割り当てられたNAT IP[アドレス]を使用してサービスプロバイダ側でネットワークアドレス変換(NAT)」されたものです。バックエンドアプリケーションがクライアントの実IPアドレスやその他の識別子を必要とする場合、PROXYプロトコルv2ヘッダーから取得することができる。

Azureでは、カスタムTLVベクトルがPROXYプロトコルv2ヘッダーPP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKIDでクライアントのLinkIDをエンコードしています (詳細については、Azureのドキュメントを参照してください)。

フィールド 長さ(オクテット) 説明
タイプ 1 PP2_TYPE_AZURE (0xEE)
長さ 2 値の長さ
1 PP2_SUBTYPE_AZURE_PRIVATEENDPOINT_LINKID (0x01)
4 ライベートエンドポイントのLINKIDを表すUINT32 (4バイト) リトルエンディアン形式でエンコードされている。

NGINX Plus R28はTLVをデコードし、LinkIDを$proxy_protocol_tlv_azure_pel_id変数でバックエンドアプリケーションに渡します。

注:$proxy_protocol_tlv_azure_pel_id変数を参照するserverブロックでは、listen[HTTP][Stream]ディレクティブに proxy_protocolパラメータも含める必要があります。例として、上記のproxy_protocol_v2.confの8行目を参照してください。

スティッキークッキーsamesiteパラメータの変数サポート

以前のNGINX Plusのリリースでは、sticky cookieディレクティブのsamesiteパラメータに3種類の値(strictlaxnone)の指定が可能でした。NGINX Plus R28では、この値を変数にすることもできます。

デフォルトでは(samesiteパラメータがなし)、NGINXはSameSite属性をCookieに注入しません。samesiteパラメータが変数の場合、結果は実行時にその変数がどのように解決されるかに依存します。

  • 標準的な値(strict, lax, none)の1つの場合 – NGINXはSameSite属性にその値を指定します
  • 空の値("") の場合- NGINXはSameSite属性を注入しません
  • それ以外の値にすると、設定ミスを示す – NGINXはSameSite属性をStrict(最も安全な設定)に設定して注入する

このサンプル設定では、HTTP User-Agentヘッダーの値に基づいてsamesite属性を設定します (これはSameSite属性をサポートしないレガシークライアントに適しています)。

 

NGINX Plus R28のその他の強化点

NGINX Open Sourceから引き継いだ変更点

NGINX Plus R28は、NGINX Open Source 1.23.2をベースに、NGINX Plus R27のリリース以降(NGINX 1.23.0から1.23.2まで)の機能変更およびバグフィックスを継承しています。変更点およびバグ修正は以下のとおりです。

  • HTTP resolverディレクティブの新しいipv4=offパラメータは、IPv4 アドレスのルックアップを無効にします。
  • ssl_session_cacheディレクティブのsharedパラメータで HTTP セッション情報の共有キャッシュを有効にすると、TLS セッションチケットのキーが自動的にローテートされるようになりました。
  • いくつかのタイプのTLS/SSLエラーが記録される重要度レベルが、critからinfoに引き下げられました。

これらのリリースから継承された新機能、変更点、バグ修正の完全なリストは、CHANGESを参照してください。

NGINX JavaScriptモジュールのアップデート

NGINX Plus R28には、NGINX JavaScriptモジュール(njs)のバージョン0.7.5から0.7.8で行われた変更と修正が採り入れられています。ブログのMake Your NGINX Config Even More Modular and Reusable with njs 0.7.7で、最も重要なものをいくつか取り上げています。完全なリストについては、Changesを参照してください。

NGINX Plusのアップグレードまたは試用

NGINX Plusを実行している場合、できるだけ早くNGINX Plus R28にアップグレードすることを強くお勧めします。また、いくつかの追加修正と改善点をピックアップし、サポートチケットを発行する必要があるときにNGINXを支援することができるようになります。

NGINX Plusをまだお試しでない方は、セキュリティ、ロードバランシング、APIゲートウェイとして、あるいは強化された監視・管理APIを備えたフルサポートのウェブサーバーとして、ぜひお試しください。30日間の無料トライアルで、今すぐ始めることができます。


"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."