Запустите системную команду Linux от имени суперпользователя, используя скрипт Python.

На моей машине установлен постфикс, и я программно обновляю virtual_alias на лету (используя python) (в каком-то действии). Как только я обновляю запись в /etc/postfix/virtual_alias, я запускаю команду:

sudo /usr/sbin/postmap /etc/postfix/virtual_alias 2>>/work/postfix_valias_errorfile
Но я получаю сообщение об ошибке:
sudo: sorry, you must have a tty to run sudo

Я хочу запустить упомянутую команду sudo нечеловеческим способом (это означает, что я запускаю эту системную команду из скрипта Python). Итак, как мне запустить эту команду программно?


person None-da    schedule 24.02.2009    source источник


Ответы (6)


Вы можете либо запустить свой скрипт python от имени root, тогда вам не нужно будет добавлять привилегию для перезагрузки постфикса.

Или вы можете настроить sudo так, чтобы пароль для /etc/init.d/postfix не требовался.

Конфигурация sudo (через visudo) позволяет NOPASSWD: разрешить команду без пароля. См. http://www.sudo.ws/sudo/man/sudoers.html#nopasswd_and_passwd

<username>  ALL = NOPASSWD: /etc/init.d/postfix

или что-то подобное.

person Douglas Leeder    schedule 24.02.2009
comment
Дуглас! Как настроить sudo так, чтобы пароль не требовался только для этого скрипта (/etc/init.d/postfix reload)? - person None-da; 24.02.2009
comment
Создание sudo без пароля является предметом sudoers, и вне рамок вопроса программирования sudo можно настроить для каждой программы для каждого пользователя. - person myroslav; 24.02.2009

#include <unistd.h>
#include <stdlib.h>

// gcc -o reload_postfix reload_postfix.c
// chown root reload_postfix
// chmod +s reload_postfix

int main( int argc, char **argv ) {
    setuid( geteuid() );
    system("/etc/init.d/postifx reload");
}

Оберните свою команду в программу с setuid. Это позволит любому пользователю перезапустить postfix. Конечно, вы можете дополнительно ограничить разрешение на выполнение для определенных групп.

person codelogic    schedule 24.02.2009
comment
Я говорил о скрипте Python! - person None-da; 24.02.2009
comment
Поскольку вы вносите изменения в конфигурацию postfix, я предположил, что это для сервера, и что безопасность будет гораздо важнее, чем использование определенного языка программирования. Вы не можете использовать сценарии setuid() из-за того, как они выполняются, отсюда и это решение (очень распространенное). - person codelogic; 24.02.2009
comment
sudo считается лучшим способом получить привилегии root. Он меняет представление о распределении битов setuid по файловой системе на один исполняемый файл, способный выполнять эту функциональность (sudo) с центральной конфигурацией, более гибкими политиками с возможностью аудита использования. - person myroslav; 25.02.2009

Чтобы ответить на ошибку: «sudo: извините, у вас должен быть tty для запуска sudo», у нас есть параметр «Требование по умолчанию» в файле sudoers. Я попытался прокомментировать это, и это сработало: D.

person None-da    schedule 06.03.2009
comment
Другой способ — поставить восклицательный знак перед requiretty, т. е. по умолчанию !requiretty. Таким образом, любой, кто читает файл sudoers, может увидеть, что вы явно разрешаете sudo без tty. - person Ian Ellis; 13.02.2016

import os
os.popen("sudo -S /etc/init.d/postifx reload", 'w').write("yourpassword")

Это, конечно, почти всегда не очень хорошая идея, так как пароль находится в виде обычного текста.

person CTT    schedule 24.02.2009
comment
Пароль sudo в виде открытого текста — УЖАСНАЯ идея, есть гораздо более безопасные способы. Бит setuid специально решает эту проблему. - person codelogic; 24.02.2009
comment
Простой текстовый пароль? Эй! Установите NOPASSWD в /etc/sudoers для пользователя или группы, чтобы не нужно было указывать пароль для sudo. - person Ian Ellis; 13.02.2016
comment
Это не такая уж плохая идея, если вы хотите быстрое и грязное решение на своем персональном компьютере. Это просто плохо в производственной среде. - person answerSeeker; 05.01.2017

если вы собираетесь сделать это на питоне, вам нужно просто сделать следующее:

напишите эту команду перед строкой, которую вы называете командой оболочки

os.setuid(os.geteuid())

затем вы вызываете команду оболочки без префикса «sudo»

person torkashvan    schedule 17.02.2013

См. StackLick.

Вам нужно предоставить пользователю возможность запускать команду sudo без пароля.

person M SH GOL    schedule 11.10.2018