Может ли мой скрипт на Python различать, запускался ли он от имени пользователя root или через sudo? - PullRequest
0 голосов
/ 30 мая 2018
[root@hostname ~]# python script.py                  # allow this

[user@hostname ~]$ sudo python script.py             # deny this
[user@hostname ~]$ sudo -E python script.py          # deny this
[user@hostname ~]$ sudo PATH=$PATH python script.py  # deny this
[user@hostname ~]$ python script.py                  # kindly refuse this

Я пытаюсь добиться описанного выше поведения. Читайте дальше, если вам небезразлично, почему этого примера недостаточно.Извините за острый язык, но большинство моих вопросов о Stack Exchange возвращают враждебные вопросы вместо ответов.

Этот вопрос возникает из-за требования администратора запустить мой скрипт, но природа сценария требует root 'переменные окружения (а не sudo).

Я провел это тщательное исследование ... ниже - из этого ответа

if os.geteuid() == 0:
    pass  # sufficient to determine if elevated privileges

Но потом я начал нуждаться в доступе PATH внутри моего скрипта.Я заметил, что

sudo -E env | grep PATH; env | grep PATH

печатает разные PATH значения.Я обнаружил, что это из-за политики безопасности на PATH.Я также обнаружил, что обходной путь к PATH равен sudo PATH=$PATH ...

Однако это не единственная переменная среды, защищенная политикой, и с этой точки зрения, зачем выдвигать это перечисление переменных среды напользователь сценария?Кажется, что требование root явно является лучшим подходом, и просто предупредите администратора, чтобы использовать root явно изнутри скрипта.

Есть ли такой способ различать root и * 1032?* с Python?

Ответы [ 3 ]

0 голосов
/ 31 мая 2018

Вы получите "враждебные вопросы", потому что предпосылка вашей проблемы не имеет большого смысла.В общем, если команда может быть запущена от имени пользователя root с помощью sudo, то не должно иметь значения, была ли она запущена с помощью sudo (или runas и т. Д.) Или каким-либо другим механизмом, для которого UID имеет значение rootтакой как интерактивный вход в систему как пользователь root.Вы не должны требовать, чтобы запуск программы был основан на интерактивном входе в систему в качестве учетной записи пользователя root, а не через программу setuid, такую ​​как sudo или вашу программу, если она была setuid root.

Дешевое и грязное решениечтобы интерактивный вход в систему root задавал уникальную переменную env, которая вряд ли будет установлена ​​при запуске вашей программы через sudo.Это, однако, очевидно, легко подделать, так что если вы делаете это для безопасности, то такой подход неприемлем.

0 голосов
/ 31 мая 2018

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

[user@hostname ~]$ sudo python
>>> import os
>>> os.environ["SUDO_UID"]  # UID of user running sudo
'uid'

И когда вы вошли в систему как root ...

[root@hostname ~]# python
>>> import os
>>> try:
...     uid = os.environ["SUDO_UID"]
        raise AssertionError("Ran with sudo")
... except KeyError, e:
...     ...  # SUDO_UID, SUDO_USER, etc. not set without sudo

Я также нашел способ доступа к root PATH, просто работающий с sudo.

path = os.popen("su - -c env | grep ^PATH= | cut -d'=' -f2-").read().strip()

Я думаюМне нравится это решение лучше, чем полагаться на то, как выполняется мой скрипт.

0 голосов
/ 30 мая 2018

Используйте модуль подпроцесса для запуска команд и проверки вывода:

from subprocess import check_output

uid = check_output(['bash', '-c', 'echo $UID']).decode().strip()
if uid != '0':
    sys.exit()  # or return

или

user = check_output(['whoami']).decode().strip()
if user != 'root':
    sys.exit()  # or return

Похоже, что кроме проверки $PATH, root и sudo неразличимы.

...