
Ich möchte einige Skripte in PHP entwickeln, die folgende Befehle aufrufen; mit der Funktion exec()
service network restart
crontab -u root /xyz/abc/fjs/crontab
usw.
Das Problem ist, dass Apache das Skript als Apache-Benutzer ausführt (ich verwende CentOS 5), unabhängig davon, ob Apache in Wheel oderGutes tun, das Schlechte und das Hässliche Die Gruppenzuweisung führt keine Befehle aus (wie oben erwähnt).
Nachfolgend sind meine Konfigurationen aufgeführt:
Meine /etc/sudoers
root ALL=(ALL) ALL
apache ALL=(ALL) NOPASSWD: ALL
%wheel ALL=(ALL) ALL
%wheel ALL=(ALL) NOPASSWD: ALL
Nachdem ich einige Kombinationen mit sudoer und httpd.conf ausprobiert habe, sieht die aktuelle httpd.conf ungefähr wie folgt aus:
meine httpd.conf
User apache
Group wheel
mein PHP-Skript
exec("service network start", $a);
print_r($a);
exec("sudo -u root service network start", $a);
print_r($a);
Ausgabe
Array
(
[0] => Bringing up loopback interface: [FAILED]
[1] => Bringing up interface eth0: [FAILED]
[2] => Bringing up interface eth0_1: [FAILED]
[3] => Bringing up interface eth1: [FAILED]
)
Array
(
[0] => Bringing up loopback interface: [FAILED]
[1] => Bringing up interface eth0: [FAILED]
[2] => Bringing up interface eth0_1: [FAILED]
[3] => Bringing up interface eth1: [FAILED]
)
Es ist keine Überraschung, dass der Befehl erfolgreich ausgeführt wird, wenn ich „Restart Network Services“ über SSH aufrufe und dabei einen ähnlichen Benutzer wie Apache verwende. Es geht darum, solche Befehle über das HTTP-Protokoll aufzurufen. Ich bin sicher, dass Software wie cPanel/Plesk so etwas wie sudoer oder so etwas verwendet und dass das, was ich versuche, grundsätzlich möglich ist. Aber ich brauche Ihre Hilfe, um herauszufinden, welches Teil mir fehlt.
Vielen Dank!
Antwort1
Wenn Sie Troyengels Lösung übernehmen, bei der ein Eintrag in die Root-Cron-Tabelle eingefügt wird, und diese dann ein wenig modifizieren, haben Sie möglicherweise eine praktikable Lösung.
Wenn Sie unbedingt Apache verwenden müssen, um einen Neustart der Schnittstelle zu signalisieren, warum lassen Sie PHP dann nicht eine Datei erstellen, die als Flag fungiert, und lassen Sie dann Ihren Root-Cronjob, der jede Minute (oder so oft) ausgeführt wird, die Existenz dieses Flags prüfen. Wenn es existiert, starten Sie die Schnittstellen neu. Wenn nicht, beenden Sie den Vorgang. (Denken Sie daran, den Cronjob das Flag entfernen zu lassen, nachdem er die Schnittstelle erfolgreich neu gestartet hat.)
Dadurch wird das Ziel erreicht (Neustart der Schnittstelle, ausgelöst von Apache/PHP) und alle möglichen Probleme werden umgangen, die mit der Gewährung des Root-Zugriffs auf einen Web-/Skriptdienst verbunden sind.
Antwort2
Sie müssen diese als PHP-Befehlszeilentools schreiben (stellen Sie sicher, dass das Paket php-cli über yum installiert ist) und sie dann direkt in der Root-Crontab ausführen, nicht als normaler Benutzer. Sie möchten es wahrscheinlich auch in einem einfachen Bash-Skript (Shell) schreiben, die Verwendung von PHP wäre übertrieben, wenn Sie Befehle nur über exec() ausführen.
Antwort3
Sie sollten die Befehle, die Sie ausführen müssen, als anderer Benutzer aufrufen sudo
und dann die sudoers
Konfigurationsdatei entsprechend einrichten, sodass der Benutzer, der das PHP-Skript ausführt, die Skripte als anderer Benutzer ausführen darf. Siehe sudoers
(5) und etwa ein Dutzend vorherige Fragen zur Verwendung von sudo.
Antwort4
Sie könnten das Sticky-Bit verwenden, um ein Shell-Skript als Root auszuführen. Dies ist jedoch etwas komplizierter.
Sie können jedoch nicht einfach setuid für ein Shell-Skript festlegen. Sie müssen eine reguläre ausführbare Datei erstellen, beispielsweise in C/C++, die keinen Interpreter aufruft, wie dies bei Shell-Skripten der Fall ist, und diese das Shell-Skript ausführen lassen.