Какой самый безопасный способ запустить процесс корневого уровня через cgi на сервере Apache?
Проблема: у меня есть скрипт, который периодически запускается через задание cron от имени пользователя root, но я хочу дать людям возможность также запускать его асинхронно через веб-страницу. (Сценарий будет написан, чтобы гарантировать, что он не запускает перекрывающиеся экземпляры или тому подобное.)
Мне не нужно, чтобы пользователи входили в систему или имели учетную запись, они просто нажимали кнопку и, если скрипт готов к запуску, он запустится. Пользователи могут выбирать аргументы для скрипта (сильно фильтруются как входные данные), но для простоты мы скажем, что у них просто есть кнопка, которую нужно нажать.
В качестве простого теста я создал скрипт Python в cgi-bin. добавление его в root:root и последующее применение к нему "chmod ug+" не дали желаемых результатов: он по-прежнему считает, что у него есть эффективная группа учетной записи веб-сервера... из того, что я могу сказать, это не позволил.
Я прочитал, что обертывание скомпилированной программой cgi сделает эту работу, поэтому я создал оболочку C, которая вызывает мой сценарий (его разрешения восстановлены в обычном режиме) и дает исполняемому файлу права root и бит setuid. Это сработало... скрипт работал так, как будто его запускал root.
Мой главный вопрос: нормально ли это (нужно, чтобы бинарная оболочка выполняла работу), и это безопасный способ сделать это? Это не мир, но я бы хотел изучить лучшие практики.
В более широком смысле, я часто задаюсь вопросом, почему скомпилированный двоичный файл является более "доверенным", чем сценарий на практике? Я думаю, вы доверяете файлу, который читается человеком через загадочный двоичный файл. Если злоумышленник может отредактировать файл, значит, у вас уже есть проблемы, тем более, что его трудно проверить. Короче говоря, я ожидал бы, что на этой основе все будет наоборот. Твои мысли?
3 ответа
Прежде всего: не делайте этого или, по крайней мере, не допускайте передачи каких-либо параметров из Интернета в ваше корневое приложение.
Теперь к вашему актуальному вопросу: когда вы пишете скрипт (Python в вашем случае), он исполняется интерпретатором. Таким образом, чтобы иметь возможность запускать скрипт от имени пользователя root, вам нужно установить интерпретатор Python suid-root, но вы действительно не хотите этого делать. Это потому, что ваш скрипт не является исполняемым файлом как таковым, а представляет собой просто набор правил для интерпретатора. Когда вы оборачиваете свой сценарий двоичным исполняемым файлом, теперь у вас снова есть исполняемый файл, который получает права root, а интерпретатор python, вызываемый из исполняемого файла, также имеет root. Дополнительную информацию об этом можно найти в разделе "Невозможно установить UID для сценариев оболочки" и http://www.diablotin.com/librairie/networking/puis/ch05_05.htm
Тем не менее, вызов сценария через sudo, как предложил @SvenW, должен работать нормально.
Другой ответ, поскольку это совершенно другой (и гораздо более общий) подход. Можно утверждать, что это канонический способ делать такие вещи:)
Поставьте своего пользователя 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 каждую минуту. Вы даже можете использовать этот файл для предоставления аргументов скрипту (который, конечно, требует особого внимания).
Это оставляет место для улучшений (одновременное нажатие несколькими пользователями), но я много раз использовал этот подход для очистки и разовых действий.