ブログ | NGINX

NGINX による SSL 秘密鍵の安全な配布

NGINX-F5 水平黒タイプ RGB の一部
オーウェン・ギャレット サムネイル
オーウェン・ギャレット
2019年4月2日公開

このブログ記事では、SSL 暗号化された Web サイトをホストするときに NGINX が使用する SSL 秘密鍵を安全に配布するいくつかの方法について説明します。 それは次のように説明しています:

多くの展開では、標準的なアプローチで十分です。 この投稿で説明する 2 つのより洗練されたアプローチは、攻撃者が SSL 秘密鍵を取得できる他の方法をブロックします。 後続の投稿では、さらにいくつかのテクニックについても見ていきます。

  • HashiCorp Vaultなどのサードパーティのシークレットストアを使用してパスワードを安全に配布する
  • VaultからNGINX Plusのキーバリューストアへの証明書のプロビジョニングを自動化し、秘密鍵がディスクに保存されないようにする

この記事で紹介したアプローチは、独自のキーを管理し、独自の安全なキー配布戦略を作成する必要があるユーザーに適用されます。 Kubernetesなどのシークレット ストアとすでに統合されている環境で NGINX を実行しているユーザーには、これらは必要ありません。

この投稿は、NGINX Open Source と NGINX Plus の両方に適用されます。 読みやすくするために、全体を通じてNGINXを参照します。

編集者 – この投稿は、NGINX で SSL 秘密鍵を保護する方法に関するシリーズの最初の投稿です。シリーズの他の投稿もご覧ください。

 

SSL 秘密キーを保護する理由は何ですか?

SSL/TLS は、ネットワーク トランザクションの認証、暗号化、整合性の検証に使用されます。 ウェブサイトは、証明機関 (CA) によって署名された公開証明書を使用して自身を認証し、対応する秘密鍵(秘密に保持する必要がある) を使用して計算を実行することで、証明書を所有していることを証明します。

秘密鍵が侵害された場合(別のエンティティに開示された場合)、主に 2 つのリスクがあります。

  • リスク1: なりすまし。 秘密鍵を持つ攻撃者は、ネットワーク トラフィックを傍受し、中間者(MITM) 攻撃を仕掛けることができます。 この攻撃は、クライアントや Web サイトに気付かれずに、すべてのトラフィックをキャプチャして復号化し、場合によっては変更することもあります。
  • リスク2: 復号化。 秘密鍵を持ち、ネットワーク トラフィックを記録した攻撃者は、ネットワーク トラフィックをオフラインで復号化できるようになります。 この攻撃は、 Perfect Forward Secrecy (PFS) 暗号を使用する接続に対しては使用できません。

秘密鍵が侵害された場合、唯一の手段は CA に連絡して証明書の失効を要求することです。その後は、クライアントに頼って失効ステータスを確認してもらいます。

さらに、有効期限が短い証明書を使用することをお勧めします (たとえば、 Let's Encrypt証明書は 90 日後に有効期限が切れます)。 証明書の有効期限が切れる直前に、新しい秘密キーを生成し、CA から新しい証明書を取得する必要があります。 これにより、秘密鍵が侵害された場合のリスクが軽減されます。

NGINX セキュリティ境界

NGINX の SSL 秘密鍵にアクセスできるのはどのユーザーとプロセスですか?

まず、NGINX を実行しているサーバーにルートアクセス権を取得したユーザーは、NGINX 自体が使用するすべてのリソースを読み取って使用できます。 たとえば、実行中のプロセスのメモリから SSL 秘密キーを抽出する方法が知られています。

したがって、秘密鍵がどのように保存および配布されたとしても、ホスト サーバーのルート権限を持つ攻撃者から秘密鍵を保護することはできません。

次に、NGINX 設定を変更してコミットできるユーザーは、内部サービスへのプロキシ アクセスを開いたり、認証手段をバイパスしたりなど、さまざまな方法でその権限を使用できます。 NGINX の設定を変更して、サーバーへのルートアクセス (または同等のアクセス) を取得することもできますが、 SELinuxAppArmorなどのツールを使用すると、その可能性を軽減できます。

したがって、通常、NGINX 構成を変更してコミットできる攻撃者から秘密鍵を保護することはできません。

幸いなことに、有能な組織であれば、攻撃者がルート権限を取得したり、NGINX 構成を変更したりすることを困難にする健全なセキュリティ プロセスを備えています。

ただし、権限の低い攻撃者が秘密鍵にアクセスできる方法は他に 2 つあります。

  • ユーザーには、NGINX 構成を表示する正当な理由がある場合や、構成データベースまたはバックアップへのアクセス権を取得する場合があります。 NGINX 秘密鍵は通常、構成に保存されます。
  • ユーザーは、ハイパーバイザーまたはシステム バックアップを介して、NGINX サーバーのファイルシステムにアクセスできる可能性があります。 秘密鍵マテリアルを含む、ファイルシステムに保存されているすべてのデータは、潜在的にアクセス可能です。

このドキュメントで説明するプロセスは、これら 2 つの攻撃方法を封じ込めます。

標準NGINX設定

まず、SSL/TLS を使用した一般的な NGINX 構成がどのようなものかを確認します。

server { listen 443 ssl; server_name a.dev0; ssl_certificate ssl/a.dev0.crt; ssl_certificate_key ssl/a.dev0.key; location / { return 200 "Hello from service A\n"; } }

SSL 公開証明書 ( a.dev0.crt ) と秘密鍵 ( a.dev0.key ) は、ファイルシステムの/etc/nginx/ssl/に保存されます。 秘密鍵は、通常はrootとして実行される NGINX マスター プロセスによってのみ読み取られるため、可能な限り厳しいアクセス権限を設定できます。

root@web1:/etc/nginx/ssl# ls -l a.dev0.key -r-------- 1 root root 1766 8月15日 16:32 a.dev0.key

秘密鍵は常に使用可能である必要があります。NGINX マスター プロセスは、NGINX ソフトウェアの起動時、構成の再読み込み時、または構文チェックの実行時 ( nginx -t ) に必ず秘密鍵を読み取ります。

SSL/TLS の設定の詳細については、 NGINX Plus 管理者ガイドを参照してください。

標準構成のセキュリティへの影響

前述のように、SSL 秘密キーは、NGINX ソフトウェアを実行している実行中のコンテナ、仮想マシン、またはサーバーへのルートアクセス権を取得した攻撃者によって読み取られる可能性があります。

SSL 秘密鍵の暗号化

NGINX は、AES256 などの安全なアルゴリズムを使用して暗号化された秘密鍵をサポートします。

root@web1:/etc/nginx/ssl# mv a.dev0.key a.dev0.key.plain root@web1:/etc/nginx/ssl# openssl rsa -aes256 -in a.dev0.key.plain -out a.dev0.key RSA キーの書き込み PEM パスフレーズを入力してください:安全なパスワード確認中 - PEM パスフレーズを入力してください:安全なパスワードをもう一度

その後、NGINX を起動するか、NGINX 設定を再読み込みまたはテストすると、NGINX は対話的に復号化パスワードを要求します。

root@web1:/etc/nginx# nginx -t PEM パスフレーズを入力:安全なパスワードnginx: 設定ファイル /etc/nginx/nginx.conf の構文は正常です nginx: 設定ファイル /etc/nginx/nginx.conf のテストが成功しました

SSL パスワード ファイルの使用

パスワードを対話的に入力するのは不便で自動化も困難ですが、 ssl_password_fileディレクティブで指定された別のファイルに保存されているパスワードのリストを使用するように NGINX を設定できます。 NGINX は秘密鍵を読み取る必要がある場合、ファイル内の各パスワードを順番に使用して鍵の復号化を試みます。 いずれのパスワードも有効でない場合、NGINX は起動を拒否します。

ssl_password_file /var/lib/nginx/ssl_passwords.txt;

ssl_password_file は構成とは別に配布され、 rootユーザーのみが読み取り可能である必要があります。 これは、信頼できるサーバーに配置される認証トークンと見なすことができます。 NGINX は、認証トークンを持つサーバー上で実行されている場合にのみ、秘密鍵を復号化できます。

暗号化されたキーを別のファイルに保存することによるセキュリティへの影響

この方法では、NGINX 構成のみを攻撃者にとって役に立たないものにすることで、攻撃対象領域を減らします。 攻撃者はssl_password_fileの内容も取得する必要があります。

攻撃者がssl_password_fileが保存されているファイルシステムへのルートアクセスを取得した場合 (たとえば、バックアップから、またはホスト システムを通じて)、そのファイルを読み取り、パスワードを使用して SSL 秘密キーを復号化できます。

ssl_password_file をRAM ディスクまたはtmpfsに保存することで、このリスクを軽減できます。 このストレージは、通常、外部の攻撃者によるアクセスが困難であり (たとえば、サーバーを再起動するとクリアされます)、システム バックアップから除外できます。 システムの起動時にパスワード ファイルが初期化されていることを確認する必要があります。

SSLパスワードリストをより安全に配布する

以下のプロセスでは、中央の配布ポイントから SSL パスワードのリストを配布するより安全な方法について説明します。

NGINX は SSL キーを復号化する必要があるときはいつでも、中央配布ポイントにクエリを実行し、パスワードをローカル ディスクに保存せずに使用します。 NGINX インスタンスは、中央パスワード サーバーで自身を認証するためにトークンを使用します。このトークンはいつでも取り消して、パスワードへのアクセスを遮断できます。

中央パスワード配布ポイントの作成

まず、パスワード配布ポイント (PDP) を作成します。 このシンプルな実装では、ユーザー名とパスワードで認証されたパスワード リストを配信するために HTTPS サービスを使用しています。

$ curl -u dev0:mypassword https://pdpserver.local/ssl_passwords.txtパスワード1 パスワード2 ...

必要に応じて、PDP で認証トークンを追加または削除することで、アクセスを有効化または取り消すことができます。 NGINX などの Web サーバーを使用してパスワード配布サーバーを実装し、適切な種類の認証トークンを使用できます。

次に、PDP からパスワードを取得するために NGINX を設定する必要があります。 まず、次の内容のconnector.shというシェル スクリプトを作成します。

#!/bin/sh
# 使用方法: connector.sh

CONNECTOR=$1
CREDS=$2
PDP_URL=$3

[ -e $CONNECTOR ] && /bin/rm -f $CONNECTOR

mkfifo $CONNECTOR; chmod 600 $CONNECTOR

while true; do
curl -s -u $CREDS -k $PDP_URL -o $CONNECTOR
done

スクリプトは、次のように呼び出されてバックグラウンド プロセスとして実行する必要があります。

root@web1:~# ./connector.sh /var/run/nginx/ssl_passwords \dev0:mypassword https://pdpserver.local/ssl_passwords.txt &

コネクタは指定されたローカル パス ( /var/run/nginx/ssl_passwords ) に接続され、 ssl_password_fileディレクティブを使用して NGINX がそのパスにアクセスするように構成します。

ssl_password_file /var/run/nginx/ssl_passwords;

コネクタ パスから読み取ってコネクタをテストします。

root@web1:~# cat /var/run/nginx/ssl_passwordsパスワード1 パスワード2 ...

NGINX がパスワードを読み取り、SSL キーを復号化できることを確認します。

root@web1:~# nginx -t nginx: 設定ファイル /etc/nginx/nginx.conf の構文は正常です nginx: 設定ファイル /etc/nginx/nginx.conf のテストは成功しました

集中型 PDP アプローチを使用すると、個々の秘密鍵やその他の機密データなど、NGINX が通常ディスクから読み取るリソースを安全に配布できます。

PDP のセキュリティへの影響

このソリューションには、SSL パスワードをディスクに保存する場合と比べていくつかの利点があります。

  • SSL パスワードはサーバーのファイルシステムに保存されないため、ファイルシステムにアクセスできる攻撃者が直接アクセスすることはできません。
  • パスワードは中央アクセス ポイントから配布されるため、監視と監査の実行が容易になります。
  • 個々のサーバーのアクセスを集中的に制御できます。 たとえば、サーバーが廃止されると、そのアクセス トークンは取り消されます。

ファイルシステムにアクセスできるユーザーは、PDP へのアクセスに使用される資格情報を抽出できる可能性があることに注意してください。 これらの資格情報は、不要になったときに取り消すことが重要です。

まとめ

SSL 秘密鍵の漏洩を防ぐ方法は数多くあり、セキュリティと複雑さのレベルが高まっています。

  • 大多数の組織では、権限のないユーザーがルートアクセスを取得したり、NGINX 構成を確認したりできないように、NGINX を実行している環境へのアクセスを制限するだけで十分です。
  • 環境によっては、NGINX 構成へのアクセスを完全に制限できない場合があるため、SSL パスワード ファイルを使用できます。
  • 限られたケースでは、組織はキーとパスワードがディスクに保存されないようにすることを望む場合があります。 パスワード配布ポイントのプロセスは、このソリューションの概念実証を示しています。

このシリーズの他の投稿では、SSL キーを保護するために実行できる追加の手順について説明します。

NGINX Plus をぜひお試しください。今すぐ30 日間の無料トライアルを開始するか、弊社にお問い合わせの上、ユースケースについてご相談ください


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