Учитывая, что у пользователя root есть некоторые учетные данные (например, ключ API), установленные в переменной среды, и учитывая непривилегированного пользователя John, как я могу позволить John выполнить скрипт, которыйиспользуетуказанный ключ API без риска раскрытия его значения Джону?
решение1
Вопрос, кажется, немного неконкретен.
Вопрос,как таковой, говорит о получении значения из «переменной среды суперпользователя» (т. е. «переменной среды root»). Я даже не уверен, что это значит. Вы говорите, что Джон должен получить значение из среды другого пользователя, который вошел в систему как «root» или который работает как «root» через
su
илиsudo
? Или вы говорите о средепроцесс (вероятно, фоновый процесс), запущенный от имени «root»?Но, какие бы детали вы ни имели в виду, это звучит как ключ очень динамичный и эфемерный. Поскольку я не понимаю, что это значит, я не скажу, что это невозможно, но это звучит сложно.
Но затем в комментарии вы говорите о том, чтобы сделать скрипт исполняемым, но не читаемым. Это говорит о том, что вы готовы жестко закодировать ключ в скрипте, пока пользователи без прав root не смогут его прочитать. Это говорит о том, что ключ очень статичен и меняется так редко, что вы готовы изменять скрипт каждый раз, когда ключ меняется.
У&Лесть длинная ветка на эту самую тему: Может ли скрипт быть исполняемым, но нечитаемым? К сожалению, большинство ответов отрицательные или представляют собой отклонения, диверсии или обходные пути, некоторые из которых работают лучше, чем другие. Например,Сантана предлагаетсоздание записи,
/etc/sudoers
которая позволяет Джонубегатьскрипт с повышенными разрешениями, не имея возможности читать его как самого себя. Но, если скрипту не нужны повышенные разрешения (кроме получения ключа), вы не хотите запускать его с повышенными разрешениями.Однако, наэтот связанный вопрос (на Super User), я представляю неуклюжий способ сделать скрипт исполняемым, но нечитаемым, обернув его в программу на языке C. Как я объясняю в том ответе, этот метод не является абсолютно надежным; есть способы, которыми информация может утечь.
Наиболее разумная / правдоподобная интерпретация, IMHO, заключается в том, что ключ хранится в файле, который Джон не может прочитать. Традиционный способ реализации таких соглашений — 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"); если (key_fp == NULL) { ошибка(KEY_FILE); выход(1); } (ваш код для чтения и проверки)ключ) fclose(key_fp); если (setenv("КЛЮЧ", ключ, 1) != 0) { fprintf(stderr, "Проблема с setenv().\n"); выход(1); } gid = getgid(); uid = getuid(); // использовать // если (setresgid(gid, gid, gid) != 0 || setresuid(uid, uid, uid) != 0) // если они доступны; в противном случае если (setregid(gid, gid) != 0 || setreuid(uid, uid) != 0) { fprintf(stderr, "Проблема со сбросом привилегий.\n"); выход(1); } args[0] = "имя_скрипта"; (отрегулируйте по мере необходимости) args[1] = NULL; execv(SCRIPT, args); ошибка(СКРИПТ); выход(1); }
Определите KEY_FILE
полный путь к файлу, содержащему ключ, и определите SCRIPT
полный путь к файлу, содержащему скрипт. Убедитесь, что у Джона есть доступ на чтение к скрипту, но не к файлу ключа, и что у него нет доступа на запись в любой из каталогов в любом из путей. Сделайте так, чтобы эта программа могла читать файл ключа, сделав его setUID и/или setGID. Она прочитает ключ, вставит его в среду, сбросит привилегии и выполнит скрипт. (Возможно, вы захотите изменить приведенный выше код так, чтобы аргументы командной строки, заданные программе, передавались скрипту.)
Как указано выше, скрипт будет запущен с UID и GID Джона, но с ключом в среде. В некоторых системах Джон может прочитать среду скрипта из или с помощью . Если это так, может быть полезно, чтобы скрипт немедленно скопировал ключ в локальную (неэкспортируемую) переменную и отменил установку переменной./proc/(pid_of_script)/environ
ps
KEY
Вероятно, скрипту будет безопасно передать ключ программе.
- через трубу (например, ),
printf "%s" (key_value) | (program)
- через документ здесь, или
- через строку here.
Риски передачи значения через среду упомянуты выше. Избегайте передачи его как параметра командной строки, так как это определенно может быть замечено ps
.
Если вы хотите, чтобы программа запускалась через sudo
, вам может потребоваться жестко закодировать UID и GID Джона, поскольку sudo
задаются как реальные идентификаторы, так и эффективные.