
我想在 php 中開發一些腳本來呼叫以下命令;使用 exec() 函數
service network restart
crontab -u root /xyz/abc/fjs/crontab
ETC。
問題是 Apache 以 apache 使用者身分執行腳本(我在 CentOS 5 上),無論將 apache 新增到 Wheel 還是做好事、做壞事、做醜事 群組分配不運行命令(如上所述)。
以下是我的配置;
我的 /etc/sudoers
root ALL=(ALL) ALL
apache ALL=(ALL) NOPASSWD: ALL
%wheel ALL=(ALL) ALL
%wheel ALL=(ALL) NOPASSWD: ALL
由於我嘗試了 sudoer 和 httpd.conf 的組合,最近的 httpd.conf 看起來如下所示;
我的 httpd.conf
User apache
Group wheel
我的 PHP 腳本
exec("service network start", $a);
print_r($a);
exec("sudo -u root service network start", $a);
print_r($a);
輸出
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]
)
毫不奇怪,當我使用 apache 等類似用戶透過 ssh 呼叫重新啟動網路服務時,該命令成功執行。其全部內容是透過 HTTP 協定存取此類命令。我確信 cPanel/Plesk 之類的軟體確實使用了 sudoer 之類的東西,而我想做的基本上是可能的。但我需要你的幫助來了解我缺少哪一塊?
多謝!
答案1
如果你採用 troyengel 的解決方案,在根 cron 表中加入一個條目,然後稍微修改一下,你可能會得到一個可行的解決方案。
如果您絕對需要使用 apache 來發出介面重新啟動的訊號,為什麼不讓 PHP 建立一個充當標誌的文件,然後讓您的根 cronjob 每分鐘(或其他)運行一次檢查該標誌是否存在。如果存在,則重新啟動介面。如果沒有,那就去死吧。 (請記得讓 cronjob 在成功重新啟動介面後刪除該標誌)。
這實現了目標(重新啟動介面,從 apache/php 觸發)並解決了授予 Web/腳本服務根級別存取權限所涉及的所有可能問題。
答案2
您必須將它們編寫為 PHP 命令列驅動工具(確保透過 yum 安裝 php-cli 套件),然後直接在根 crontab 中執行它們,而不是以普通使用者的身分執行它們。您可能還想用基本的 bash (shell) 腳本編寫它,如果您只是透過 exec() 運行命令,那麼使用 php 就太過分了。
答案3
您應該使用 -- 呼叫需要以不同使用者身分執行的命令sudo
,然後sudoers
適當地設定設定文件,以便允許執行 PHP 腳本的使用者以其他使用者身分執行腳本。請參閱sudoers
(5) 以及之前大約十幾個有關 sudo 使用的問題。
答案4
您可以使用黏滯位元使 shell 腳本以 root 身分執行。然而,要做到這一點有點複雜。
但是,您不能只在 shell 腳本上設定 uid。您需要使用 C/C++ 建立一個常規可執行文件,它不會像 shell 腳本那樣呼叫解釋器,並讓它執行 shell 腳本。