NGINX Plus R26リリースのお知らせ

NGINX | 2022年2月15日

NGINX Plus Release 26(R26)の提供開始をお知らせします。NGINX Open SourceをベースとするNGINX Plusは、Webサーバー、ロードバランサー、リバースプロキシ、コンテンツキャッシュ、APIゲートウェイの機能を1つに統合した唯一のソフトウェアです。

NGINX Plus R26の新機能および強化された機能は次のとおりです。

  • JSON Web Key SetのキャッシュによるJWT検証の高速化 – 過去数回のリリースで追加してきたJSON Web Token(JWT)サポートの一連の機能強化を継続し、JSON Web Key Set(JWKS)のインメモリキャッシュを導入しました。これにより、JWT検証のオーバーヘッドが大幅に削減されます。
  • TLSハンドシェイクの強化 – クライアントがALPNを介して、確立しようとしているセッションのNGINX構成コンテキストと一致しない通信プロトコルを提案した場合、NGINX PlusはTLSハンドシェイクを拒否します(たとえば、http{}コンテキストの仮想サーバーにIMAPメールプロトコルを提案した場合)。
  • NGINX JavaScriptモジュールの機能強化 – asyncおよびawaitキーワードとPromiseオブジェクトを使用する非同期関数がサポートされるようになりました。また、乱数の生成やCookieの暗号化などの暗号処理に対応するWebCrypto APIを実装しました。

このリリースではさらに、IBM System Z(s390x)アーキテクチャのサポート、TCP接続の各方向を個別に切断する機能、Perl Compatible Regular Expression(PCRE)ライブラリのバージョン 2のサポートが追加されています。

動作に関する重要な変更

NGINX JavaScript Moduleでのサポート終了:js_include

リリース時に発表したとおり、NGINX Plus R23では、NGINX JavaScriptモジュールのバージョン0.4.0で、js_importディレクティブがjs_includeディレクティブに置き換わりました。js_includeディレクティブはその時点で非推奨となり、本リリース以降はサポートされません。

NGINX Plus R26にアップグレードする前に、NGINX構成ファイル内の「js_include」を「js_import」に置き換え、NGINX構成で参照される関数について、JavaScriptファイルに「export」ステートメントを追加します。次の手順に従ってください。

  1. NGINX構成ファイルを編集します。たとえば、次のように変更します。
js_set $foo myFunction;
  1. 変更後:
js_set $foo module_name.myFunction;
  • Replace js_includeをjs_importに置き換え、暗黙的に設定されるmodule_name(ディレクティブに指定するJavaScriptファイル名から​.js拡張子を除いたもの)を控えておきます。
  • JavaScript関数を参照する各ディレクティブでは、関数名の先頭にmodule_nameを付けます。これらのディレクティブでは、関数名が第1パラメーターです。ただし、js_set[HTTP][Stream]ディレクティブでは第2パラメーターです。
  1. NGINX設定ファイルで参照される関数を定義しているJavaScript(module_name.js)ファイルを編集します。参照される関数名を指定して、次のようなexport文を各ファイルに追加します。
export default { myFunction, otherFunction }
  1. The exportステートメントは、.jsファイル内のどこにでも記述できますが、慣例として関数の直前またはファイルの末尾に配置します。

Cookie-Flagモジュールは廃止されました

サードパーティ製のCookie‑FlagモジュールはNGINX Plus R23で非推奨となり、当時の発表のとおり、このリリース以降、NGINXモジュールリポジトリでは提供されなくなりました。

NGINX Plus R26にアップグレードする前に、NGINXの設定を編集し、set_cookie_flagディレクティブ(非推奨のモジュールで定義)を組み込みのproxy_cookie_flagsディレクティブに置き換えてください。

TLSネゴシエーションでNPNプロトコルのサポートを終了

NGINXがTLSおよびHTTP/2接続を確立する方法が更新されました。NGINXとクライアント(通常はブラウザー)間のTLSハンドシェイクでは、ハンドシェイクによって確立されるセッションで使用する通信プロトコルをネゴシエートします(多くの場合、このネゴシエーションによりセッションがHTTP 1.xからHTTP/2にアップグレードされます)。この目的で最初に使用されたのは、TLSのNext Protocol Negotiation(NPN)拡張機能でした。しかし、現在NPNは廃止されたものと見なされており、RFC 7301として公開されているApplication-Layer Protocol Negotiation(ALPN)拡張機能に置き換えられています。

NGINX Plus R26ではNPNがサポートされなくなったため、クライアントはALPNのみを使用する必要があります。

さらに、ALPN実装の機能を拡張し、堅牢性を強化しました。詳しくは「TLSハンドシェイクの堅牢化」をご覧ください。

旧NGINX Plusソフトウェアリポジトリの更新終了

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

NGINX Plusをインストールまたはアップグレードすると、オペレーティングシステムのパッケージマネージャー(apt、yum、または同等のもの)にNGINX Plusのソフトウェアリポジトリが設定されます。

旧リポジトリ「plus-pkgs.nginx.com」を使用するよう構成された既存のシステム(NGINX Plus R23以前を実行しているシステム)をNGINX Plus R26にアップグレードする場合は、パッケージマネージャーの参照先を新しいリポジトリ「pkgs.nginx.com/plus」に更新する必要があります。手順については、F5 Knowledge Baseを参照してください。

NGINX Plus R26を新規インストールする場合は、『Installing NGINX Plus』について『NGINX Plus Admin Guide』を参照してください。

NGINX Plus R26は旧リポジトリでは利用できません。旧リポジトリは今後更新されません。

NGINX Plus APIのOpenAPI仕様へのアクセス方法の変更

NGINX Plusソフトウェアパッケージには、NGINX Plus API用のYAML形式の「OpenAPI仕様」および「Swagger UI」が含まれなくなりました。これらは「NGINX Plus管理ガイド」からアクセスできるようになりました。

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

新たにサポートされるオペレーティングシステムとアーキテクチャ:

削除された旧バージョンのオペレーティングシステム:

  • Alpine Linux 3.11(サポート対象の最も古いバージョンは3.12)

非推奨となり、NGINX Plus R27で削除される予定の旧バージョンのオペレーティングシステムおよびアーキテクチャ:

  • Power8アーキテクチャ(ppc64le)
  • CentOS 8.1+
  • Alpine Linux 3.12

新機能の詳細

JSON Web Key SetのキャッシュによるJWT検証の高速化

JSON Web Tokenを検証する際、NGINXはJSON Web Key Set(JWKS)を使用して、トークンの署名を検証するか、トークンを復号します。JWKSは、設定ファイルに保存することも、HTTPリクエストを介して外部サービスから取得することもできます。また、JWKSをメモリにキャッシュすると、次のような利点があります。

  • CPU使用率の大幅な削減
  • リクエストレイテンシーの短縮
  • キャッシュ処理の一環としてJWKSキーをJSONから暗号処理に最適化されたバイナリ形式に変換することによる、JWT検証の効率化

JWKSをメモリにキャッシュするには、新しい「auth_jwt_key_cache」ディレクティブを追加し、各キーセットの有効期限(この例では3時間)を指定します。

コード例を読み込み中…

外部サーバーからJWKを取得する場合は、標準のコンテンツキャッシュを設定し、proxy_cache_use_staleディレクティブを追加することも推奨します。これにより、期限切れのJWKSをバックグラウンドで更新している間も、NGINX PlusはそのJWKSを引き続き提供します。

コード例を読み込み中…

JWKSキャッシュに加えてコンテンツキャッシュを使用するメリットは、次の2つです。

  • レジリエンス – JWKSは、有効期限が切れた後でもキャッシュから取得できます。これにより、JWKSプロバイダーが一時的に利用できない場合のレジリエンスが向上しますが、その一方でセキュリティリスクが高まります。
  • 認可サーバーへの影響 – キャッシュされたJWKSの有効期限が切れた場合、JWKSキャッシュを単独で使用しているか、コンテンツキャッシュと組み合わせて使用しているかによって、認可サーバーへの影響が異なります:
    • JWKSキャッシュのみを使用する場合、期限切れのJWKSの新しいバージョンがキャッシュに再格納されるまで、受信したすべての認可リクエストが認可サーバーに転送されます。認可サーバーの応答が遅いと、JWKSを取得するためのHTTPリクエストが繰り返し送信され、急増する可能性があります。この追加負荷によって認可サービスが処理しきれなくなり、問題が悪化するおそれがあります。
    • 期限切れのJWKSを提供するようにコンテンツキャッシュを有効にすると、JWKSに対するリクエストは1件だけ認証サーバーに転送されます。それ以降のリクエストはキューに格納され、コンテンツキャッシュへのデータ格納後にNGINXが処理します。これにより、認証サービスへの負荷が軽減され、リソース消費量も削減されます。

TLSハンドシェイクの強化

TLSを標的とする攻撃(例:ALPACA)が増加しています。エクスプロイトに対するプロアクティブな防御への継続的な取り組みの一環として、NGINXによるTLS接続の処理を強化しました。

Application-Layer Protocol Negotiation(ALPN)は、TLSハンドシェイクのオプション拡張です。クライアントとサーバーはTLSハンドシェイク時に、ハンドシェイクによって確立される暗号化セッションで使用するレイヤー7プロトコルを選択するためにALPNを使用します。ALPNの最も一般的なユースケースは、ブラウザとWebサーバーまたはアプリケーションサーバー間のセッションをHTTP/1.xからHTTP/2へアップグレードするためのネゴシエーションです。

NGINX Plusでは、クライアントがALPNを介して提示したプロトコルが、確立中のセッションのNGINX構成コンテキストと一致しない場合、TLSハンドシェイクを拒否するようになりました。たとえば、http{}コンテキストで定義された仮想サーバーにはHTTP用のALPNプロトコルIDが必要ですが、mail{}コンテキストの仮想サーバーにはSMTP、POP、またはIMAP用のプロトコルIDが必要です。

NGINX Plus R26では、ネゴシエートされたプロトコルを取得するための変数$ssl_alpn_protocol[HTTP][Stream]が導入されました。($ssl_preread_alpn_protocols変数は、stream{}コンテキストでNGINX Plus R15に導入されたもので、引き続きハンドシェイク中にクライアントが通知したすべてのプロトコルのリストを取得します。)

このスニペットでは、alpnログ形式を定義します。このログ形式では、$ssl_alpn_protocolを使用して、アクセスログエントリのalpn=フィールドにプロトコルを含めます。

コード例を読み込み中…

新しい「ssl_alpn」ディレクティブでは、stream{}コンテキストでNGINX Plusが受け入れるプロトコルを定義します。このディレクティブを省略すると、NGINX Plusはクライアントが提示するすべてのプロトコルを検討対象にできます。

コード例を読み込み中…

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

NGINX Plus R26には、NGINX JavaScriptモジュール(njs)のバージョン0.7.2が組み込まれており、次の2つの機能強化が含まれています。

注:このセクションでは、非同期処理および暗号処理に使用するJavaScriptの構文を理解していることを前提としています。コードスニペットの詳細な分析は、このブログでは扱いません。

[編集者 – このセクションで説明するユースケースは、NGINX JavaScriptモジュールの数多くのユースケースの一部にすぎません。完全な一覧については、「NGINX JavaScriptモジュールのユースケース」をご覧ください。]

非同期関数のサポートを強化

PHPなど、一般的に使用されている多くのスクリプト言語では、コマンドや関数は同期的に実行されます。つまり、スクリプトが関数を呼び出すと、その関数が結果を返すまでスクリプトは一時停止(実行を停止)します。

JavaScriptは非同期でも動作できます。関数が非同期で呼び出されると、スクリプトは関数から結果が返されるのを待たずに実行を続けます。

次のサンプルスクリプトをご覧ください。

コード例を読み込み中…

njsランタイムは、設定されたタイムアウトが経過するまで待機しないため、空のレスポンスが返されます(待機する場合、出力は「b,a」になります):

$ curl http://127.0.0.1/
$ 

意図した結果を得るには、非同期処理を正しく扱うことが極めて重要です。JavaScriptにはそのための方法がいくつかありますが、一般的なNGINXのユースケースでは、非同期関数をラップして、実行フローを同期的にすることが望ましい場合がよくあります。そこで役立つのが、Promiseオブジェクトと、asyncおよびawaitキーワードです。

ECMAScript 6(JavaScript向け言語仕様ECMA‑262の第6版)では、非同期関数の戻り値の型としてPromiseオブジェクトが定義されています。このオブジェクトは、次の3つの状態のいずれかになります。

  • 履行済み – 処理が正常に完了しました
  • rejected – 操作に失敗しました
  • pending – 初期状態(fulfilledでもrejectedでもない状態)

JavaScript関数をキーワード「async」で定義すると、関数の戻り値の型は「Promise」になります。njsで「Promise」オブジェクトを扱う関数を記述する際は、「async」キーワードと「await」キーワードが重要です。

次の例をご覧ください。

コード例を読み込み中…

The fs.readFile関数(12行目)はPromiseを返します。この関数はカスタムasync関数でラップされており、ファイル名がuser.textの場合にのみfs.readFile()が呼び出されます。awaitキーワードにより、ラップする関数はPromiseの完了を待ってからデータを返します。

Wrapping fs.readFile()を別の関数でラップすると、エラーを捕捉しやすくなります。async関数内で例外が発生すると、Promiseの状態はrejectedに設定されます。別の方法として、9行目を、拒否されたPromiseを返すステートメントに置き換えることもできます。

コード例を読み込み中…

また、Promiseオブジェクトを直接操作することもできます。次の例では、Promise.resolve関数がp1とp2のそれぞれについてPromiseを返します。Promise.all関数は、p1とp2の両方のPromiseが解決されるまで待ってから、結果を返します。

コード例を読み込み中…

これで、curlコマンドから期待どおりの出力が得られます(タイムアウト値が短いため、bが先に返される点に注意してください)。

$ curl http://127.0.0.1/b,a
$ 

WebCrypto APIによる新しい暗号化機能

NGINX JavaScriptでは、WebCrypto APIを介して強化された暗号化機能を利用できるようになりました。njsで一般的な暗号化のユースケースは次のとおりです。

  • セッションID用の安全な乱数の生成
  • メッセージ、データ、Cookieの暗号化と復号
  • 対称暗号アルゴリズムおよび非対称暗号アルゴリズムを使用したデジタル署名の作成または検証

このnjsコードは乱数を生成します:

コード例を読み込み中…

また、次のNGINX Plus構成でnjsコードを呼び出します。

コード例を読み込み中…

この関数は、次のような乱数を出力します。

$ curl 127.0.0.123225320050,3668407277,1101267190,2061939102,2687933029,2361833213,32543985,4162087386

WebCryptoのgetRandomValues関数は、安全な乱数やWebCrypto全般を使い始めるうえで最適な出発点です。実装は非常にシンプルで、Promiseを返すのではなく、結果を直接返します。

ただし、WebCryptoの暗号化関数のうち、より負荷の高いものは非同期で動作します。たとえば、ドキュメントには、сrypto.subtle.digest()について次のように記載されています。

指定されたデータのダイジェストを生成します。使用するダイジェストアルゴリズムの識別子と、ダイジェストを生成するデータを引数として受け取ります。ダイジェストによって解決されるPromiseを返します。

したがって、сrypto.subtle.digest()を直接呼び出した場合、async関数でラップしない限り、その結果が次のステップで利用可能になるとは限りません。そこで、関数が値を返す前にhash変数へ結果が格納されるよう、ここではasyncキーワードとawaitキーワードを使用した関数でラップします。

コード例を読み込み中…

このNGINX Plus構成の「js_set」ディレクティブは、「$hosthash」変数に、「setReturnValue」関数が返す値(「host_hash」関数でラップされたもの)を設定します。

コード例を読み込み中…

ホスト名「example.com」をハッシュ化する例を次に示します。

$ curl -H "Host: example.com" 127.0.0.1#
e8e624a82179b53b78364ae14d14d63dfeccd843b026bc8d959ffe0c39fc4ded1f4dcf4c8ebe871e657a12db6f11c3af87c9a1d4f2b096ba3deb56596f06b6f4

NGINX Plus R26のその他の機能強化

IBM Z(s390x)アーキテクチャのサポート

モダンアプリケーションがあらゆるデジタル環境へと広がる中、NGINXのような不可欠な基盤コンポーネントも、それに対応していくことが重要です。このため、CentOS 8.1以降、RHEL 8.1以降、Ubuntu 20.04を使用するIBM Z(s390x)アーキテクチャでNGINX Plusをサポートします。既存のメインフレーム資産でモダンアプリケーションをホストしたい組織は、ソフトウェアベースのWebサーバー、ロードバランサー、リバースプロキシ、コンテンツキャッシュ、APIゲートウェイとしてNGINXおよびNGINX Plusを導入できるようになりました。

StreamモジュールでのTCPハーフクローズのサポート

新しい「proxy_half_close」ディレクティブでは、TCP接続の各方向を個別に切断できるため、「stream{}」コンテキストで効率がさらに向上します。

PCRE2ライブラリのサポート

以前のバージョンのNGINX Plusでは、NGINXの設定で使用される正規表現を評価するために、Perl互換正規表現(PCRE)ライブラリ(バージョン 1)を使用しています。この主要なオープンソースプロジェクトは最近サポート終了となり、後継のPCRE2に置き換えられました。NGINX PlusはPCRE2を使用してビルドされていますが、基盤となるオペレーティングシステムで利用可能なバージョンを使用し、PCREとPCRE2のいずれでビルドされた動的モジュールもサポートします。設定を変更する必要はありません。

NGINX Plusへのアップグレードまたはお試し

NGINX Plusをご利用の場合は、できるだけ早くNGINX Plus R26へアップグレードすることを強く推奨します。追加の修正や改善も適用されるほか、サポートチケットを起票する際に、NGINXがより適切に支援できるようになります。

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


共有

著者について

Robert Haynes
Robert Haynesテクニカルマーケティングマネージャー

Robert Haynesのその他のブログ記事

関連するブログ記事

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
NGINX | 2024/01/18

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する

OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
NGINX | 2023/05/31

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正

Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
NGINX | 2023/02/09

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法

Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINX | 2022/05/24

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング

NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
NGINX | 2018/08/17

SELinuxでNGINXおよびNGINX Plusを使用する

Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。

NGINX PlusによるAWS Auto Scalingグループの負荷分散
NGINX | 2017/03/06

NGINX PlusによるAWS Auto Scalingグループの負荷分散

新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります