NGINX(エンジンエックス)|日本公式サイト

NGINXはF5ファミリーの一員となりました。新体制の詳細はこちらを御覧ください。

NGINX Plus 新バージョンR23の紹介

NGINX Plusの最新バージョン23(R23)がこの度リリースされました。NGINX Plusは、NGINXオープンソースに基づいており、ソフトウェアロードバランサー、リバースプロキシ、およびAPIゲートウェイを提供する唯一の製品です。

NGINX Plusの新バージョンR23の新機能は次のとおりです。

  • gRPC ヘルスチェック – gRPCサーバに対するアクティブヘルスチェックをサポート。gRPCのクライアントリクエストと別に、gRPCリクエスト処理可能かどうかをNGINXが動的にチェックすることで信頼性を大幅に向上することが可能です。
  • 非特権インストールのサポート – root権限のない(root)ユーザーがNGINX Plusをインストールしたり、アップグレードしたりできるようになりました。ゼロトラスト・セキュリティモデルへの傾向が強まっていることに対応しています。
  • OpenID Connect PKCEのサポート – OpenID Connect Authorization CodeフローにPKCE拡張機能を実装。PKCEはいくつかのタイプの攻撃を防ぎ、パブリッククライアントとの安全なOAuthにおけるコード交換を可能にします。

その他リリースとして、SSL/TLSのきめ細かな設定の強化があります。Cookieフラグを設定するためのネイティブメソッド、およびStreamモジュールでの変数設定が可能となりました。NGINX Plusのエコシステムへの更新は、NGINX JavaScriptモジュール用の新しいバッファーおよびクエリ文字列モジュール、Kerberos用の新しいSPNEGO動的モジュール、およびPrometheus-njs動的モジュールの機能強化が含まれます。

重要な動作変更

  • 非推奨モジュール – サードパーティのCookieフラグモジュールは非推奨になり、新しいproxy_cookie_flagsディレクティブに置き換えられました。proxy_cookie_flagsは現在非推奨であり、NGINX Plus R26で削除される予定です。詳細については、Cookieフラグを設定するためのネイティブメソッドを参照してください。
  • サポートされる新しいオペレーティングシステム:
    • Alpine 3.12 (x86_64, arm64)
    • Debian 10 (aarch64; x86_64 has been supported since NGINX Plus R17)
  • 削除された、または削除される予定の古いオペレーティングシステム:
    • Alpine 3.9 is no longer supported; oldest supported version is 3.10
    • CentOS/Oracle Linux/RHEL 6.5+ is no longer supported; oldest supported version is 7.4
    • Ubuntu 19.10 is no longer supported
    • Debian 9 will be removed in NGINX Plus R24

各新機能の詳細

gRPC ヘルスチェック

ロードバランサーとしてデプロイされたNGINX Plusは、アクティブヘルスチェックにより、バックエンド(アップストリーム)サーバーが正常に稼働しているかをモニターできます。 NGINX Plus R23はgRPCヘルスチェックプロトコルをサポートしており、バックエンドのgRPCサーバーが新しいリクエストを処理できるかどうかを正確にテストできます。特に動的、かつコンテナ化された環境で役立ちます。gRPCサービスの新しいインスタンスを起動するときは、サービスが「完全に稼働」したときにのみリクエストを送信することが重要です。これには、TCPポートのチェックや、HTTP URIの可用性を確認したりするよりも詳細なヘルスチェックが必要です。これは、サービス自体がリクエストを受信する準備ができているかどうかを示します。

gRPCヘルスチェックを実装したgRPCサービスの設定は、非常に簡単です。

upstream grpc_backend {
zone grpc_backend 64k;
server 10.0.0.1:50051;
server 10.0.0.2:50051;
}
server {
listen 443 ssl http2;
ssl_certificate ...;
ssl_certificate_key ...;
location / {
grpc_pass grpcs://grpc_backend; # Use grpc:// to proxy as plaintext
health_check mandatory type=grpc;
}
}

view raw
grpc_health.conf
hosted with ❤ by GitHub

この設定は、”grpc_backend”アップストリームグループへのすべてのリクエストの負荷を分散します。”health_check”ディレクティブには、各アップストリームサーバーのヘルスサービスの”Check”メソッドを呼び出す”type=grpc”パラメータが指定します。”SERVING”を応答するサービスを、正常と見なします。mandatoryパラメーターは、NGINX Plusが起動したとき、または新しいサーバーがアップストリームグループに導入されたときに、ヘルスチェックに合格するまでトラフィックが転送しないよう動作します(この指定がない場合、新しいサービスはデフォルトで正常であると見なされます)。

各アップストリームサーバーで複数のgRPCサービスが公開されている場合は、次の例のように、”grpc_service”パラメーターの値としてその名前を指定することで、公開されているサービスの中で最も重要なサービス(その他サービスと依存関係があったり、従属関係にあるサービス)を監視することができます。

health_check type=grpc grpc_service=MyStatus;

gRPCヘルスチェックプロトコルを実装していないgRPCサービスの場合は、少なくともアップストリームサーバーがgRPCリクエストに応答しているかどうかをテストすることができます。これは、Checkメソッドに応答してエラーステータスコードが送信されるためです。 “grpc_health.conf”の設定では、gRPCプロトコルを実装していないサービスがステータスコード”12 (UNIMPLEMENTED)”で応答することが想定されます。

また、gRPCサービスがバックエンドコードを変更せずに着信リクエストに応答できることも確認することができます。このアプローチを使用して、任意のgRPCサービスを監視することが可能です。

location / {
grpc_pass grpc://grpc_backend;
health_check type=grpc grpc_status=12; # 12=unimplemented
}

非特権インストールのサポート

以前のリリースでは、NGINX Plusは、特権ユーザーrootで実行される最小限のプロセスでのみ動作していました。たとえば、NGINX Plus管理者ガイドのインストール手順では、次のプロセスを生成されます。

$ ps auxf | grep nginx
root  ...  9068  888 ?  Ss 21:44  0:00 nginx: master process nginx
nginx ...  9712 3572 ?  S  21:44  0:00  \_ nginx: worker process

ここで示されているように、マスタープロセスはroot権限で実行されています。他のすべてのプロセス(ワーカーとキャッシュ管理)は、非特権ユーザーアカウントnginxを使用します。

機密データを扱う重要なシステムは、ユーザーrootを使用したくない場合があります。NGINX Plus R23では、非特権ユーザーとしてインストールし実行できるようになっています。特権ユーザー必要の無い下記OS用のNGINX Plusインストールスクリプト”ngxunprivinst.sh“をGitHubリポジトリにご用意しています。

  • Alpine Linux
  • Amazon Linux, Amazon Linux 2
  • CentOS, Red Hat Enterprise Linux
  • Debian, Ubuntu

注:root権限が必要です(ただし、非特権ユーザーアカウントでNGINX Plusをインストールすることはできます)。

インストールスクリプトを使用するには、次のコマンドを実行します。 (使用可能なすべての”ngxunprivinst.sh”コマンドを表示するには、コマンド名パラメーターを指定せずにスクリプトを実行するか、GitHubリポジトリでスクリプトのコードを参照してください。)

  1. スクリプトをダウンロードして、実行可能であることを確認します。

    $ chmod +x ngxunprivinst.sh
  2. NGINX Plus証明書とキー(nginx-repo.crtおよびnginx-repo.key)をローカルディレクトリにコピーします。”‑c”および”‑k”オプションは、それらを識別するためにすべての”ngxunprivinst.sh”コマンドに含まれています。
  3. NGINXPlusリポジトリで利用可能なNGINXPlusのバージョンを一覧表示します。

    $ ./ngxunprivinst.sh list -c nginx-repo.crt -k nginx-repo.key
    18-1
    18-2
    19-1
    20-1
    21-1
    22-1
    23-1
  4. 目的のパッケージをフェッチします(ここではNGINX Plus R23-1をフェッチしています)。 “‑p“オプションは、インストールディレクトリを指定します。

    $ ./ngxunprivinst.sh fetch -c nginx-repo.crt -k nginx-repo.key -p /home/nginxrun -v 23-1
  5. 必要なパッケージをインストールします(ここでは、NGINXPlusとNGINXJavaScriptモジュールnjsをインストールします)。

    $ ./ngxunprivinst.sh install -c nginx-repo.crt -k nginx-repo.key -p /home/nginxrun -v 23.1 nginx-plus-23-1.el8.ngx.x86_64.rpm nginx-plus-module-njs-23%2B0.4.6-1.el8.ngx.x86_64.rpm
  6. ‑p”オプションでパスを指定、”‑c”オプションで構成ファイル名を指定、”‑e”オプションでエラーログに名指定し、NGINXを起動します。

    $ /home/nginxrun/usr/sbin/nginx -p /home/nginxrun/etc/nginx -c nginx.conf -e /home/nginxrun/var/log/error.log


    警告メッセージを抑制するため”‑e”オプションを指定することも可能です。 NGINX Plusは、起動時に構成を読み取る前に、デフォルトのエラーログ/var/log/nginx/error.logに書き込みます。権限のないユーザーには、このファイルを作成または書き込む権限がないため、警告が表示されます。構成が読み取られると、error_logディレクティブは、非特権ユーザーが書き込むことができる場所にエラーログを設定します。

  7. (オプション)NGINX Plusがroot以外のユーザーとして実行されていることを確認するには、次のコマンドを実行します。

    $ ps auxf | grep nginx
    nginxrun ...  9068  888 ?  Ss 21:55 0:00 nginx: master process
    nginxrun ...  9712 3572 ?  S  21:55 0:00  \_ nginx: worker process

OpenID Connect PKCEサポート

Proof Key for Code Exchange(PKCE)は、OpenID Connect(OIDC)認証コードフローに最近追加された拡張機能であり、さまざまな種類の攻撃を防ぎ、パブリッククライアントとのOAuthのコード交換を保護します。 NGINX Plus R23では、拡張機能をサポートするためOpenID Connectリファレンス実装を更新しました。OAuth 2.1ではPKCEが必須になります。

具体的な変更は、”client_secret”をcode challengeの2つの新しい値と置き換えることです。

  • code_challenge
  • code_verifier

様々な攻撃に対処するために、特にモバイルデバイスや、トークンのチャレンジ(アクセス、ID、または更新トークンのいずれか)が次のように調整されました。

  1. NGINX Plusは”code_verifier”を生成(および記憶)します。
  2. NGINX Plusは、エンドユーザーをリダイレクトしてOIDC IDプロバイダー(IdP)のログインページにログインします。リクエストには、”code_challenge”と呼ばれる”code_verifier”のハッシュしたものが含まれています。
  3. .IdPはユーザーの”auth_code”をNGINX Plusに送信します。
  4. 共有された状態に基づいて、NGINX Plusは生成された”code_verifier”を見つけ、IdPのトークンエンドポイントからのトークンセットの認証コードを交換するリクエストを送信できます。

PKCEを追加される前は、NGINX Plusが固定のクライアントシークレットをIdPと共有するだけで十分でした。OIDCリファレンス実装の更新で、NGINX PlusはPKCEとクライアントシークレット手法の両方の認証コードフローを処理できるようになっています。

PKCEを使用して拡張された認証コードフローを有効にする構成例を次に示します。

map $host $oidc_pkce_enable {
www.example.com 1;
default 0;
}

view raw
oidc_pkce.conf
hosted with ❤ by GitHub

新しい”$oidc_pkce_enable”変数は、PKCEフローのスイッチとして機能します。特定のドメインに対して1に設定すると、PKCEフローが使用されます。 0(デフォルト)に設定すると、PKCE以外の認証コードフローが使用されます。

NGINX Plus R23で強化されたその他機能

SSL/TLS 接続設定の強化

LS v1.3は、サーバー間、およびサーバーとそのクライアント間のエンドツーエンド暗号化により、以前のTLSバージョンよりも強力なセキュリティを実現します。 NGINX Plus R23は、TLSv1.3をきめ細かく制御するためのOpenSSLの設定へ直接アクセスする方法を提供します。

SSL証明書とキーの指定をせずデフォルトHTTPSサーバを簡単に作成

以前のリリースでは、TLSで保護されたHTTPSトラフィックのデフォルトのサーバーブロックssl_certificateおよびssl_certificate_keyディレクティブを含める必要があり、「ダミー」の自己署名証明書とキーを作成する必要がありました。

ssl_reject_handshakeディレクティブは、次のサンプル構成のように、証明書とキーの要件を排除します。

server {
# Default server to catch all unconfigured HTTPS traffic
listen 443 default_server ssl;
ssl_reject_handshake on;
}

直接OpenSSLを設定する

NGINX Plus R23を使用すると、OpenSSL1.0.2以降でNGINXPlusがSSL / TLSを処理する方法をよりきめ細かく制御できます。

次のユースケースでは、新たなレベルの制御が可能になっています。

  • ChaCha暗号 – NGINX Plusは、クライアント(通常はモバイル)が優先リストの一番上にその暗号を指定した場合にChaCha20を使用します。 ChaCha20は、それをサポートするクライアントのパフォーマンスを明らかに向上します。

  • TLS v1.3の暗号リスト設定 – 以前のリリースでは、次の例のように、ssl_ciphersディレクティブを使用してNGINX Plusの優先SSL/TLS暗号のリストを設定していました。

    ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;

    view raw
    tls_ciphers.conf
    hosted with ❤ by GitHub

    ただし、TLS v1.3の暗号のOpenSSL実装は古いインターフェイスと互換性がないため、このディレクティブはTLS v1.3には適用されません。 TLS v1.3の暗号リストを設定するには、次の例のように新しいssl_conf_commandディレクティブを使用します。

    ssl_conf_command Ciphersuites TLS_CHACHA20_POLY1305_SHA256;

    view raw
    tls_ciphers.conf
    hosted with ❤ by GitHub

    TLSv1.2とv1.3の両方に暗号を設定するには、構成に両方のディレクティブを含めます。

    ssl_protocols TLSv1.2 TLSv1.3;
    # For TLS 1.2
    ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    # For TLS 1.3
    ssl_conf_command Ciphersuites TLS_CHACHA20_POLY1305_SHA256;

    view raw
    tls_ciphers.conf
    hosted with ❤ by GitHub

  • プロキシ接続アップグレード設定 – “ssl_conf_command”ディレクティブによって実装された暗号構成メカニズムに基づいて、NGINX Plus R23は、以下のプロトコルでプロキシされた接続の暗号スイートに対して同様の制御を提供します。

  • 次の例は、古いTLSバージョンを使用しているクライアントからの要求をTLSv1.3をサポートしているバックエンドサーバーに対しアップグレードしてTLSv1.3を使用するようにNGINX Plusを構成する方法を示しています。

    upstream my_backend {
    zone my_backend 64k;
    server 10.0.0.1:8443;
    }
    server {
    listen 443 ssl;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_certificate /etc/ssl/api.example.com.crt;
    ssl_certificate_key /etc/ssl/api.example.com.key;
    location / {
    proxy_pass https://my_backend;
    proxy_ssl_protocols TLSv1.3;
    proxy_ssl_conf_command Ciphersuites TLS_AES_256_GCM_SHA384;
    }
    }

    view raw
    tls_upgrade.conf
    hosted with ❤ by GitHub

CacheManagerの強化

NGINX Plusがキャッシュサーバとして構成されている場合、キャッシュマネージャーは最近アクセスされなかったキャッシュコンテンツを削除することにより、キャッシュ容量が”max_size“パラメータで設定された制限を超えないことを保証します。

NGINX Plus R23では、キャッシュマネージャーがキャッシュを格納するファイルシステム上の使用可能なディスク容量を監視し、使用可能なスペースがproxy_cache_pathディレクティブの新しいmin_freeパラメーターよりも小さい場合(空き容量が少なくなった場合)にコンテンツを削除することもできます。

つまり、キャッシュが他のプロセスと同じファイルシステムを共有している場合でも、NGINX Plusでは、キャッシュでディスクをいっぱいにしてしまうことを防ぐことができます。

proxy_cache_path /var/cache/nginx keys_zone=cache_zone:10m min_free=100M;
server {
#...
location / {
proxy_pass http://backend;
proxy_cache cache_zone;
proxy_cache_key $uri;
}
}

保護されていないCookieは、常に攻撃の的となるリスクを抱えています。 Mozilla Developer Network(MDN)で述べられているように、意図しないパーティやスクリプトがCookieにアクセスしないようにする方法のひとつは、”Set-Cookie”ヘッダーに”HttpOnly”や”Secure”などのフラグを設定することです。

以前のリリースでは、動的モジュールリポジトリで利用可能なサードパーティのCookieフラグモジュールに実装される形で”set_cookie_flag”ディレクティブを提供していました。 NGINX Plus R23では、”proxy_cookie_flags”ディレクティブが導入され、そのディレクティブとモジュールが置き換えられています。

非推奨のCookieFlagモジュールはNGINX Plus R26で削除されるため、設定内の”set_cookie_flag”ディレクティブを見つけて、できるだけ早く”proxy_cookie_flags”ディレクティブに置き換えることをお勧めします。

Cookie保護フラグを設定行っていないシンプルなバックエンドアプリケーションにプロキシするための設定例です。

view raw
cookie_flags.conf
hosted with ❤ by GitHub

この例では、”HttpOnly”、”Secure”、”SameSite”フラグを追加して、アップストリームサーバーによって作成されたappcookieセッションのCookieを保護します。これは、NGINX Plus管理ガイドで説明されているとおり、NGINX Plusをセッションパーシステンスのために使用します。

curl”コマンドまたはブラウザの開発者ツールを使用すると、appcookieに”HttpOnly”、”Secure”、および”SameSite”フラグが設定されていることがわかります。

< HTTP/1.1 200 OK
< Server: nginx/1.19.4
< Date: Thu, 08 Dec 2020 14:46:12 GMT
< Content-Type: application/octet-stream
< Content-Length: 9
< Connection: keep-alive
< Set-Cookie: appcookie=appserver1; Secure; HttpOnly; SameSite=Strict
< Content-Type: text/html

NGINX Plus R23では、この例のように、stickyディレクティブを使用して”SameSite”フラグをCookieに追加することもできます(”httponly”および”secure”パラメーターはNGINX Plus R6以降サポートされています)。

ストリームモジュールでの変数の設定

NGINX Plus R23は、TCP / UDP構成で変数を設定するためのsetディレクティブを導入し、HTTPトラフィック処理に一般的に使用される機能を拡張します。

これは、複数の変数から複雑な複合値を作成する例です。

set $src_tuple $remote_addr:$remote_port;

view raw
set_stream.conf
hosted with ❤ by GitHub

少し高度なユースケースとしては、”set”ディレクティブを使用して”key‑value store”を更新します。 DNS負荷分散のこの設定でのkey value storeは、各クライアントIPアドレスがDNS要求を行った時間を記録し、各レコードを24時間保持します。

upstream dns_backends {
zone dns_backends 64k;
server 10.0.0.1:53;
server 10.0.0.2:53;
}
keyval_zone zone=dns_timestamp:1M timeout=24h;
keyval $remote_addr $timestamp zone=dns_timestamp;
server {
listen 53; # tcp
listen 53 udp;
proxy_pass dns_backends;
set $timestamp $time_iso8601; # Update the dns_timestamp keyval
}

view raw
dns_lb.conf
hosted with ❤ by GitHub

次の例では、NGINX Plus APIを使用して、各クライアントが過去24時間に最新のDNS要求を行ったタイミングを知ることができます。

$ curl http://localhost:8080/api/6/stream/keyvals/dns_timestamp
{
  "172.17.0.1": "2020-12-08T15:51:28+00:00",
  "172.17.0.2": "2020-12-08T12:36:08+00:00",
  "172.17.0.7": "2020-12-08T15:15:42+00:00"
}

NGINX Plus R23 のその他新機能

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

NGINX JavaScriptモジュール(njs)が0.5.0に更新されました。このバージョンでは、Node.jsバッファモジュールに類似したバッファモジュールが導入されています。バッファオブジェクトを使用すると、文字列に依存する代わりに、バイナリデータを簡単に操作できます。

その他の注目すべき機能強化は、URLで渡されたキーと値のペアに簡単にアクセスできるクエリ文字列モジュールと、デバッグ用の行レベルのバックトレースサポートです。

動的モジュールの更新

Kerberos用の新しいSPNEGO動的モジュール

SPNEGO Kerberos認証のサポートが、NGINX Plus動的モジュールリポジトリで利用できるようになりました。インストール手順と詳細情報へのポインタについては、NGINX Plus管理ガイドを参照してください。

非推奨のCookieフラグモジュール

上記のCookieフラグを設定するためのネイティブメソッドで詳しく説明されているように、新しい”proxy_cookie_flags”ディレクティブは、サードパーティのCookieフラグモジュールに実装されている”set_cookie_flag”ディレクティブに置き換わるものです。このディレクティブは非推奨になり、NGINX PlusR26で削除される予定です。構成に”set_cookie_flag”ディレクティブが含まれている場合は、できるだけ早くそれを”proxy_cookie_flags”に置き換えてください。

Prometheus-njsモジュール更新

Prometheus njsモジュールは、追加メトリックを公開するようになりました。また、NGINX JavaScriptモジュール(njs)を使用するデプロイメントに対応するようにアップグレードされています。 Prometheus njsをバージョン1.3.1以降にアップグレードする場合、非推奨のnjs構成への参照を回避するために、NGINX設定ファイルを更新することが重要です。

  • js_include”ディレクティブは非推奨になり、”js_import”ディレクティブに置き換えられました
  • js_content”および”js_set”ディレクティブは、モジュール関数を参照できます

注目すべきバグ修正

応答が”proxy_buffer_size”ディレクティブの値よりも大きい場合に、変数が空でないことをテストするためにmatchブロックで”require”ディレクティブを使用したヘルスチェックが、異常なアップストリームサーバーを検出しなかった可能性があった動作を修正しました。

NGINX Plusのアップグレードまたはトライアル

NGINX Plusをすでにお使いの方は、できるだけ早くNGINX Plus R23にアップグレードすることをお勧めします。あわせて、いくつかの追加の修正や改善ポイントを入手することができます。これは、サポートチケットを発行する際に必要となります。

NGINX Plusをまだ試したことがない方は、セキュリティ、負荷分散、APIゲートウェイ機能として、または強化された監視および管理APIを備えた完全にサポートされたWebサーバーとしての機能をぜひ試してみてください。30日間無料のトライアル版をお試しいただけます。 NGINX Plusがアプリケーションの提供と拡張にどのように役立つかを実際に体験いただきご確認ください。

関連資料