如何允許用戶執行腳本而不洩露受保護的信息

如何允許用戶執行腳本而不洩露受保護的信息

鑑於 root 使用者在環境變數中設定了一些憑證(例如 API 金鑰),並且給定非特權使用者 John,我如何讓 John 執行一個腳本用途說 API 金鑰沒有將其值洩漏給 John 的風險?

答案1

問題好像有點沒有重點。

  • 問題是,本身, 討論從「超級使用者環境變數」(即「根環境變數」)取得值。我什至不確定這意味著什麼。您是說 John 應該從以「root」身分登入的(另一個)使用者的環境中取得值,或透過su或以「root」身分執行的使用者的環境中取得值sudo嗎?或者你在談論一個環境過程 (可能是後台進程)以「root」身分執行?

    但是,無論您想到什麼細節,這聽起來似乎關鍵是非常動態且短暫的。由於我不明白這意味著什麼,所以我不會說這是不可能的,但聽起來很困難。

  • 但隨後在評論中您談到使腳本可執行但不可讀。這表示您願意將金鑰硬編碼到腳本中,只要非 root 使用者無法讀取它。這表示密鑰非常靜態,很少發生變化,因此您願意在每次密鑰更改時修改腳本。

    大學與大學關於這個主題有一個很長的話題: 腳本可以執行但不可讀嗎?  遺憾的是,大多數答案是否定的,或者是偏離、轉移注意力或變通辦法,其中一些比其他更有效。例如,桑塔納建議建立一個條目,/etc/sudoers 允許 John跑步具有提升權限的腳本,但無法以自己的身分讀取它。但是,如果腳本不需要提升的權限(除了取得金鑰),您不希望以提升的權限來執行它。

    然而,關於這個相關問題(關於超級用戶),我提出了一種笨拙的方法,透過將腳本包裝在 C 程式中來使腳本可執行但不可讀。正如我在該答案中解釋的那樣,這種技術並不是萬無一失的;資訊可能會透過多種方式洩漏出去。

  • 恕我直言,最合理/最合理的解釋是密鑰保存在約翰無法讀取的檔案中。實現這種安排的傳統方式是 setUID 和/或 setGID。 (sudo也很有用。)

下面是如何執行此操作的範例。寫一個 C 程序,如下所示:

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

#定義KEY_FILE        (適當的路徑名)
#定義腳本          (適當的路徑名)

主要的()
{
        檔案 *key_fp;
        字符鍵[80];        (酌情調整)
        gid_t gid;
        uid_t uid;
        字元 *args[10];      (酌情調整)

        key_fp = fopen(KEY_FILE, "r");
        if (key_fp == NULL)
        {
                錯誤(KEY_FILE);
                退出(1);
        }
        (您要讀取和驗證的程式碼鑰匙
        fclose(key_fp);
        if (setenv("KEY", key, 1) != 0)
        {
                fprintf(stderr, "setenv() 出現問題。\n");
                退出(1);
        }
        gid = getgid();
        uid = getuid();
        // 使用
        // if (setresgid(gid, gid, gid) != 0 || setresuid(uid, uid, uid) != 0)
        // 如果它們可用;否則
        if (setregid(gid, gid) != 0 || setreuid(uid, uid) != 0)
        {
                fprintf(stderr, "刪除權限時出現問題。\n");
                退出(1);
        }
        args[0] = "腳本名稱";     (酌情調整)
        參數[1] = NULL;
        execv(腳本,參數);
        錯誤(腳本);
        退出(1);
}

定義KEY_FILE為包含金鑰的檔案的完整路徑名,並定義SCRIPT為包含腳本的檔案的完整路徑名。確保 John 具有對腳本的讀取權限,但沒有密鑰檔案的讀取權限,且他對任一路徑中的任何目錄都沒有寫入權限。透過設定該程式 setUID 和/或 setGID 來安排程式能夠讀取金鑰檔案。它將讀取金鑰,將其插入環境中,刪除權限,然後執行腳本。 (您可能需要修改上面的程式碼,以便將提供給程式的命令列參數傳遞給腳本。)

如上所述,該腳本將使用 John 的 UID 和 GID 運行,但金鑰位於環境中。在某些系統上,John 可以從或使用讀取腳本的環境。如果是這樣,讓腳本立即將金鑰複製到本機(非匯出)變數並取消設定變數可能會有所幫助。/proc/(pid_of_script)/environpsKEY

腳本將密鑰傳遞給程式可能是安全的

  • 透過管道(例如),printf "%s" (key_value) | (program)
  • 透過此處的文檔,或
  • 通過這裡的字串。

上面提到了透過環境傳遞價值的風險。避免將其作為命令行參數傳遞,因為這肯定可以被ps.

如果你想讓程式可以透過 運行sudo,你可能需要對 John 的 UID 和 GID 進行硬編碼,因為sudo設定了真實的 ID 和有效的 ID。

相關內容