重要なパスワードをサーバー環境変数に保存しても安全ですか?


23

サーバーのクラスターがあり、各サーバーには現在、機密性の高いミッションクリティカルなシステム(メッセージキュー、データストア、その他のサービス)のプレーンテキストパスワードが含まれています。

一部の人々は、重要なパスワードを構成ファイルからサーバープロセスが実行されるユーザーアカウントの環境変数に移動します。このようにして、構成ファイルをバージョン管理にコミットできます。システム管理者は、サーバーシステムのセットアップ時に適切な環境変数を作成するだけで済みます。当然、これらのサービスを実行するアカウントへのアクセスは非常に制限されています。

これは、プレーンテキストの構成ファイルでパスワードを回避するための本当に最良の方法ですか、それとももっと良い方法がありますか?


3
変数として保存する場合、保存時とユーザーがクエリを実行するときの両方で平文であることに注意してください。つまり、サーバー層の制御を少し失うと、攻撃者にパスワードを渡したことになります。おそらく暗号を使用し、必要に応じてパスワード情報を解読します。
フランクトーマス14年

いい考えだ、フランク。暗号を使用する場合、どのようなシステムを使用しますか?RSA / SSHキー、キーチェーンツール、または他の何かに基づいたものですか?現在、CentOSやAmazonなどのLinux> 2.6システムを使用しています。
スティーブHHH 14年

回答:


11

Linuxシステムを使用している場合は、/ proc / * / environを見て、環境変数が機密情報を保存するのに適した場所であるかどうかを判断します。/ proc / selfは現在のプロセスです:

$ tr '\0' '\n' < /proc/self/environ
USER=me
LOGNAME=me
HOME=/home/me
PATH=/usr/bin:/bin:/usr/sbin:/sbin
MAIL=/var/mail/me
SHELL=/usr/bin/sh
SSH_CLIENT=1.2.3.4 58195 22
SSH_CONNECTION=1.2.3.4 58195 7.8.9.0 22
SSH_TTY=/dev/pts/1
TERM=xterm

環境変数を設定することはおそらくどこかでファイルを読んでいることに気をつけてはいけません。

覚えておくべきことは、パスワードを使用すると、プログラムでパスワードを使用できることを意味します。このパスワードが、プログラムが必要とするたびに入力するユーザーによって提供されない場合、そのパスワードはプログラムのアクセスのみに基づいてアクセス可能でなければなりません。パスワードをローカルで暗号化し、キーを使用してプログラムを復号化することもできますが、それはパスワードを誤って公開しないようにすることです。プログラムと同じアクセス権を持つ人は、暗号化キーの読み取りなど、プログラムと同じ操作を実行できます。

これを行う正しい方法は、アプリケーションを制限付きアカウントとして実行し、ファイルシステムレベルの権限で保護されたファイルにパスワードを保存することです。パスワードをバージョン管理システムから保護するために、ファイルなどを「インクルード」できることを願っています(VCSにセキュリティ管理がないと仮定)。不注意による開示から保護するために、必要に応じてパスワードを隠してください。base64でエンコードし、pgpを使用して暗号化してください。サーバープログラムのオプションセットで意味があります。これを行うためのプログラムを作成している場合、できる最善の方法は、必要な場合にのみユーザーにパスワードを要求し、使用されたらすぐにそのパスワードをメモリから消去することです。



3
はい、プログラムを実行しているユーザーが所有するモード0600のファイルには、プログラムの環境にアクセスできる同じユーザーがアクセスできます。しかし、私が述べたように、環境はおそらくファイルを読み取ることで構成されているため、データを環境にコピーすると、データが利用できる場所の数が増えます。また、デフォルトでは、環境は子プロセスに複製されます。また、多くのプログラムには、バグや意図的な設計上の決定のために、環境変数を照会する外部手段があります(phpinfo()を考えてください)。ファイルがいずれかの方法で関与する場合、なぜ攻撃対象領域を増やすのですか?
ダニーザウアー

1
あなたが与えたtrコマンドは私にとっては機能しませんでした-これは機能しました:cat /proc/self/environ | tr '\0' '\n'
ロボキャット

私は自分の電話にいるので、それを伝えるのは難しいです...それはゼロでなければなりません。文字「o」を入力しましたか?
ダニーザウアー

8

あなたはニーズがされることを、任意のデータを持っている場合、最終的には、読みだけでなく、として書かれた、あなたは(またはあなたがしている場合は、パスワードを使って何かを保護終わるつもりは本当に物理的なハードウェアスマートカードとPINで、被害妄想)、なし暗号化の層がいくつあっても問題ありません。

これは、システムセキュリティと利便性の基本的な問題に要約されます。悪意のあるアクターが「商品」に到達するために侵害しなければならないセキュリティコントロールのレイヤーを多数持つことで「多層防御」を追加できますが、正当なアクターがデータの読み取りまたは変更を希望する場合、彼らはたくさんのフープを通過しなければなりません。別の方法は、テキストファイルのプレーンテキストパスワードです。

ミッションクリティカルなシステムで情報を本当に保護したい場合の対処方法:

  1. 永続ストレージ全体のコンテンツが暗号化されるように、フルディスク暗号化を使用します。

  2. マシンへの物理的なアクセスを制限します。安全なロックメカニズムでマシンのシャーシをロックし、キーへの物理的なアクセスを制御します。アクセスのゲートキーパーとなる筋肉(武装したガード)を雇います。

  3. デバイスのオペレーティングシステムにきめ細かな必須アクセス制御(MAC)を適用します。GNU / Linux上のSELinuxのようなものから始めて、それをEnforcingに設定してから、実動ソフトウェアの正確なニーズに合わせてポリシーを調整し、それらのアカウントに必要なファイルに対する必要な許可のみを許可します。

  4. システム固有のパスワードと構成ファイルのバージョン管理を行う場合、プレーンテキストのパスワードをバージョン管理に誤ってコミットしてしまう可能性のある間違いを避けたいと思います。漏洩したパスワードをVCSのキャッシュ。環境変数は、そのためのいくつかの実行可能なオプションの1つです。もう1つは、プログラムの起動時のパスワードプロンプトですが、マシンを再起動して動作状態を復元するのは手作業であり、自律的に実行することはできません。そのため、利便性とセキュリティが再びあります。

  5. ネットワークを介した攻撃の危険性を最小限に抑えるために、ファイアウォールの許可を処理するネットワーク専門家を必ず用意してください。外部システム、特にパブリックインターネットとインターフェイスするソフトウェアの監査(コードの侵入テストおよびホワイトボックステスト)。「インターフェース」には、直接的なネットワーク接続だけでなく、「信頼できない」データ(バイトがセキュアサーバーのRAM /ディスク/ CPUの外部から発信されたデータ)の読み取りまたは書き込みも含まれます。

これは完全なリストではありませんが、特にポイント4はおそらくあなたに関係がありますが、少なくともステップ1から3を実行しない場合、ポイント4とポイント5の検討はあまり役に立ちません。システムは、かなり基本的なレベルでは安全ではありません。


#1はスキップします。システムが実行されている場合、ファイルシステムはマウントされ、暗号化されていません。実行されていない場合は、物理的なアクセス制御が適切でなければなりません。再起動が必要な場合は、ブートごとに復号化キーを提供する必要があります(面倒です)、またはマシンにそれを提供する必要があります-この場合、資格情報は通常、ハードドライブにアクセスできる人にも利用可能。ほとんどの「サーバー」マシンは、通常、そのトレードオフコストのためにディスク暗号化を使用しません。:)
ダニーザウアー14年

「これは、システムセキュリティと利便性の基本的な質問に要約されます」-私の答えから引用-あなたのコメントにも同様に当てはまります。セキュリティ利便性を同時に最大化することはできません。
allquixotic

1
#1は、RAMの一部がディスクにヒットする場合(スワップ)、または後で「不良」になり、OSから離れたがそのRAMを保持しているssdセクターにヒットする場合に重要です。ディスクが現在ロック解除されている場合でも、そのデータの塊はプラッター上でスクランブルされます。
アキラ14年

3

環境変数にパスワードを渡すことは、プログラムにファイルからパスワードを読み取らせるのと同じくらい安全です。同じユーザーとして実行されているプロセスのみがプロセスの環境を読み取ることができ、これらのプロセスはとにかく同じファイルを読み取ることができます。

これは、コマンドラインでパスワードを渡すこととは異なることに注意してください。コマンドライン引数は、同じユーザーとして実行されているプロセスだけでなく、同じマシン上で実行されているすべてのプロセスで読み取り可能です(強化対策を除く)。

環境を介して変数を渡す場合、プログラムが他のプログラムを起動するかどうかに注意してください。これらの他のプログラムは、親の環境を継承します。そのため、他のプログラムが環境のコンテンツを誤ってリークする恐れがある場合は、これを行わないでください。

シナリオの欠陥は、「サーバーシステムのセットアップ時に適切な環境変数を作成する」ことです。環境変数は、プロセスの動的なプロパティです。システムのセットアップ時に作成することはできません。セットアップすることで、再起動後も存続するものを意味する場合ではありません。つまり、特定のユーザーがログインしたときに、管理者がこの変数が環境に存在するように調整したと考えられます。これは、構成ファイル(通常~/.pam_environment~/.profileまたはから読み取られたファイル~/.profile)を介して行われます。したがって、このソリューションでは、実際には、パスワードを構成ファイルから移動しません。

パスワードがユーザーのログイン時環境にあるように設定するのは良い考えではありません。これは、そのユーザーとして実行されているすべてのプロセスが秘密を持っているため、どこでもリークに対して脆弱であることを意味します。

パスワードは、バージョン管理下にある構成ファイルおよび通常の展開メカニズムとは別のファイルに配置する必要があります。便利な場合は、ある時点で環境にパスワードを入れてもかまいませんが、できるだけ小さなプログラムセットに対して実行する必要があります。

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