ブログ | NGINX

NGINX オープンソースで再起動なしで SSL/TLS 証明書をローテーション

NGINX-F5 水平黒タイプ RGB の一部
マキシム・イヴァニツキー サムネイル
マキシム・イヴァニツキー
2023年9月26日公開

高性能 Web サーバーの世界では、軽量で効率的なアーキテクチャにより大量のトラフィックを処理できるため、 NGINX は人気のある選択肢です。 NGINX JavaScript モジュール (njs)の一部として共有辞書機能が導入されたことで、NGINX のパフォーマンス機能が次のレベルに到達しました。

このブログ記事では、njs 共有辞書の機能と利点について説明し、SSL/TLS 証明書をローテーションするときに再起動せずに NGINX Open Source を設定する方法を示します。

共有辞書の基本と利点

新しいjs_shared_dict_zoneディレクティブにより、NGINX Open Source ユーザーは共有メモリ ゾーンを有効にして、ワーカー プロセス間で効率的にデータを交換できるようになります。 これらの共有メモリ ゾーンはキーと値の辞書として機能し、リアルタイムでアクセスおよび変更できる動的な構成設定を保存します。

共有辞書の主な利点は次のとおりです。

  • 最小限のオーバーヘッドと使いやすさ - njs に直接組み込まれているため、直感的な API と簡単な実装により、プロビジョニングと利用が簡単です。 また、ワーカー プロセス間でデータを管理および共有するプロセスを簡素化するのにも役立ちます。
  • 軽量かつ効率的 -イベント駆動型の非ブロッキング I/O モデルを活用して、NGINX とシームレスに統合します。 このアプローチにより、メモリ使用量が削減され、同時実行性が向上し、NGINX は多数の同時接続を効率的に処理できるようになります。
  • スケーラビリティ -複数のワーカー プロセスにわたって水平にスケーリングする NGINX の機能を活用することで、複雑なプロセス間通信メカニズムを必要とせずに、それらのプロセス間でデータを共有および同期できます。 有効期間 (TTL) 設定を使用すると、非アクティブになった共有辞書エントリのレコードをゾーンから削除して管理できます。 evictパラメータは、新しいエントリ用のスペースを確保するために、最も古いキーと値のペアを削除します。

共有辞書による SSL ローテーション

共有辞書の最も影響力のある使用例の 1 つは、SSL/TLS ローテーションです。 js_shared_dict_zoneを使用する場合、SSL/TLS 証明書またはキーの更新時に NGINX を再起動する必要はありません。 さらに、NGINX 上の証明書を管理するための REST のような API も提供されます。

以下は、 js_setおよびssl_certificateディレクティブを使用して HTTPS サーバーを設定する NGINX 構成ファイルの例です。 JavaScript ハンドラーはjs_set を使用して、ファイルから SSL/TLS 証明書またはキーを読み取ります。

この構成スニペットは、共有辞書を使用して、証明書とキーを共有メモリにキャッシュとして保存します。 キーが存在しない場合は、ディスクから証明書またはキーを読み取り、キャッシュに格納します。

キャッシュをクリアする場所を公開することもできます。 ディスク上のファイルが更新されると (証明書やキーが更新されるなど)、共有辞書はディスクからの読み取りを強制します。 この調整により、NGINX プロセスを再起動せずに証明書/キーをローテーションできるようになります。

http { ... js_shared_dict_zone ゾーン = kv:1m;
server { … # 変数に njs 関数を設定します。 証明書/キーの値を返します js_set $dynamic_ssl_cert main.js_cert; js_set $dynamic_ssl_key main.js_key;
# 変数のデータを使用する ssl_certificate data:$dynamic_ssl_cert; ssl_certificate_key data:$dynamic_ssl_key;
# キャッシュをクリアする場所 location = /clear { js_content main.clear_cache; # allow 127.0.0.1; # deny all; }
...}

js_shared_dict_zoneを使用して SSL/TLS 証明書とキーをローテーションするための JavaScript 実装は次のとおりです。

function js_cert(r) { if (r.variables['ssl_server_name']) { return read_cert_or_key(r, '.cert.pem'); } else { return ''; } } function js_key(r) { if (r.variables['ssl_server_name']) { return read_cert_or_key(r, '.key.pem'); } else { return ''; } } /** * 共有メモリからキー/証明書の値を取得するか、ディスクにフォールバックします */ function read_cert_or_key(r, fileExtension) { let data = ''; let path = ''; const zone = 'kv'; let certName = r.variables.ssl_server_name; let prefix = '/etc/nginx/certs/'; path = prefix + certName + fileExtension; r.log('Resolving${path} '); const key = ['certs', path].join(':'); const cache = zone && ngx.shared && ngx.shared[zone];
if (cache) { data = cache.get(key) || ''; if (data) { r.log(`Read${key}キャッシュから`); データを返します; } } try { data = fs.readFileSync(path, 'utf8'); r.log('キャッシュから読み取り'); } catch (e) { data = ''; r.log(`ファイルからの読み取りエラー:${path} 。 エラー=${e} `); } if (cache && data) { try { cache.set(key, data); r.log('キャッシュに保持されました'); } catch (e) { const errMsg = `共有辞書ゾーンへの書き込みエラー:${zone} 。 エラー=${e} `; r.log(errMsg); } } データを返す }

/clearリクエストを送信すると、キャッシュは無効になり、NGINX は次の SSL/TLS ハンドシェイク時にディスクから SSL/TLS 証明書またはキーを読み込みます。 さらに、リクエストから SSL/TLS 証明書またはキーを取得し、キャッシュを永続化および更新するjs_content を実装することもできます。

この例の完全なコードは、njs GitHub リポジトリにあります。

今すぐ始めましょう

共有辞書機能は、アプリケーションのプログラミング性を高める強力なツールであり、合理化とスケーラビリティに大きな利点をもたらします。 js_shared_dict_zoneの機能を活用することで、新たな成長の機会を獲得し、増加するトラフィック需要を効率的に処理できるようになります。

js_shared_dict_zoneを使用して NGINX デプロイメントを強化する準備はできていますか? js_shared_dict_zoneを使用して NGINX デプロイメントをアップグレードすると、新しいユースケースが利用可能になり、この機能の詳細についてはドキュメントを参照してください。 さらに、最近導入されたnjs-acme プロジェクトで共有辞書関数の完全な例を確認できます。これにより、njs モジュール ランタイムが ACME プロバイダーと連携できるようになります。

NGINX オープンソースの使用開始に興味があり、質問がある場合は、 NGINX コミュニティ Slack に参加して、自己紹介をして、NGINX ユーザーのコミュニティについて知りましょう。


「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"