Проблема: у меня есть скрипт, который периодически запускается через задание cron как корень, но я хочу дать людям возможность запускать его асинхронно через веб-страницу. (Сценарий будет написан так, чтобы гарантировать, что он не запускает перекрывающиеся экземпляры или что-то подобное.)
Мне не нужно, чтобы пользователи входили в систему или имели учетную запись, они просто нажимают кнопку, и, если сценарий готов к запуску, он запускается. Пользователи могут выбирать аргументы для сценария (сильно отфильтрованные как входные), но для простоты мы скажем, что у них просто есть кнопка, которую можно нажать.
В качестве простого теста я создал скрипт Python в cgi-bin. переключение его на root: root и последующее применение к нему "chmod ug +" не дало желаемых результатов: он все еще думает, что у него есть эффективная группа учетной записи веб-сервера ... из того, что я могу сказать, это не разрешается.
Я читал, что упаковка его с помощью скомпилированной программы cgi выполнит эту работу, поэтому я создал оболочку C, которая вызывает мой сценарий (его разрешения восстановлены до нормального) и дал исполняемому файлу права root и бит setuid. Который работал ... скрипт работал так, как будто его запустил root.
Мой главный вопрос: нормально ли это (необходимость в бинарной оболочке для выполнения работы) и является ли это безопасным способом сделать это? Это не актуально, но все же я хотел бы изучить передовой опыт.
В более широком смысле, я часто задаюсь вопросом, почему на практике скомпилированный двоичный файл пользуется большим доверием, чем сценарий? Я бы подумал, что вы доверяете файлу, который читается человеком, а не загадочным двоичным файлам. Если злоумышленник может редактировать файл, значит, у вас уже проблемы, тем более, если его нелегко изучить. Короче говоря, я ожидал, что все будет наоборот. Твои мысли?
Другой ответ, поскольку это совершенно другой (и гораздо более общий) подход. Можно возразить, что это канонический способ делать такие вещи :)
Поместите своего пользователя apache (как бы он ни был назван, я полагаю www-data
) в sudoers файл (с visudo
) с очень конкретной строкой, которая позволяет ему запускать только yourscript.py
и только с локальной машины (hostname
) без пароля. Что-то вроде этого:
www-data hostname=(root)NOPASSWD:/path/to/yourscript.py
Затем ваш сценарий CGI может запустить этот сценарий с вызова sudo /path/to/yourscript.py
.
Конечно, вы должны быть дополнительно уверены, что параметры, которые вы можете использовать для этого скрипта, полностью ограничены допустимыми значениями - оптимально как из сценария оболочки cgi, так и из yourscript.py
.
Самый простой (и довольно безопасный) способ ИМХО - косвенный: сделать так, чтобы веб-страница создавала файл где-нибудь, если пользователь нажимает кнопку, и изменяет ваш скрипт, чтобы он запускался только в том случае, если файл существует, а затем удалите его. Затем каждую минуту запускайте этот скрипт из задания cron. Вы даже можете использовать этот файл для предоставления аргументов сценарию (что, конечно, требует особого внимания).
Это оставляет место для улучшения (одновременные клики нескольких пользователей являются одним), но я много раз использовал этот подход для очистки и одноразовых действий.
Прежде всего: не делайте этого или, по крайней мере, не позволяйте передавать какие-либо параметры из Интернета в ваше приложение, работающее с root-правами.
Теперь к вашему актуальному вопросу: когда вы пишете скрипт (Python в вашем случае), он запускается интерпретатором. Итак, чтобы иметь возможность запускать скрипт от имени пользователя root, вам необходимо установить интерпретатор python suid-root, но вы действительно не хотите этого делать. Это связано с тем, что ваш сценарий не является исполняемым файлом как таковой, а просто набором правил для интерпретатора. Когда вы завершаете свой скрипт двоичным исполняемым файлом, теперь у вас снова есть исполняемый файл, который получает права root, и интерпретатор python, вызываемый из исполняемого файла, также имеет root. Более подробную информацию об этом можно найти в Невозможно установить UID в сценариях оболочки и http://www.diablotin.com/librairie/networking/puis/ch05_05.htm
Тем не менее, вызов сценария через sudo, как предложил @SvenW, должен работать нормально.