1

Учитывая, что у пользователя root есть некоторые учетные данные (скажем, ключ API), заданные в переменной среды, и при наличии непривилегированного пользователя John, как я могу позволить Джону выполнить сценарий, который использует указанный ключ API, без риска утечки его значения Джону ?

1 ответ1

2

Вопрос кажется немного не сфокусированным.

  • Вопрос сам по себе говорит о получении значения из «переменной среды суперпользователя» (т. Е. «Корневой переменной среды»).  Я даже не уверен, что это значит.  Вы говорите, что Джон должен получить значение из среды (другого) пользователя, вошедшего в систему как «root», или который работает как «root» через su или sudo?  Или вы говорите о среде процесса (возможно, фонового), выполняющегося от имени пользователя root?

    Но, какие бы детали вы ни имели в виду, звучит так, будто ключ очень динамичный и эфемерный.  Поскольку я не понимаю, что это значит, я не скажу, что это невозможно, но звучит сложно.

  • Но затем в комментарии вы говорите о создании сценария исполняемого, но не читаемого.  Это говорит о том, что вы готовы иметь ключ, жестко запрограммированный в сценарии, если пользователи без прав root не могут его прочитать.  Это говорит о том, что ключ очень статичен и меняется настолько редко, что вы готовы изменять скрипт каждый раз, когда ключ меняется.

    U & L имеет длинную тему на эту тему:может ли скрипт быть исполняемым, но не читаемым?  К сожалению, большинство ответов отрицательные или являются отклонениями, отклонениями или обходными путями, некоторые из которых работают лучше, чем другие.  Например, Сантана предлагает создать запись в /etc/sudoers которая позволит Джону запускать сценарий с повышенными разрешениями, но при этом не сможет читать его самому.  Но если сценарию не нужны повышенные разрешения (кроме получения ключа), вы не хотите запускать его с повышенными разрешениями.

    Однако в этом связанном вопросе (о суперпользователе ) я представляю хитрый способ сделать скрипт исполняемым, но не читаемым, обернув его в программу на Си.  Как я объясняю в этом ответе, эта техника не является надежной; Есть способы, которыми информация может просочиться.

  • ИМХО, наиболее разумная / правдоподобная интерпретация заключается в том, что ключ хранится в файле, который Джон не может прочитать.  Традиционным способом реализации таких соглашений является setUID и / или setGID. (sudo также полезно.)

Вот пример того, как это сделать.  Напишите программу на C, например:

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

#define KEY_FILE        (appropriate pathname)
#define SCRIPT          (appropriate pathname)

main()
{
        FILE    *key_fp;
        char    key[80];        (adjust as appropriate)
        gid_t   gid;
        uid_t   uid;
        char    *args[10];      (adjust as appropriate)

        key_fp = fopen(KEY_FILE, "r");
        if (key_fp == NULL)
        {
                perror(KEY_FILE);
                exit(1);
        }
        (your code to read and validate key)
        fclose(key_fp);
        if (setenv("KEY", key, 1) != 0)
        {
                fprintf(stderr, "Problem with setenv().\n");
                exit(1);
        }
        gid = getgid();
        uid = getuid();
        // use
        //      if (setresgid(gid, gid, gid) != 0  ||  setresuid(uid, uid, uid) != 0)
        // if they’re available; otherwise
        if (setregid(gid, gid) != 0  ||  setreuid(uid, uid) != 0)
        {
                fprintf(stderr, "Problem dropping privileges.\n");
                exit(1);
        }
        args[0] = "scriptname";     (adjust as appropriate)
        args[1] = NULL;
        execv(SCRIPT, args);
        perror(SCRIPT);
        exit(1);
}

Определите KEY_FILE для полного пути к файлу, который содержит ключ, и задайте SCRIPT для полного пути к файлу, который содержит скрипт.  Убедитесь, что у Джона есть доступ на чтение к сценарию, но не к файлу ключа, и что у него нет прав на запись ни в один из каталогов в любом из путей.  Сделайте так, чтобы эта программа могла читать файл ключа, задав для него setUID и / или setGID. Он прочитает ключ, вставит его в среду, сбросит привилегии и выполнит скрипт.  (Вы можете захотеть изменить приведенный выше код, чтобы аргументы командной строки, передаваемые программе, передавались в сценарий.)

Как указано выше, сценарий будет выполняться с UID и GID Джона, но с ключом в среде.  В некоторых системах Джон может читать среду сценария из /proc/(pid_of_script)/environ или с помощью ps .  Если это так, может быть полезно, чтобы скрипт немедленно скопировал ключ в локальную (не экспортируемую) переменную и сбросил переменную KEY .

Вероятно, для сценария будет безопасно передать ключ программе

  • через канал (например, printf "%s" (key_value) | (program)),
  • через здесь документ, или
  • через строку здесь.

Риски передачи ценности через окружающую среду упомянуты выше.  Избегайте передачи его в качестве параметра командной строки, так как это определенно может быть видно по ps .

Если вы хотите, чтобы программа работала через sudo , вам может понадобиться жестко кодировать UID и GID Джона, потому что sudo устанавливает как действительные, так и действительные идентификаторы.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .