2014-02-19 6 views
5

In einem Projekt an dem ich arbeite, gibt es einige Codes, der einen lang andauernden Prozess sudo mit anläuft:Töten ein subProzess über sudo gestartet

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

Ich mag diesen Prozess bereinigen, wenn die Eltern beendet. Momentan läuft der Unterprozess weiter, wenn der Elternteil beendet wird (natürlich wieder an init angehängt).

Ich bin mir nicht sicher, die beste Lösung für dieses Problem. Der Code ist darauf beschränkt, nur bestimmte Befehle über sudo auszuführen, und das Gewähren der umfassenden Berechtigung zum Ausführen von sudo kill wäre bestenfalls skizzenhaft.

Ich habe keine offene Pipe für den untergeordneten Prozess, den ich schließen kann (der untergeordnete Prozess liest nicht von stdin), und ich kann den Code des untergeordneten Prozesses nicht ändern.

Gibt es andere Mechanismen, die in dieser Situation funktionieren könnten?

+0

Gute Frage.Ich glaube nicht, dass Sie einen Prozess beenden können, der (nicht mehr) Eigentum des Benutzers ist. Ich gehe davon aus, dass Sie '/ etc/sudoers' so konfiguriert haben, dass das Programm mit sudo ohne Passwort ausgeführt werden kann. Haben Sie darüber nachgedacht, das gleiche für 'killall/usr/bin/somecommand' zu tun? – goncalopp

Antwort

5

Zuerst beantworte ich nur die Frage. Obwohl ich es nicht gut finde, ist es das, wonach du gefragt hast. Ich würde diesen Kindprozess in ein kleines Programm einbinden, das auf stdin hören kann. Dann können Sie sudo dieses Programm, und es wird in der Lage sein, den Prozess ohne sudo zu laufen, und wird seine pid kennen und die Rechte haben, um den Prozess zu töten, wenn Sie es durch stdin bitten, dies zu tun.

Im Allgemeinen bedeutet eine solche Situation sudo ohne Passwort und schlechte Sicherheit. Die gebräuchlichste Technik besteht darin, die Berechtigungen des Programms zu verringern, anstatt sie zu erhöhen. In diesem Fall sollten Sie ein Runner-Programm erstellen, das vom Superuser gestartet wird, dann startet es Ihr Hauptprogramm mit einer Verringerung der Berechtigungen und wartet auf die Kommunikation zwischen den Pipes. Wenn es notwendig ist, einen Befehl auszuführen, teilt Ihr Hauptprogramm dies dem Runner-Programm mit, und das Runner-Programm führt den Job aus. Wenn es notwendig ist, den Befehl zu beenden, teilen Sie dies über die Pipe erneut einem Runner-Programm mit.

Die gemeinsamen Regeln sind:

  1. Wenn Sie Superuser-Rechte benötigen, können Sie sie mit dem sehr übergeordneten Prozess geben sollte.
  2. Wenn ein untergeordneter Prozess eine privilegierte Operation ausführen muss, fordert er den übergeordneten Prozess auf, dies für ihn auszuführen.
  3. Der Top-Level-Prozess sollte so klein wie möglich gehalten werden und so wenig wie möglich machen. Je größer es ist, desto mehr Sicherheitslöcher entstehen.

Das ist, was viele Anwendungen tun. Das erste Beispiel, das mir in den Sinn kommt, ist der Apache-Webserver (zumindest auf * nix), der ein kleines Top-Level-Programm und vorgekündigte Arbeitsprogramme hat, die nicht als root/wheel/was auch immer-sonst-ist-der-Superuser ausgeführt wird. Nutzername.

0

Diese OSError: [Errno 1] Operation not permitted in der letzten Zeile erhöhen wird:

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

sudo Angenommen wird nach einem Passwort nicht fragen, ist eine Umgehung ein Shell-Skript zu machen, die sudo ruft ...

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

... und dann machen Sie das in Python:

p = subprocess.Popen("/path/to/script.sh", cwd="/path/to") 
print p.stdout.read() 
p.terminate() 
Verwandte Themen