シェル/Perl スクリプトでパスワードを保持するためのベスト プラクティスは?
質問
私は最近、同僚を助けるために Perl とシェル スクリプトのスキルをほこりを払わなければなりませんでした。問題の同僚は、大規模な Oracle データベース バックエンドを備えた内部アプリケーションからいくつかのレポートを提供する任務を負っていますが、彼らにはこれを行うためのスキルがありません。私にそのようなスキルがあるかどうか疑問に思う人もいるかもしれませんが(笑い)、どうやら十分な数の人が私がそのスキルを持っていると考えているようで、私がそのスキルから抜け出すことはできないことを意味します。
そこで私の質問ですが、データベースからレポートを抽出するために、私のスクリプトは明らかに接続してクエリを実行する必要があります。これまでのところ、データベースのユーザー名とパスワードを保存する場所について適切な解決策を思いつくことができていないため、現在はスクリプトにプレーンテキストとして保存されています。
おそらく CPAN モジュールとして、他の誰かがすでに書いた、これに対する良い解決策はありますか?それとも、ユーザーとパスワードの組み合わせをファイルシステム上の別の場所に隠された完全に別のファイルに保存するなど、他にやった方がよいことはあるのでしょうか?それとも、システム全体の grep を使用してスクリプトから抽出されるのを避けるために、単純に暗号化したままにしておくべきでしょうか?
編集:Oracle データベースは HP-UX サーバー上にあります。
アプリケーション サーバー (シェル スクリプトを実行する) は Solaris です。
スクリプトを私だけが所有するように設定することはできません。複数のサポート担当者がアクセスできるサービス アカウントがスクリプトを所有する必要があります。
スクリプトは cron ジョブとして実行することを目的としています。
公開キー認証を使用したいのですが、Oracle でそれを機能させる方法がわかりません。そのような方法がある場合は、教えてください。
解決
私のベストプラクティスは、シェル/Perl スクリプトにパスワードを保持しないことです。それが公開鍵認証の目的です。
他のヒント
スクリプトがサーバーからリモートで実行されている場合。
- レポートビューを作成する
- ログインしているユーザーには、レポート ビューで選択するためのアクセス権のみを与えます
- パスワードを保存するだけです。
そうすれば、ユーザーができることは、レポートのデータを選択することだけです。たとえ誰かがパスワードを偶然入手したとしても、それを使ってできることは限られてしまいます。
私は個人的に設定ファイルにパスワードを保持しており、アプリケーションとは独立して配布され、特定のマシン/環境に合わせて変更できます。シェル スクリプトでは、メイン スクリプト内でこれらをソースできます。
ただし、Perl にはさまざまなアプローチがあります。調べてみるとよいかもしれません Getopt::Long コマンド ライン オプション (および追加で Getopt::ArgvFile それらを単純な構成ファイルに保存する)、または次のようなものを参照してください。 構成::IniFiles 背後にもう少し力のあるもののために。私が通常使用するのはこれら 2 種類ですが、他にも使用可能な構成ファイル モジュールがあります。
良い解決策はありません。パスワードを少し難読化することはできますが、安全にすることはできません。
DB 設定を制御できる場合は、パスワードなしで名前付きパイプ (少なくとも mysql はこれをサポートしています) による接続を試行し、OS に権限を処理させることができます。
資格情報を制限付きのアクセス許可を持つファイルに保存することもできます。
ksh と bash のタグを付けたので、Linux を想定します。
問題のほとんどは、ユーザーがスクリプトを読んでファイルの非表示/暗号化に使用した方法を特定できれば、同じことを手動でも実行できることです。
より良い方法は、次のようにすることです。
- 自分だけが表示、読み取り、開くことができるようにスクリプトを作成します。chmod700です。パスワードをハードコードする必要はありません。
- ユーザーが実行でき、 sudo を実行する「ランチャー」スクリプトを用意します。
こうすることで、ユーザーはランチャー スクリプトを確認し、コマンド ラインが 1 つしかないことを確認できます。実行することはでき、機能しますが、sudo されたスクリプトのソースを読み取る権限がありません。
実行している Oracle のバージョンがわかりません。Oracle の古いバージョン (9i Advanced Security より前) では、一部の DBA は次のようにします。 CREATE USER OPS$SCOTT IDENTIFIED BY EXTERNALLY
そしてセット REMOTE_OS_AUTHENT
本当のこと。
これは、リモートの Sun マシンがユーザーを SCOTT として認証し、Oracle DB がその認証を受け入れることを意味します。
これは悪い考えです。
想像できるように、SCOTT のローカル ユーザーを持つ Windows XP はパスワードなしで DB にログインできます。
残念ながら、Oracle 9i DB に関して私が知っている唯一のオプションは、スクリプトまたはクライアント マシンがアクセスできる場所にユーザー名とパスワードを保存しないことです。
どのようなソリューションであっても、Oracle のソリューションを調べてみる価値はあります。 プロジェクトのロックダウン コミットする前に。
パスワードを保存するには、2 段階の暗号化ルーチンを実行できます。最初はスクリプト自体にハードコードされたキーを使用し、オプションで 2 回目はファイルに保存されたキー (アクセスを制限するためにファイル権限を使用して設定されます) を使用します。
特定の状況では、キー ファイル (+ スクリプトからのキー) を使用するか、状況の要件がそれほど大きくない場合は、スクリプトにハードコードされたキーを使用して暗号化を使用することができます。どちらの場合も、パスワードは構成ファイル内で暗号化されます。
完璧な解決策はありません。何らかの方法で暗号化を解除してクリアテキストのパスワードを取得できなければなりません...そして、あなたがそれを行うことができれば、正しい情報を持っている他の人もそれを行うことができます。
特に Perl スクリプトを渡す状況では (vs.exe) 暗号化 (およびハードコードされたキー) がどのように行われているかを簡単に確認できます。そのため、キーファイル (ファイルシステムのアクセス許可によって保護できる) を使用するオプションも許可する必要があります。
実装方法の実際的な例をいくつか示します。 ここ
UNIX では、これらのスクリプトを常に setuid にし、ユーザーとパスワードの情報を厳重に保護されたファイルに保存します (ディレクトリ ツリー全体は通常のユーザーは読み取り/検索できず、ファイル自体はスクリプトの所有者のみが読み取り可能です)。 。
これらを別のファイルに保存し、簡単に暗号化し、必要なテーブルへの読み取り専用アクセス権を持つ別のユーザーをデータベース内に作成します。ファイルが読み取られたと思われる場合は、そのユーザーのみのアクセスを遮断できます。
さらに凝りたい場合は、SUID プログラムで /proc//exe と cmdline (Linux の場合) をチェックし、その後でのみユーザー名を解放することもできます。
Solaris サーバーから ANT を使用して SQL コードを MSSQL (実際にはその MSSQL サーバー上のデータベースにデプロイするため、ロールは SysAdmin である必要がありました) にデプロイする開発者と同様の問題が発生しました。ここでも、ユーザー名とパスワードを ANT build.xml ファイルに保存したくなかったので、理想的ではないことはわかっていますが、私の解決策は次のとおりです。
- ユーザー名とパスワードの名前と値のペアをプレーン テキスト ファイルに保存します
- (Solaris 上で) ファイルを暗号化し、特定の管理者のみが知っているパスフレーズを使用する
- 暗号化されたファイルのみを Solaris システム上に残します。
- ANT build.xml は sudo 復号化を実行し、管理者が入力したパスフレーズの入力を求めます。
- ANT は、ユーザー名とパスワードを SQL 文字列の変数としてロードする復号化されたファイルをソースします。
- ANT は平文ファイルを直ちに削除しました
- ANT はコードをデプロイして終了します
これはすべて数秒で行われ、サーバー上で SQL ユーザー名とパスワードにアクセスできるようになることはありません。コードは許可された管理者によって運用環境にデプロイされるため、開発者がコードにコードを含める必要はありません。
確かにもっと良くなる可能性はありますが、...
JB
これまでこのスレッドを見たことがないのが残念です。とても面白そうです。今後このスレッドにアクセスする人のために 2 セントを追加します。
DB サーバー自体で OS 認証を使用することをお勧めします。REMOTE_OS_AUTHENT はまだ FALSE です。
別のマシンからスクリプトを呼び出す場合は、フレーズのない SSH キーをセットアップし、SSH を使用してそこにアクセスします。その後、SQL 結果を呼び出し側マシンにパイプバックして、この情報をさらに処理できます。
これにより、どこにでもパスワードをコーディングする必要がなくなります。もちろん、悪意のある管理者がフレーズなしキーを乗っ取って使用した場合、DB ホスト上のユーザー アカウントにアクセスし、OS 認証された DB ユーザーが実行できるあらゆる操作を行うことができます。これを軽減するには、その OS ユーザーのデータベース権限を最小限に、たとえば「読み取り専用」に下げることができます。
インゴ
Windows では、クリア テキストのパスワードを含むフォルダーとその中にファイルを作成します。スケジュールされたジョブ (スクリプトまたはバッチ) を実行するユーザーを、このフォルダーおよびファイルへの読み取り/書き込みアクセス権を持つ唯一のユーザーとして設定します。(管理者も削除します)。他のすべてのスクリプトに、この制限付きファイルからクリア テキスト パスワードを読み取るコードを追加します。
少数の人にとってはこれで十分でしょう。
キーワード:パスワードのハードコーディング
Cyberark AIM などの商用ソリューションや、より高度なソリューションもありますが、無料ですぐに使用できるので、私は SSH 公開/秘密キーを利用しています。その理由の 1 つは、SSH キーのペアが既に作成されている可能性が高いためです。セキュリティポリシー;次に、SSH キー ペアには、ファイル アクセス許可、継続的なシステム強化 (トリップワイヤなど)、またはキー ローテーションによってキーを保護する一連の標準プロトコルがすでに組み込まれています。
これが私がやった方法です:
SSH キー ペアをまだ生成していない場合は生成します。キー ペアとディレクトリは、デフォルトのシステム プロトコル/権限によって保護されます。ssh-keygen –t rsa –b 2048
SSH公開キーを使用して文字列を暗号化し、同じ.sshディレクトリ$ echo "Secretword"に保存します| openssl rsautl -encrypt -inkey〜/.ssh/id_rsa.pub -pubin -out〜/.ssh/secret.dat
SSH 秘密キーを使用してキーを復号化し、パラメータをスクリプト/AP にリアルタイムで渡します。リアルタイムで復号化する行を含めるスクリプト/プログラム:文字列=
openssl rsautl -decrypt -inkey ~/.ssh/id_rsa -in ~/.ssh/secret.dat
PS - 私は CYBERARK AIM エージェントレス ソリューションを実験しています。API/スクリプトに大幅な変更/APIの変更が必要になるのは、ある意味面倒です。その様子はまたお知らせします。