2014-02-19 3 views
5

В проекте я работаю, есть некоторый код, который запускает длительный процесс с использованием sudo:Убийства подпроцесс началось через Суд

subprocess.Popen(['sudo', '/usr/bin/somecommand', ...]) 

Я хотел бы, чтобы очистить этот процесс, когда родитель выходы. В настоящее время подпроцесс продолжает работать, когда родительский выход (конечно, подключен к init).

Я не уверен в лучшем решении этой проблемы. Код ограничивается только запуском определенных команд через sudo, а предоставление полных полномочий для запуска sudo kill будет в лучшем случае отрывочным.

У меня нет открытой трубы для дочернего процесса, который я могу закрыть (дочерний процесс не читается из stdin), и я не могу изменить код дочернего процесса.

Есть ли какие-либо другие механизмы, которые могут работать в этой ситуации?

+0

Хороший вопрос.Я не думаю, что вы можете убить процесс, который больше не принадлежит пользователю. Я полагаю, из вашего примера, что вы настроили '/ etc/sudoers', чтобы разрешить запуск программы с sudo без пароля. Рассматривали ли вы то же самое для 'killall/usr/bin/somecommand'? – goncalopp

ответ

5

Прежде всего, я просто отвечаю на вопрос. Хотя я не думаю, что это хорошо, это то, о чем вы просили. Я бы обернул этот дочерний процесс в небольшую программу, которая может прослушивать stdin. Тогда вы можете sudo эту программу, и она сможет запустить процесс без sudo и будет знать его pid и иметь права, необходимые для его уничтожения, когда вы спросите его об этом через stdin.

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

Общие правила:

  1. Если вам нужно суперпользователя права, вы должны дать им очень родительского процесса.
  2. Если дочерний процесс должен выполнять привилегированную операцию, он просит процесс верхнего уровня сделать это для него.
  3. Процесс верхнего уровня должен быть как можно меньшим и сделать как можно меньше. Чем больше, тем больше дырок в безопасности создает.

Это то, что делают многие приложения. Первым примером, который приходит мне на ум, является веб-сервер Apache (по крайней мере, на * nix), который имеет небольшую программу верхнего уровня и предваренные рабочие программы, которые не запускаются как root/wheel/whatever-else-is-the-superuser- имя пользователя.

0

Это поднимет OSError: [Errno 1] Operation not permitted на последней строке:

p = subprocess.Popen(['sudo', '/usr/bin/somecommand', ...]) 
print p.stdout.read() 
p.terminate() 

Предполагая, что Sudo не будет запрашивать пароль, один обходной путь, чтобы сделать скрипт, который вызывает Судо ...

#!/bin/sh 
sudo /usr/bin/somecommand 

... и то сделайте это в Python:

p = subprocess.Popen("/path/to/script.sh", cwd="/path/to") 
print p.stdout.read() 
p.terminate() 
Смежные вопросы