保護された情報を公開せずにユーザーがスクリプトを実行できるようにする方法

保護された情報を公開せずにユーザーがスクリプトを実行できるようにする方法

ルートユーザーが環境変数に設定された資格情報(APIキーなど)を持ち、権限のないユーザーであるジョンが与えられた場合、ジョンにスクリプトを実行させるにはどうすればよいでしょうか。用途その API キーを John に漏らすリスクなしに使用できますか?

答え1

質問が少し焦点が定まっていないようです。

  • 質問、それ自体、 「スーパーユーザー環境変数」(つまり「ルート環境変数」)から値を取得することについて言及しています。それが何を意味するのかさえわかりません。ジョンは「ルート」としてログインしている(別の)ユーザーの環境から値を取得する必要があると言っているのですか、またはまたはを介して「ルート」として実行しているユーザーの環境について話しているのですかsusudoプロセス (おそらくバックグラウンド プロセス)「root」として実行されていますか?

    しかし、どんな詳細を念頭に置いていても、鍵は非常に動的で一時的なものであるように思われます。これが何を意味するのか理解できないので、不可能とは言いませんが、難しそうです。

  • しかし、コメントでは、スクリプトを実行可能にするが読み取り不可にすることについて言及しています。これは、非ルート ユーザーが読み取れない限り、スクリプトにキーをハードコードしても構わないと考えていることを示唆しています。これは、キーが非常に静的であり、めったに変更されないため、キーが変更されるたびにスクリプトを変更してもよいと考えていることを示唆しています。

    U&Lまさにこのトピックに関する長いスレッドがあります: スクリプトは実行可能だが読み取り不可であることはありますか?  残念なことに、ほとんどの回答は否定的なもの、または回避策、転向、回避策であり、そのいくつかは他のものよりも効果的です。たとえば、サンタナは示唆する/etc/sudoers ジョンが走るスクリプトを昇格された権限で実行しますが、自分自身としてそれを読み取ることはできません。ただし、スクリプトが昇格された権限を必要としない場合 (キーを取得する場合以外)、昇格された権限でスクリプトを実行しないでください。

    しかし、この関連する質問(Super User 上)、スクリプトを C プログラムでラップして実行可能だが読み取り不可にする、不格好な方法を紹介します。その回答で説明したように、この手法は絶対確実ではなく、情報が漏洩する可能性があります。

  • 私の意見では、最も合理的で妥当な解釈は、キーが John が読み取れないファイルに保存されることです。このような配置を実装する従来の方法は、setUID および/または setGID です。(sudoも便利です。)

その方法の例を次に示します。次のような C プログラムを記述します。

#include <stdio.h>
#include <stdlib.h>

#KEY_FILE を定義する        (適切なパス名)
#define スクリプト          (適切なパス名)

主要()
{
        ファイル *key_fp;
        文字キー[80];        (適宜調整してください)
        gid_t ジッド;
        uid_t ユーザID;
        char *引数[10];      (適宜調整してください)

        key_fp = fopen(KEY_FILE, "r");
        (key_fp == NULL)の場合
        {
                perror(KEY_FILE);
                終了(1);
        }
        (コードを読み取って検証する
        キーfpをクローズします。
        (setenv("KEY", キー, 1) != 0) の場合
        {
                fprintf(stderr, "setenv() に問題があります。\n");
                終了(1);
        }
        gid = getgid();
        uid を取得します。
        // 使用
        // (setresgid(gid, gid, gid) != 0 || setresuid(uid, uid, uid) != 0 の場合)
        // 利用可能な場合; そうでない場合
        (setregid(gid, gid) != 0 || setreuid(uid, uid) != 0)の場合
        {
                fprintf(stderr, "権限の削除中に問題が発生しました。\n");
                終了(1);
        }
        args[0] = "スクリプト名";     (適宜調整してください)
        引数[1] = NULL;
        execv(スクリプト、引数);
        perror(スクリプト);
        終了(1);
}

KEY_FILEキーを含むファイルのフルパス名を に定義し、SCRIPTスクリプトを含むファイルのフルパス名を に定義します。John がスクリプトへの読み取りアクセス権を持ち、キー ファイルへのアクセス権を持たないこと、また、どちらのパスのディレクトリにも書き込みアクセス権を持たないことを確認します。このプログラムがキー ファイルを読み取れるように、setUID および/または setGID を設定します。このプログラムはキーを読み取り、環境に挿入し、権限をドロップして、スクリプトを実行します。(上記のコードを変更して、プログラムに渡されたコマンド ライン引数がスクリプトに渡されるようにすることもできます。)

上で述べたように、スクリプトは John の UID と GID を使用して実行されますが、キーは環境にあります。一部のシステムでは、John が または を使用してスクリプトの環境を読み取ることができる場合があります。その場合、スクリプトでキーをすぐにローカル (エクスポートされていない) 変数にコピーし、変数を設定解除すると役立つ場合があります。/proc/(pid_of_script)/environpsKEY

スクリプトがプログラムにキーを渡すのはおそらく安全だろう

  • パイプ(例:)を通して、printf "%s" (key_value) | (program)
  • hereドキュメントを通じて、または
  • here 文字列を介して。

値を環境経由で渡すことのリスクについては、上で説明しました。コマンドライン パラメータとして渡すことは避けてください。これは、 によって確実に認識されるからですps

プログラムを を通じて実行可能にしたい場合は、 が実 ID と有効 ID を設定するsudoため、John の UID と GID をハードコードする必要があるかもしれません。sudo

関連情報