Выполнение скрипта Python с правами root (seteuid vs c-wrapper)

У меня есть быстрая разовая задача в скрипте python, которую я хотел бы вызвать из Django (пользователь www), для этого потребуются привилегии root.

Сначала я думал, что смогу использовать Python os.seteuid() и установить бит setuid в скрипте, но потом понял, что мне нужно будет установить бит setuid в самом Python, что, я полагаю, большое, нет, нет. Из того, что я могу сказать, это также будет иметь место при использовании sudo, чего я действительно хотел бы избежать.

На данный момент я подумываю просто написать оболочку C, которая использует seteuid и вызывает мой скрипт python от имени root, передавая ему необходимые аргументы.

Это правильно или надо смотреть что-то другое?


person kwl34    schedule 03.10.2011    source источник
comment
Почему бы вам просто не выполнить его как внешний процесс, используя subprocess и sudo, хотя все в этом пахнет гнилью.   -  person Anders    schedule 03.10.2011
comment
Потому что это потребует разрешения www для запуска Python от имени пользователя root :(   -  person kwl34    schedule 03.10.2011
comment
Основная проблема здесь заключается в том, что setuid и общие операции sudo применяются не к отдельным скриптам Python, как к двоичному, а к самому интерпретатору Python.   -  person kwl34    schedule 03.10.2011


Ответы (3)


sudo не требует бита setuid на Python. Вы можете включить sudo только для одной команды, без аргументов:

 www          ALL=(ALL)       NOPASSWD:  /root/bin/reload-stuff.py ""

Это будет безопасно, если ваш скрипт не принимает никаких аргументов, не может быть переопределен пользователем www, а sudo выполняет «env_reset» (по умолчанию в большинстве дистрибутивов).

Вы можете принимать аргументы, но будьте очень осторожны с ними — не берите имена выходных файлов, убедитесь, что вы проверили все входные данные. В этом случае удалите «» в конце строки sudo.

person theamk    schedule 03.10.2011
comment
Интересный! Я собираюсь проверить это немедленно тогда. Однако мой сценарий принимает аргументы, хотя и простые. Как вы думаете, со мной все будет в порядке, пока мой скрипт на Python выполняет строгое сопоставление этих аргументов? - person kwl34; 03.10.2011
comment
да. Вы можете принимать агрумнты, если будете с ними осторожны. - person theamk; 03.10.2011
comment
ALL=(root), вероятно, предпочтительнее, чтобы ограничить запуск сценария только пользователем root, а не любым другим пользователем. Лучше ограничиться только тем, что вам нужно. - person CivFan; 01.10.2016
comment
@theamk Достаточно ли env_reset, чтобы пользователь не мог загружать свои собственные пакеты сайта и, таким образом, обманывать reload-stuff для запуска вредоносного кода? Меня особенно беспокоит virtualenv или PEP-370. - person gcscaglia; 21.03.2018
comment
env_reset установит HOME для целевого дома пользователя (например, /root) и очистит всю другую среду - так что да, virtualenvs будет игнорироваться, а сайт пользователя будет использоваться из дома root, что будет безопасным - person theamk; 02.04.2018

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

РЕДАКТИРОВАТЬ: использование оболочки с поддержкой setuid также удовлетворит концепцию разделения привилегий, хотя я рекомендую chroot веб-сервера и монтировать chrooted файловую систему nosuid (что помешает этому).

person knitti    schedule 03.10.2011
comment
Это то, что я предлагаю использовать бинарную оболочку C. Он предоставляет ограниченный интерфейс для определенных функций, к которым пользователю нужен доступ с повышенными привилегиями через seteuid(). - person kwl34; 03.10.2011
comment
Да, ты прав, так и будет. Я не рассматривал это, потому что я рекомендую chroot веб-серверов и монтировать к веб-серверу доступные файловые системы nosuid. - person knitti; 03.10.2011
comment
Я хотел бы порекомендовать sudo над C-оболочкой. Очень легко забыть очистить, скажем, PYTHONSTARTUP или какую-либо другую переменную env, но sudo с env_reset сделает это за вас. - person theamk; 03.10.2011

sudo позволяет ограничить аргументы, передаваемые программе. От man sudoers:

john           ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*

On the ALPHA machines, user john may su to anyone except root but
he is not allowed to specify any options to the su(1) command.

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

person Petr Viktorin    schedule 03.10.2011
comment
Я могу ошибаться, но для этого по-прежнему требуется предоставить пользователю www sudo root доступ к самому интерпретатору Python, и вы, по сути, используете парсер аргументов sudo только для того, чтобы разрешить запуск вашего скрипта. Это правильно? Если да, то будет ли легко также учитывать аргументы, передаваемые сценарию (ключ/значение)? - person kwl34; 03.10.2011
comment
Да, это правильно. И да, это должно быть легко, но я бы рекомендовал общаться через stdin/stdout. К сожалению, поскольку это секретный вопрос, альтернативы чтению man sudoers действительно нет. - person Petr Viktorin; 03.10.2011