Откажитесь от привилегий root для определенных операций в Python
В моем Python script я выполняю несколько операций, требующих привилегий root. Я также создаю и записываю файлы, которые я не хочу использовать исключительно от root, но от пользователя, который запускает мой script.
Обычно я запускаю свой script с помощью sudo
. Есть ли способ сделать это?
Ответы
Ответ 1
Вы можете переключаться между uid с помощью os.seteuid()
. Это отличается от os.setuid()
тем, что вы можете вернуться к привилегии root, когда они вам понадобятся.
Например, запустите в качестве пользователя root:
import os
open('file1', 'wc')
# switch to userid 501
os.seteuid(501)
open('file2', 'wc')
# switch back to root
os.seteuid(0)
open('file3', 'wc')
Это создает file1
и file3
как root, но file2
как пользователь с uid 501.
Если вы хотите определить, какой пользователь вызывает ваш script, sudo
устанавливает две переменные среды:
SUDO_USER
SUDO_UID
Соответственно имя пользователя и uid пользователя, который вызвал sudo
. Таким образом, вы можете использовать int(os.environ['SUDO_UID'])
для использования с os.seteuid()
.
Ответ 2
http://linux.die.net/man/8/sudo quote:
Реальные и эффективные uid и gid настроены так, чтобы они соответствовали целевому пользователю
Итак, ваш единственный способ узнать, какой пользователь использовать, - это прочитать целевого пользователя либо из конфигурационного файла, либо из опции cmdline, либо каким-то образом из эвристического предположения.
Хорошей идеей является так называемое освобождение прав: Начните с привилегий root, затем сделайте то, за что вы их запустили. Затем стать менее привилегированным пользователем.
Для этого вы должны использовать модуль os:
http://docs.python.org/2/library/os.html#os.setuid
Ответ 3
Я обнаружил, что использование os.seteuid и os.setegid фактически не отменяет привилегии root. После их вызова я все еще мог делать то, что требовало привилегий от root. Решение, которое я нашел, что работало, заключалось в том, чтобы вместо os.setresuid и os.setresgid:
sudo_uid = int(os.getenv("SUDO_UID"))
sudo_gid = int(os.getenv("SUDO_GID"))
# drop root privileges
os.setresgid(sudo_gid, sudo_gid, -1)
os.setresuid(sudo_uid, sudo_uid, -1)
subprocess.call("mkdir /foo1", shell = True) # should fail
# regain root privileges
os.setresgid(0, 0, -1)
os.setresuid(0, 0, -1)
subprocess.call("mkdir /foo2", shell = True) # should succeed