NGINX.COM
Web Server Load Balancing with NGINX Plus


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

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

重要な動作の変化

アップストリームゾーンに必要なメモリの増加

HTTPレスポンスコードの詳細なレポート」で詳しく説明しているように、NGINX Plus R25はクラスごとの集計カウントだけでなく、個々のステータスコードのカウントも提供します。NGINX Plusがリバースプロキシまたはロードバランサーとして構成されている場合、上流の「ピア」(バックエンドサーバ)を監視するために使用する共有メモリゾーンのサイズを大きくする必要がある場合があります(ピア数が20以上ある場合)。

NGINX Plus R25 は、共有メモリゾーンのプロビジョニングが不十分な場合に起動せず、アップグレードに失敗することがあります。アップグレードの前に、各アップストリームゾーンのメモリ使用率を確認することが重要です。メモリ割り当ての確認と調整方法については、「起動時の失敗を防ぐために十分なメモリを割り当てる」を参照してください。

NGINX Plusレポ構成とインストール手順の変更点

NGINX Plus R24のリリース時に、すべてのNGINXソフトウェアのパッケージリポジトリが再編成され、NGINX Plusのインストール手順が変更される結果となりました。

NGINX Plusをインストールまたはアップグレードすると、オペレーティングシステムのパッケージマネージャー(aptyum、または同等のもの)がNGINX Plus用のソフトウェアリポジトリで構成されます。古いレポを使用するように構成された既存のシステム(NGINX Plus R23以前を実行しているもの)では、新しいレポを参照するようにパッケージマネージャーを更新する必要があります。F5 Knowledge Baseに記載されている手順を参照してください。

NGINX Plus R25の初期インストールを行う場合、『NGINX Plus Admin Guide』の「NGINX Plusのインストール」を参照してください。

注:新しいソフトウェアリポジトリを使用する必要があります。古いリポジトリは更新されなくなり、今後のインストールやアップグレードでエラーが発生する可能性があります。

非推奨のクッキー・フラグ・モジュール

NGINX Plus R23のリリース時に発表されたように、サードパーティのCookie Flagモジュールは非推奨であり、NGINX Plus R26でダイナミックモジュールレポから削除される予定です。このモジュールで定義されているset_cookie_flagディレクティブは、ビルトインのproxy_cookie_flagsディレクティブに置き換えられます。できるだけ早く、設定内の set_cookie_flag ディレクティブを proxy_cookie_flags ディレクティブに置き換えることをお勧めします。

プラットフォームサポートの変更

  • 新しいOSに対応しました。
    • Debian 11 (x86_64, aarch64)
    • Alpine Linux 3.14 (x86_64, aarch64)
  • 古いOSがサポート対象外になりました。
    • Alpine Linux 3.10; サポートされている最も古いバージョンは3.11です。
    • Amazon Linux 1 (2018.03+); Amazon Linux 2 LTS に切り替えます。
    • FreeBSD 11.4+; 最も古いサポートバージョンは12.1+です。
    • Ubuntu 16.04 LTS; 最も古いサポートバージョンは18.04 LTSです。
  • 以下OSは非推奨となり、NGINX Plus R26で削除される予定です。
    • Alpine Linux 3.11

新機能の詳細

JSONウェブトークンの使用例と機能の追加

NGINX Plus R24は、暗号化されたJSONウェブトークン(JWE)のサポートを開始し、データの機密性を備えることで、人気のあるクライアント認証方法の1つを拡張しています。NGINX Plus R25は、この機能をベースに、署名付き(JWS)および暗号化(JWE)の両方のユースケースによりJWTを用いた認証のセキュリティを向上し、より高度な認証機能をサポートします。この強化により、個人を特定できる情報(PII)の漏洩リスクを低減し、より柔軟な対応が可能になります。NGINX Plusの新しいJWTの機能と強化された機能は以下の通りです。

復号化されたJWE暗号文の変数

JWTは、HTTPリクエストのステートレス認証(つまり、トークンベース認証)の方法として広く利用され、信頼されています。エンドユーザの属性をトークンのペイロードで送信することにより、JWTはリクエストをより安全にすることができます。しかし、暗号化されていない個人情報をウェブクライアントに保存することによるリスクは、セキュリティ研究者とDevSecOps実務者の間で緊急の懸念事項であるという点で一致しています。そのため、JSON Web Encryption標準(RFC 7516)が開発され、暗号化トークンの実装に関するガイドラインが提供されています。

NGINX Plus R24はJWEのサポートを導入し、クレームセット全体のデータの整合性と機密性を提供します。暗号化されたトークン内に個人を特定できる情報(PII)をエンコードすることで、JWT使用時のデータ漏えいのリスクを大幅に軽減します。

NGINX Plus R25は、新しい変数 $jwt_payload によりJWEのサポートを開始し、NGINX PlusがJWEと暗号文を復号化し、HTTPリクエストの処理中に平文にアクセスできるようにします。この新機能は、高度なアクセス制御ポリシーやリクエストルーティングの実装に使用できるほか、ユーザがバックエンドアプリケーションのJWE復号化レイヤーとしてNGINX Plusを展開することも可能になります。

ネストしたJWTのサポート

JWEトークンは、CDNや他のTLSを終端するプロキシを経由する場合にも暗号文が機密性を保持するため、個人情報保護に効果的です。しかし、暗号化は諸刃の剣であり、JWEはアプリケーション環境に複雑さをもたらす可能性があります。この問題に対処する方法として、ネストされたJWTを使用することが挙げられます。

Diagram showing structure of a nested JWT
ネストされたJWTの詳細

ネストされたJWTは、JWEの暗号文としてJWSを埋め込みます。NGINX Plus R25では、JWSとJWEを同時にサポートすることで、HTTPリクエストの認証方法としてネストされたJWTを実現しています。NGINX Plusは1回の操作で、JWEの暗号文を復号し、得られた平文をJWSとして検証し、同封のトークン内のexp(有効期限)とnbf(未使用)のクレームを用いて有効であることを確認することができるようになりました。これにより、JWEの中に暗号化したペイロード保持することで、既存のJWSの環境を拡張することが可能になります。

次のコンフィギュレーションスニペットは、そのプロセスを示しています。auth_jwt_typeディレクティブへの新しいネストされたパラメータは、NGINX PlusにJWE復号化とJWS検証の両方を実行するように指示します。また、JWTヘッダとJWTクレーム用の変数が評価される方法にも影響します。

  • auth_jwt_header_set ディレクティブは、外側のJWEヘッダに対して処理を行います。
  • auth_jwt_claim_set ディレクティブはネストされた JWS クレームに対して処理を行います。
  • $jwt_header_name 変数は、外側の JWE ヘッダのプロパティを含みます。
  • $jwt_claim_name 変数は、ネストされた JWS クレームを含みます。

以下の設定により、NGINX Plusは追加のHTTPリクエストヘッダを構築し、バックエンドアプリケーションに送信します。JWEヘッダの暗号化アルゴリズム($jwt_header_enc変数)とJWSペイロードのJWTサブジェクトクレーム($jwt_claim_sub変数)は、オリジナルのリクエストでプロキシされます。これは、アプリケーションが暗号化のコーディングやライブラリを実装することなく、HTTPヘッダを利用するだけでJWEベースの認証を活用できることを意味します。



ゼロトラストアーキテクチャで動作しているユーザのために、以下の設定は、バックエンドアプリケーションが $jwt_payload 変数に格納されたJWSトークンを検証することを可能にします。この変数には、JWE 暗号文の復号化されたプレーンテキストバージョンが含まれています。ネストされたJWTがある場合、JWSはベアラートークンとしてバックエンドアプリケーションに渡される可能性があります。


本質的に、ネストされたJWTは、バックエンドアプリケーションのために「通常のJWT」署名付きトークンを解析またはプロキシングしながら、NGINX Plusが同時に安全なトークンを解読および検証することを可能にすることによって、操作を合理化してアプリケーションセキュリティを向上させます。

JWEの非対称暗号化について

NGINX Plus R24では、AES標準を使用したトークンの対称型暗号化のサポートが導入されました。NGINX Plus R25では、RSAキーペアを使用した非対称暗号化のサポートが追加されました。非対称暗号は、RSA(Rivest-Shamir-Adleman)アルゴリズムを使用して数学的に互いにリンクされた暗号化と復号化のための異なるキー(公開および非公開)を使用し、クライアントとサーバ間のHTTPSトラフィックのSSL/TLS暗号化で使用されているのと同じメカニズムです。

NGINX Plus R25は、鍵管理アルゴリズムとしてOEAP(Optimal Asymmetric Encryption Padding)付きのRSAをサポートしており、NGINX Plus側で明示的に設定する必要はありません。JWSのalg(アルゴリズム)ヘッダでサポートされている値は、RSA-OAEPRSA-OAEP-256RSA-OAEP-384およびRSA-OAEP-512です。

以下の構成では、auth_jwt_key_fileディレクティブのパラメータとして、(アンラップ)RSAプライベートキーを含むJSON Web Key(JWK)ファイルを指定するだけで、JWEに非対称暗号を実装できます(auth_jwt_key_requestディレクティブも使用可能です)。


マルチソースJWK対応

ネストされたJWTを活用するということは、関連するJWKが複数のソースから来る可能性が高いことを意味します。NGINX Plus R25は、同じコンテキストで複数のauth_jwt_key_fileおよびauth_jwt_key_requestディレクティブをサポートしています。NGINX Plusは、指定されたすべてのソースからキーをロードし、結合されたキーセットの中から一致する検証キーを探します。外部のIDプロバイダーによって発行され、暗号化が別のプロセスによって行われたJWE内にネストされているJWSを扱うときに非常に便利です。

この機能は、APIゲートウェイとして展開されたNGINX Plusにさらなる柔軟性、セキュリティ、そして高度な処理を可能とします。

カスタムJWT検証ルール

NGINX PlusをAPIゲートウェイとしてデプロイする場合、JWTクレームを検査してきめ細かいアクセス制御を実装することが一般的です。これは、複雑な構成につながる可能性があります。以前のNGINX Plusのリリースでは、if設定ブロックを使用してJWTクレームを評価できましたが、このアプローチはやや制限されており、暗号化されたトークンには機能しませんでした。

NGINX Plus R25では、JWT検証プロセス中にトークンに対して追加のチェックを実行するネイティブな方法を提供することで、この制限に対処しています。auth_jwt_requireディレクティブは、JWT検証プロセスに、オプションでカスタマイズ可能なステップを追加します。このディレクティブはスペースで区切られた文字列のリストを受け付けますが、JWTの検証を成功させるためには、これらすべてが空や0(ゼロ)であってはなりません。これはJWTの検証プロセスに大きな柔軟性をもたらします。

JWT 標準はどのclaimが必須かを規定していないので、auth_jwt_require を使って各環境に適したclaimを列挙することができます。

以下の設定は、すべてのトークンに expsub の両方の claim が存在することを保証するものです。


mapブロックやNGINX Plusのキーバリューストアを使用してauth_jwt_requireディレクティブにブール値を渡すことで、より複雑なユースケースを構成することができます。また、NGINX JavaScriptモジュールを使用して、相互TLS(mTLS)におけるクライアント証明書紐付けたアクセストークン(RFC 8705で定義)などのリッチな認証ソリューションを実装することも可能です。

次の構成では、クライアント証明書認証(mTLS)とJWT検証の両方を実行します。14行目のauth_jwt_requireディレクティブは、$thumbprint_match変数を評価するよう呼び出し、それがゼロ以外の値を持つ場合にのみJWT検証を成功させます。この変数は、2行目で呼び出されたJavaScriptの関数を実行することで評価されます。


先ほどのスニペットの2行目で呼び出されたvalidate関数のコードは以下の通りです。


HTTPレスポンスコードのより詳細なレポーティング

監視と可視化は、アプリケーションのパフォーマンス、可用性、セキュリティの基礎となるものです。HTTPレスポンスコードは、アプリケーションの状態を把握するための最も重要な情報源の1つです。NGINX Plus APIは、NGINXとクライアント間、およびNGINXとアップストリームサーバ間で行われるやり取りの両方についてHTTPレスポンスコードを追跡し、その結果をNGINX Plusが提供するリアルタイムの監視ダッシュボードのタブで確認することが可能です。

NGINX Plus APIの以前のバージョンでは、HTTPレスポンスコードのカウントをクラス(2xx4xxなど)ごとに集計していました。現在では、コードを個別にカウントします(200404503など)。これにより、アプリケーションで何が起こっているかを正確に把握することができます。たとえば、認証に失敗したエラー(403)やコンテンツが見つからないエラー(404)の急増など、原因が大きく異なるエラーを区別することができます。メトリクス収集の構成については、『NGINX Plus Admin Guide』を参照してください。

NGINX Plus R25でリリースされたNGINX Plus APIの最新バージョン(バージョン7)では、応答オブジェクト内に”codes”オブジェクトが追加され、個々のHTTP応答コードのカウント数を確認することが可能になっています。集計されたレスポンスは引き続き利用可能で、codesオブジェクトを含まない旧バージョンのNGINX Plus APIもNGINX Plus R25で使用することができます。以下は、新しいメトリックの例です。

$ curl -s http://localhost:8080/api/7/http/server_zones/www.example.com | jq
{
  "processing": 31,
  "requests": 63192,
  "responses": {
    "1xx": 0,
    "2xx": 54368,
    "3xx": 8454,
    "4xx": 330,
    "5xx": 9,
    "codes": {
      "200": 54368,
      "302": 8454,
      "401": 30,
      "404": 200,
      "429": 100,
      "503": 9
    },
    "total": 63161
  },
  "discarded": 0,
  "received": 693436,
  "sent": 13843478
}

起動不良を防ぐために十分なメモリを確保する

重要:NGINX Plusがリバースプロキシまたはロードバランサーとして構成されている場合、個々のコードをカウントすると、各アップストリームグループの共有メモリゾーンのメモリ使用量が増加します。アップストリームグループに20以上のピアが存在する場合、zoneディレクティブで設定したメモリサイズを増やす必要がある場合があります。

NGINX Plus R25 は、アップストリームゾーンがプロビジョニング不足の場合、起動せず、アップグレードが失敗する場合があります。

以下は、アップストリームグループの共有メモリゾーンの設定です。


NGINX Plus R25 にアップグレードする前に、既存のアップストリームゾーンのメモリ使用量を確認することが重要です。これを行うには、これらの方法のいずれかを使用する前に、NGINX Plus APIが有効になっていることを確認します。

  • ライブ・アクティビティ・モニタリング・ダッシュボードのHTTP Upstreams タブを確認します。この例では demo.nginx.com の利用率が 54% となっています。

  • 以下のコマンドを実行し、ホストから直接NGINX Plus APIを使用します。まず

    • 必要に応じて jq ユーティリティをインストールします。
    • API 変数をapiディレクティブが有効な場所に設定します。
    $ API=http://localhost:8080/api; for i in `curl -s $API/1/http/upstreams | jq -r '.[].zone | @uri'`; do echo -n $i; curl -s $API/1/slabs/$i | jq -r '.pages | 100*(.used / (.used + .free)) | " \(round)% used"'; done

現在の使用率が40%を超えている場合(スクリーンショットのように)、zoneディレクティブの2つ目のパラメータ(サイズ)を少なくとも2.5倍にしてください。例えば、上記の設定スニペットでは、64k160kに増やすことをお勧めします。

プロキシのための動的SSL/TLSクライアント証明書ロード

相互TLS (mTLS) は、クライアントとサーバの両方の身元を確認する、一般的な認証方法です。NGINX Plusでは、アップストリームグループのサーバを動的かつ変数で定義することができます。つまり、NGINX Plusがこれらのアップストリームサーバに対して自身を検証するために使用するTLS証明書を動的に選択できるようにする必要があることを意味します。

NGINX Plus R25では、mTLSに使用される設定ディレクティブをバックエンドサーバに拡張し、証明書を表す変数を受け取れるようにしました。この変数は、以下のいずれかを参照することができます。

  • ディスク上のファイル
  • PEM形式の生データ。先頭に”data:”を付与し、パラメータを指定します。

これにより、NGINX Plusは証明書とプライベートキーを動的に選択できるようになり、常に変更される可能性のある最新のアプリケーション環境に役立ちます。NGINX Plusのキーバリューストアに証明書とプライベートキーを格納することができ、プライベートキーがディスク上ではなくメモリに格納されるため、セキュリティが強化されます。もう1つの使用例は、APIコールを使用してキーバリューストアの証明書を更新する、自動化された証明書のローテーションです。

以下の構成では、NGINX Plusはホスト名に基づいて異なるアップストリームグループにリクエストをルーティングします。プロキシ接続はmTLSを使用して行われ、各アップストリームに適したクライアント証明書が動的に選択されます。


以下のディレクティブは、上流サーバとのmTLSのための動的な証明書のロードをサポートします。

HTTPリクエスト処理におけるセキュリティ強化

NGINXの哲学の中核となる考え方の1つは、特にセキュリティに関する継続的な改善です。セキュリティ研究者とのコラボレーション、F5の業界をリードするセキュリティ技術の製品への統合、社内での開発努力など、利用可能なすべてのリソースを活用しています。

最後の例として、NGINX Plus R25はHTTPリクエストに対していくつかの追加チェックを行い、リクエストスマグリングなどの潜在的な攻撃からアプリケーションを保護します。これらの条件ではエラーが返されます。

  • HTTP/1.0 リクエストに Transfer-Encoding ヘッダが含まれている。
  • Transfer-Encoding ヘッダと Content-Length ヘッダが共に存在する。
  • リクエスト行またはヘッダ名に空白または制御文字がある場合
  • Host ヘッダに空白文字または制御文字が含まれている
  • CONNECT メソッドが使用されている

また、プロキシされるURIにおいて、以下の文字が常にエスケープされるようになりました:", <, >, \, ^, `, {, |, }.

なお、これらの変更は事前予防的なセキュリティ強化であり、既知の脆弱性に対応するものではありません。

TCP/UDP アプリケーションの再読み込み時の必須ヘルスチェックのステータスの永続化

NGINX Plusは、必須ヘルスチェックを使用して、アップストリームグループに追加された新しいサーバに対し、クライアントのリクエストがプロキシされる前にテストし、健全であることを確認します。NGINX Plus R23 およびそれ以前のバージョンでは、設定の再読み込み前後の状態にかかわらずアップストリームサーバが利用不可の状態であると見なされました。その結果、NGINX Plus は最初のヘルスチェックに合格するまで、サーバにリクエストを送信しませんでした。

NGINX Plus R24 では、HTTP アプリケーション向けに、リロード後の必須ヘルスチェックのステータスをオプションで持続させることができるようになりました。リロード前の最後の必須ヘルスチェックが成功した場合、NGINX Plusはリロード後の必須ヘルスチェックが成功するのを待つ必要がなく、すぐにサーバにリクエストを送信することができます。

NGINX Plus R25では、この機能をTCP/UDPアプリケーション(streamコンテキスト内)にも拡張しています。HTTPに関しては、mandatoryパラメータと一緒に persistentパラメータをhealth_checkディレクティブに追加してください。


NGINX JavaScriptモジュールの機能強化

NGINX JavaScriptモジュール(njs)がバージョン0.6.2にアップデートされ、いくつかのバグフィックスと、JavaScript ES6との互換性を強化する機能拡張が行われました。

let および const キーワードによる変数宣言

NGINX JavaScriptは、letおよびconstキーワードを用いたスコープ付き変数の宣言をサポートするようになりました。NGINX Plusおよびnjsの以前のバージョンでは、変数の宣言および代入にvarキーワードのみをサポートしていました。これは、異なるプロジェクト、プログラミング言語、およびエンジニアリングチームが共有コードベースやライブラリで共同作業する際にしばしば発生する複雑さに対処するために必要な、特定のblockステートメントのスコープに限定された変数を提供するものではありません。

JavaScript ES6 では、スコープ付き変数を定義するために let キーワードと const キーワードが用意されています。

  • let 変数は、blockステートメントまたはそれを使用する式のスコープに制限されます。これに対して、var キーワードは、ブロックスコープに関係なく、グローバルに、あるいは関数全体に局所的に変数を宣言します。
  • const 変数は、 let キーワードで宣言された変数と同様に、ブロックスコープで定義されます。定数の値は再割り当てによって変更することはできませんし、再宣言することもできません。

すべての Promise コンストラクタのメソッドをサポート

Promise.all()Promise.allSettled()Promise.any()、および Promise.race() のコンストラクタメソッドを追加し、njs は JavaScript ES6 標準で定義されているすべてのコンストラクタメソッドをサポートするようになりました。

NGINX Plusのアップグレード・トライアル

NGINX Plusを実行している場合、できるだけ早くNGINX Plus R25にアップグレードすることを強くお勧めします。必要となる追加修正と改善点を取得してください。サポートチケットを発行する必要がある場合、NGINXが支援することが可能です。

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

Hero image
NGINXクックブック 設定レシピ集(日本語版)

待望の【O'Reilly】NGINX Cookbook日本語版がついに完成!NGINXクックブックは、NGINXを最大限に活用する方法を解説しています。



著者について

Zach Westall

Product Marketing Manager

About F5 NGINX

F5 NGINXについて
F5, Inc.は、人気のオープンソースプロジェクト「NGINX」を支援しています。NGINXはモダンアプリケーションを開発・構築するためのテクノロジースイートを提供しています。NGINXとF5製品との併用で、コードからユーザーまでの広範なアプリケーション領域をサポートし、マルチクラウドアプリケーションサービスとしてNetOpsとDevOps間の課題を解決します。

詳しくはnginx.co.jpをご覧ください。Twitterで@nginxをフォローして会話に参加することもできます。