https://12factor.net/config のdevopsガイドラインでは、Webサイトのシークレット(データベースパスワード、APIキーなど)を環境変数に入れることをお勧めしています。バージョン管理で無視されたテキストファイル(JSON、XML、YAML、INIなど)を使用する代わりに、どのような利点がありますか?
.bash_profileおよびwebserver構成で環境変数を処理するよりも、シークレットを含む構成ファイルをコピーする方がはるかに簡単です。私は何かを逃していますか?
著者は彼らの推論を挙げていますが、それは少しばらばらです。彼らの主な議論は、誤って設定ファイルをチェックインするのは簡単であり、設定ファイルはさまざまなフォーマットを持ち、システム内に散在している可能性があることです(認証トークンや資格情報など、セキュリティ関連の設定のせいぜい3つは平凡な引数です)。
私の経験を踏まえると、基本的に次の3つのオプションがあり、関連する長所と短所があります。
このアプローチをとるときは、理想的にはそれらをリポジトリ自体から分離し、アプリがコンテンツを格納する領域の外にあることを確認する必要があります。
通常、これは、起動スクリプトから環境変数と値のリストを取得することで行われますが、場合によっては、プログラム名の前にコマンドラインでそれらを記述するだけです。
/proc
のhidepid
マウントオプション)、デフォルトでは有効になっておらず、プロセスを所有するユーザーからの攻撃を防ぎません。真剣に、絶対にこれを避けてください、それは安全ではありません、そしてそれは維持するためにロバの苦痛です。
環境変数は、Webサーバーのすべての子プロセスによって継承されます。これは、サーバーに接続するすべてのセッションと、それらによって生成されるすべてのプログラムです。秘密はそれらのプロセスすべてに自動的に明らかにされます。
シークレットをテキストファイルに保存する場合、それらはサーバープロセスで読み取り可能である必要があるため、すべての子プロセスでも読み取り可能である必要があります。しかし、少なくともプログラムはそれらを探し出さなければなりません。自動的には提供されません。また、いくつかの子プロセスを異なるアカウントで実行し、シークレットをそれらのアカウントのみが読み取り可能にすることもできます。たとえば、 suEXEC はApacheでこれを行います。
環境変数やファイルに関してセキュリティ関連のトレードオフがいくつかあるとしても、セキュリティがこの推奨事項の主な原動力ではなかったと思います。 12factor.netの作者がHeroku PaaSの開発者でもある(またはそうだったのか?)ことを思い出してください。誰もが環境変数を使用できるようにすると、おそらく開発がかなり簡単になります。構成ファイルの形式と場所は非常に多様であり、それらすべてをサポートすることは困難でした。環境変数は比較すると簡単です。
行われた会話の一部を推測するのに、それほど想像力は必要ありません。
開発者A:「ああ、この秘密の構成ファイルのUIは乱雑です!json、xml、csvを切り替えるドロップダウンが本当に必要ですか?」
開発者B:「ああ、誰もがアプリの設定に環境変数を使用していたら、人生はとてもすばらしいでしょう。」
開発者A:「実際には、そのために考えられるセキュリティ関連の理由がいくつかあります。環境変数が誤ってソース管理にチェックインされることはないでしょう。」
開発者B:「デーモンを起動するスクリプトまたは設定ファイルで環境変数を設定しないでください。」
開発者A:「Herokuにはありません。UIに入力するようにします。」
開発者B:「ああ、12factor.netのドメイン名に関する警告が出たところだ」1
1:ソース:構成。
構成ファイルの代わりに環境変数を使用する理由はいくつかありますが、見落とされる最も一般的な理由の2つは、out-of-band configurationおよびサーバー、アプリケーション、または組織の役割間の強化された分離。考えられるすべての理由の完全なリストを提示するのではなく、私はこれらの2つのトピックのみを回答で取り上げ、それらのセキュリティへの影響について軽く触れます。
すべてのシークレットを構成ファイルに保存する場合は、それらのシークレットを各サーバーに配布する必要があります。つまり、コードと一緒にシークレットをリビジョン管理にチェックインするか、シークレット用に完全に別個のリポジトリまたは配布メカニズムを用意する必要があります。
シークレットを暗号化しても、この問題の解決には役立ちません。問題を1つの削除にプッシュするだけです。これで、キーの管理と配布についても心配する必要があります。
つまり、環境変数は、開発と運用を分離したい場合に、サーバーごとまたはアプリケーションごとのデータをソースコードから移動するためのアプローチです。ソースコードを公開している場合、これは特に重要です!
シークレットを保持する構成ファイルがあることは確かですが、シークレットをソースコードに格納すると、特異性の問題が発生します。シークレットのセットごとに個別のブランチまたはリポジトリがありますか?適切なシークレットのセットが適切なサーバーに確実に届くようにするにはどうすればよいですか?または、どこでも同じ(またはすべてが1つのファイルにある場合はどこでも読み取り可能)の「シークレット」を使用してセキュリティを低下させ、1つのシステムのセキュリティ制御が失敗した場合に大きなリスクを構成しますか?
サーバーごと、またはアプリケーションごとに固有のシークレットを設定する場合、環境変数を使用すると、多数のファイルを管理する必要があるという問題がなくなります。新しいサーバー、アプリケーション、またはロールを追加する場合、新しいファイルを作成したり、古いファイルを更新したりする必要はありません。問題のシステムの環境を更新するだけです。
カーネル/メモリ/ファイルのセキュリティを徹底的に調査することはこの回答の範囲外ですが、適切に実装されたシステムごとの環境変数は、「暗号化された」シークレットよりも安全であることを指摘する価値があります。どちらの場合でも、ターゲットシステムは、暗号化されたシークレットを使用するために、メモリ内のsomeポイントに保持する必要があります。
値が特定のノードの揮発性メモリに格納されている場合、オフラインでコピーして攻撃できるディスク上のファイルがないことも指摘する価値があります。これは一般にメモリ内の秘密の利点と考えられていますが、確実なものではありません。
環境変数と他のシークレット管理手法の問題は、絶対的なものよりも、セキュリティと使いやすさトレードオフのほうが重要です。あなたのマイレージは異なる場合があります。
開発者の観点から見ると、構成データを環境変数に格納すると、さまざまな環境(開発、QA、および本番)間のデプロイメントが簡略化され、開発者は間違った構成ファイルのデプロイについて心配する必要がなくなります。
Azure Webアプリは、このパターンを使用するオプションを提供し、非常にうまく機能します。
それに加えて、潜在的に機密性の高いデータをソース管理の範囲外に保ちます。これらのファイルには必要なボイラープレート構成の多くも含まれているため、これらのファイルをソース管理から無視することは(少なくとも.NETでは)現実的ではありません。