環境変数としてウェブサイトの秘密の価値を置くことの利点は何ですか?


24

https://12factor.net/configのdevopsガイドラインは、環境変数にWebサイトのシークレット(データベースパスワード、APIキーなど)を含めることを提案しています。テキストファイル(JSON、XML、YAML、INIなど)を使用する代わりにバージョン管理から無視される利点は何ですか?

.bash_profileおよびwebserver構成の環境変数を処理するよりも、秘密を使用して構成ファイルをコピーする方がはるかに簡単です。私は何かを見逃していますか?


1
理論的には、メモリよりもファイルの方が読みやすいため、攻撃対象領域をより大きく、複雑さをより小さくすることができます。
フローリンAsăvoaie18年

私の開発者の経験則では、環境変数に設定を保存するのは、Dockerのような環境でのみ行うのが最適です。コンテナーVM以外では、12factor.netの他のすべてのポイントと構成ファイルの使用を承認/優先します。通常のサーバー展開での環境変数の安全でない性質を好む人はいませんでした。
コーリーオグ

回答:


21

作者は彼らの推論をリストしていますが、それは少しばらばらです。彼らの主な議論は、構成ファイルを誤ってチェックインするのは簡単であり、構成ファイルはさまざまな形式を持ち、システム全体に散在する可能性があるということです(これらの3つはすべて、認証トークンや資格情報のようなセキュリティ関連の構成のせいぜい平凡な引数です)。

私自身の経験から、基本的に次の3つのオプションがあり、関連する利点と欠点があります。

データを設定ファイルに保存します。

このアプローチをとる場合、理想的にはリポジトリ自体からそれらを分離し、アプリがコンテンツを保存するエリアの外にあることを確認する必要があります。

利点:

  • SELinuxやAppArmorなどを使用してシステム全体のセキュリティを向上させる場合は特に、アクセスを隔離および制御するのが非常に簡単です。
  • 一般に、技術に詳しくないユーザーでも簡単に変更できます(これは公開されたソフトウェアの利点ですが、必ずしも組織固有のソフトウェアには適していません)。
  • サーバーの大規模なグループ間で簡単に管理できます。構成を展開するためのあらゆる種類のツールがあります。
  • 使用されている正確な構成が何であるかを検証するのはかなり簡単です。
  • よく書かれたアプリの場合、通常、構成ファイルを更新してから特定の信号をアプリ(通常はSIGHUP)に送信することにより、サービスを中断することなく構成を変更できます。

短所:

  • データを安全に保つには、適切な計画が必要です。
  • さまざまな形式を学習する必要があるかもしれません(ただし、最近では心配する必要があるのはほんの一握りであり、一般に類似した構文を持っています)。
  • 正確な保管場所はアプリ内でハードコーディングされている可能性があり、展開が問題になる可能性があります。
  • 構成ファイルの解析には問題があります。

データを環境変数に保存します。

通常、これはスタートアップスクリプトから環境変数と値のリストを取得することによって行われますが、場合によっては、プログラム名の前にコマンドラインでそれらを記述することもあります。

利点:

  • 構成ファイルの解析と比較して、ほとんどすべてのプログラミング言語では、環境変数から値を引き出すことは簡単です。
  • 誤って構成を公開することを心配する必要はありません。
  • この方法は一般的ではないため、あいまいさによってある程度のセキュリティが得られます。また、アプリをハッキングするほとんどの人は、環境変数をすぐに見ようとは思わないでしょう。
  • アクセスはアプリケーション自体で制御できます(子プロセスを生成するとき、環境を簡単にスクラブして機密情報を削除できます)。

短所

  • ほとんどのUNIXシステムでは、プロセスの環境変数に簡単にアクセスできます。一部のシステムはこれを軽減する方法(たとえば、LInuxのhidepidマウントオプション)を提供します/procが、デフォルトでは有効になっておらず、プロセスを所有するユーザーからの攻撃から保護しません。
  • 上記のセキュリティ問題を正しく処理する場合、使用している正確な設定を確認することは簡単ではありません。
  • 子プロセスを生成するときに環境をスクラブするには、アプリを信頼する必要があります。そうしないと、情報が漏洩します。
  • アプリを完全に再起動しない限り、構成を簡単に変更することはできません。

コマンドライン引数を使用してデータを渡します。

真剣に、これをすべてのコストで避けてください、それは安全ではありません、そして、それは維持するためにロバの痛みです。

利点:

  • ほとんどの言語の環境変数よりもさらに簡単に解析できます。
  • 子プロセスは自動的にデータを継承しません。
  • アプリケーションの開発時に特定の構成をすばやくテストする簡単な方法を提供します。

短所:

  • 環境変数と同様に、ほとんどのシステムで別のプロセスのコマンドラインを簡単に読み取ることができます。
  • 構成を更新するのは非常に面倒です。
  • 構成の長さに強い制限を設定します(1024文字まで)。

1
一つではない重要でない点は、最終的に、彼らはそのために、ディスク上のどこかにある、手動で任意のパスワードを与えることなく、サーバーの無人(再)起動である
PlasmaHH

7
ほとんどのUNIXシステムでは、重要な特権を必要とせずに、ほとんどすべてのプロセス環境変数を読み取ることができます。 -それを拡張できますか?/ proc / #### / environファイルは所有者のみが読み取ることができるため、rootになるか、sudoを持っている必要があります。
ラウエンツァ

このenv設定トレンドのいくつかは、標準コンテナを使用してenv変数をコンテナに渡すことで設定するdockerなどからも発生したと思います。
ラウエンツァ

@rrauenzaプロセスの所有権は、アカウントで物事を分離する非常に良い仕事をしない限り、重要な特権ではありません。また、所有者でない場合、実際にはCAP_SYS_ADMIN機能(ルートが暗黙的に持っている)のみが必要です。また、環境変数に関しては、おそらく正しいでしょうが、それはDockerを使用しても限界的な設計です。
オースティンヘメルガルン

3
@rrauenzaのポイントに同意します。答えはあらゆる点で非常に優れていますが、重要な特権を必要とせずにプロセス環境変数をほとんど正確に読み取ることができる方法を明確にしたいと思います。「実際にはCAP_SYS_ADMIN機能(ルートが暗黙的に持っている)だけが必要です...」に関して、悪意のあるエージェントがルート権限を持っている場合、さらなる議論は冗長であり、CAP_SYS_ADMINはルート権限である可能性があります(man7.org/linuxを参照) /man-pages/man7/capabilities.7.htmlCAP_SYS_ADMINカーネル開発者への注意
Nubarke

13

環境変数は、Webサーバーのすべての子プロセスに継承されます。これは、サーバーに接続するすべてのセッションと、それらによって生成されるすべてのプログラムです。秘密は、これらのプロセスすべてに自動的に公開されます。

テキストファイルにシークレットを保持する場合は、サーバープロセスで読み取り可能である必要があり、すべての子プロセスでも読み取り可能である必要があります。しかし、少なくともプログラムはそれらを見つけて見つけなければなりません。自動的には提供されません。また、いくつかの子プロセスを異なるアカウントで実行し、それらのアカウントでのみシークレットを読み取り可能にすることもできます。たとえば、suEXECはApacheでこれを行います。


1
「サーバーに接続するすべてのセッション」は誤解を招く声明です。サーバーへのHTTPセッションを開いてその環境変数にアクセスすることも、ルートアクセスまたはWebサーバープロセスを所有していない限り、そのサーバーのシェルにログインして取得することもできません。
セグフォルト

Webサーバーによって生成されるすべてのプロセスは、他の方法でアクティブな手順を実行しない限り、その環境を継承します。HTMLページにはその情報を使用する機能はありませんが、スクリプトにはあります。
アンドリューシュルマン

正しいものの、この回答は、特にセッションという用語に関して、いくつかの修正/譲歩で行うことができます。最初に読むと、外部クライアントへの情報開示の可能性をほとんど示唆するために、環境変数の使用を悪い光で描いているようです。また、env-varsの制限された設定に対してsuexecに匹敵する譲歩を行うことができます。たとえば、プロセスごとのenv-vars(a la MYVAR=foo /path/to/some/executable)を設定すると、プロセスとその子のみへの伝播が制限されます。子プロセスの環境。
シャローム

2

環境変数やファイルに関しては、セキュリティ関連のトレードオフがいくつかあるとしても、セキュリティがこの推奨事項の主な推進力であるとは思いません。12factor.netの作成者は、Heroku PaaSの開発者でもありました(またはそうでしたか?)。誰もが環境変数を使用できるようにすることで、開発がかなり簡素化されたと思われます。さまざまな構成ファイルの形式と場所は非常に多様であり、それらをすべてサポートすることは困難でした。環境変数は比較すると簡単です。

行われた会話のいくつかを推測するのに、多くの想像力は必要ありません。

開発者A:「この秘密の設定ファイルUIは散らかっています!json、xml、csvを切り替えるドロップダウンが本当に必要ですか?」

開発者B:「ああ、誰もがアプリの構成に環境変数を使用しなければ、人生はとても壮大になるでしょう。」

開発者A:「実際には、セキュリティに関連するもっともらしい理由がいくつかあります。環境変数が誤ってソース管理にチェックインされることはおそらくないでしょう。」

開発者B:「デーモンを起動するスクリプト、または構成ファイルで環境変数を設定しませんか?」

開発者A:「Herokuではありません!UIに入力させます。」

開発者B:「見てください、12factor.netのドメイン名アラートが消えました。」1


1:ソース:構成。


1

TL; DR

構成ファイルの代わりに環境変数を使用する理由はいくつかありますが、見落とされる最も一般的なものの2つは、帯域外構成の有用性と、サーバー、アプリケーション、または組織の役割間の分離の強化です。考えられるすべての理由を網羅したリストを提示するのではなく、回答の中でこれら2つのトピックのみを取り上げ、それらがセキュリティに与える影響について軽く触れます。

帯域外構成:ソースコードからの秘密の分離

すべてのシークレットを構成ファイルに保存する場合、それらのシークレットを各サーバーに配布する必要があります。つまり、コードと一緒にシークレットをリビジョン管理にチェックインするか、シークレット用の完全に別個のリポジトリまたは配布メカニズムを持つことを意味します。

秘密を暗号化しても、これを解決することはできません。鍵の管理と配布についても心配する必要があるため、問題を1つ削除するだけです。

要するに、環境変数は、開発を運用から分離する場合に、サーバーごとまたはアプリケーションごとのデータをソースコードから移動するためのアプローチです。これは、ソースコードを公開している場合に特に重要です。

分離の強化:サーバー、アプリケーション、および役割

秘密を保持するための構成ファイルを確かに持つことはできますが、秘密をソースコードに保存すると、特異性の問題が生じます。シークレットセットごとに個別のブランチまたはリポジトリがありますか?適切なシークレットのセットが適切なサーバーに到達するようにするにはどうすればよいですか?または、どこでも同じ(またはすべてを1つのファイルに収めている場合はどこでも読み取り可能)な「秘密」を持つことでセキュリティを低下させます。

サーバーごと、またはアプリケーションごとに一意のシークレットを使用する場合、環境変数を使用すると、多数のファイルを管理する必要がなくなります。新しいサーバー、アプリケーション、またはロールを追加する場合、新しいファイルを作成したり古いファイルを更新したりする必要はありません。問題のシステムの環境を更新するだけです。

セキュリティに関する別の考え

カーネル/メモリ/ファイルセキュリティの徹底的な調査はこの回答の範囲外ですが、適切に実装されたシステムごとの環境変数は、「暗号化された」シークレットと同じくらい安全であることを指摘する価値があります。どちらの場合でも、ターゲットシステムは、使用するために、ある時点で復号化されたシークレットをメモリに保持する必要があります。

また、特定のノードの揮発性メモリに値が保存されている場合、オフラインでコピーおよび攻撃できるディスク上のファイルは存在しないことを指摘する価値があります。これは一般に、インメモリシークレットの利点と考えられていますが、決定的なものではありません。

環境変数と他の秘密管理手法の問題は、絶対的な問題よりもセキュリティと使いやすさのトレードオフの問題です。あなたのマイレージは異なる場合があります。


2
これは納得のいくものではありません。なぜなら、構成ファイルについて言及する欠点はすべて環境変数にも当てはまるからです。環境変数構成データです。彼らは魔法のように自分自身を設定しません。これらは各システムに配布する必要があり、何らかの設定メカニズムを使用してそれらを設定する必要があります。
jpaugh

@jpaughあなたはストローマンの議論をして、私が言ったことのないものを攻撃しています。私が対処する問題は、帯域外設定とデータ分離です。明確に説明したように、これらのことは好きな方法で行うことができます。必要に応じて、GitHubでコードと一緒に秘密を公開することもできますが、一般的なケースでは確かに賢明ではないようです。しかし、唯一のあなたはのために必要なトレードオフを決定することができ、あなたの特定の脅威モデルの中に適切に動作するシステムを。
CodeGnome

2
他の構成データと同じくらい環境変数に適用されることを除いて、すべてのポイントは正しいです。環境変数をファイルに保存する場合、それらをコミットできます。また、帯域外で送信する場合は、入力するよりもファイルで行う方が簡単です。しかし、それらを入力したい場合は、代わりにJSONオブジェクトを入力して、stdinで読み取ってみませんか?実際には、コマンドラインよりも安全です。
jpaugh

1

個人的には、環境変数を設定することはお勧めしません。.bashrcこれらはシェルによって開始されたすべてのプロセスから見えるようになりますが、デーモン/スーパーバイザーレベル(init / rcスクリプト、systemd config)で設定して、スコープが必要な場所に限定されるようにするためです。

別々のチームが操作を管理する場合、環境変数は、操作用の簡単なインターフェイスを提供し、構成ファイル/形式を知らずに、および/またはコンテンツのマングリングに頼ることなく、アプリケーションの環境を設定します。これは、運用チームが運用上のニーズ(展開の容易さ、スケーラビリティ、セキュリティなど)に基づいて展開システム(OS、スーパーバイザープロセス)を選択できる多言語/マルチフレームワーク設定で特に当てはまります。

別の考慮事項は、CI / CDパイプラインです-コードが異なる環境を通過するため(すなわち、dev、test / qa、ステージング、プロダクション)環境の詳細(展開ゾーン、データベース接続の詳細、資格情報、IPアドレス、ドメイン名など)は、専用の構成管理ツール/フレームワークによって最適に設定され、アプリケーションによって消費されます。環境からのプロセス(DRYで、1回書き込み、どこでも実行)。従来、開発者はこれらの運用上の懸念を管理する傾向がありましたが、コードに加えて構成ファイルまたはテンプレートをチェックインする傾向があり、運用要件が変わると回避策やその他の複雑さを追加する傾向があります(たとえば、新しい環境/展開/サイト、スケーラビリティ/セキュリティ重量を量ります、

  • Env-varsは、大規模な構成/複雑さを簡素化します。
  • Env-vars は、アプリケーションの非コード関連の側面を担当するチームとともに、統一された(標準ではないが)拘束力のない方法で運用構成を配置します。
  • 環境変数は、アプリケーションをサポートするマスター/スーパーバイザープロセス(たとえば、god、monit、supervisord、sysvinit、systemdなど)のスワップアウトをサポートします。進化/変化します。現在、すべての言語フレームワークには何らかのプロセスランタイムがありますが、これらは運用上劣る傾向があり、開発環境により適しているか、多言語/マルチフレームワークの本番環境で複雑さが増します。

生産のために、私は、アプリケーションでENVは-varsの設定好むEnvironmentFileなどの/etc/default/myapplication.conf構成管理とのみによって読み取り可能セットで展開されているrootようなsystemd(またはそのことについて何かが)専用の下でアプリケーションを起動することができますDeprivilegedシステムユーザプライベートグループopsおよびの専用ユーザーグループでバックアップsudo-これらのファイルは、デフォルトでは世界中で読み取り不可能です。これは、開発者/テスターが独自のEnvironmentFilesをdev / qa / test環境にドロップできるようにする一方で、Dev + Opsのすべての長所をサポートする1​​2ファクター準拠であり、適切なセキュリティのすべての利点を備えています。


0

開発者の観点から見ると、環境変数に構成データを保存することで、開発、QA、本番などのさまざまな環境間での展開が簡単になり、開発者は間違った構成ファイルの展開について心配する必要がなくなります。

Azure Webアプリには、このパターンを使用するオプションがあり、非常にうまく機能します。

それに加えて、潜在的に機密性の高いデータをソース管理から除外します。ソース管理からこれらのファイルを無視することは(少なくとも.NETでは)実際には実行できません。これらのファイルには、必要な定型的な構成が数多く存在するためです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.