2010-11-12 250 views
5

如何允許PHP腳本使用root權限執行bash腳本?允許PHP使用root權限執行bash腳本

比方說,有一個PHP腳本...

<?php 
// location: /var/www/script.php 
exec("bash /var/scripts/test.sh"); // "sudo bash ..." does not work 
?> 

和bash腳本...

#!/bin/bash 
# location: /var/scripts/test.sh 
sudo mkdir /test 

當然PHP和Apache不應以root身份運行,並在只有最好的腳本可以用root權限執行。有任何想法嗎?

最好的問候, 神保

+4

爲什麼你需要腳本以root權限運行?您可以通過Apache正在運行的用戶更改其訪問的資源是否可讀(並且必要時可寫)? – meagar 2010-11-12 19:11:36

+0

不,我想執行'git pull'和一些'a2dissite' /'a2ensite'。 – Jimbo 2010-11-12 19:13:49

回答

6

任何基於PHP的解決方案,在鏈的某個時刻給root用戶權限是危險的:與訪問PHP用戶的攻擊者可以獲取root用戶,那就是從安全角度來看,這是不能接受的。

我自己從來沒有實現過這個,但我會建議我建議的內容here:使用root權限的腳本/ cron作業頻繁地掃描PHP腳本中某個位置的某個位置,以完成工作 - for例如,具有特定名稱的文件或作業數據庫中的條目。

如果發現該文件存在,則根腳本會執行其操作並再次刪除該文件。

如果您的PHP腳本不需要根腳本的直接響應,我認爲這將是最好的方式。 (當然,根腳本將狀態消息寫入文件也可以方便響應)。

只要您嚴格限制PHP可以爲根腳本編寫什麼類型的作業,這是一個水密解決方案,因爲它不會讓root用戶進入PHP的業務。

+0

我目前正在運行此解決方案。我想知道是否有像腳本/ crontab那樣安全的解決方案,但是更快,更高效並且允許直接響應。就像打多米諾骨牌一樣。 – Jimbo 2010-11-12 19:20:50

+0

@Jimbo - 你的意思是運行php + apache比shell命令更快嗎?或者你的手段更方便? – ajreal 2010-11-12 19:24:52

+0

不,我的意思是沒有等到cron工作開始的時候。 – Jimbo 2010-11-12 19:33:50

1

您可能不需要以root身份運行PHP或Apache。如果你能控制你的服務器,你可以使用一個叫做suPHP的Apache模塊,並且指定你想運行Apache的用戶爲配置中的php腳本。您可以逐個站點地完成此操作,因此您只需要在特定域上運行suPHP腳本即可。我缺乏專業知識來就如何安裝它提供建議,但我有我們的專用服務器公司爲我做這件事,以允許github post-receive hook在我的開發服務器上調用腳本來觸發對開發服務器的git pull時間有人推到github回購。由於Apache需要作爲本地回購站的所有者運行,因此我無法以其他任何方式使其工作。

我只是想到另一種基於其他評論的可能的解決方案 - 你可能會寫一個簡單的PHP腳本來接收來自github鉤子的請求,並將一些任意信息寫入777目錄中的文件權限或數據庫。然後有一個cron作業,每分鐘檢查一次該文件或數據庫以查看它是否已經更改,如果是,直接發出git pull請求,因爲cron通常以root用戶身份運行。你甚至可以看到文件的時間戳是否已經改變,以確定是否執行git pull。你可以讓你的cron腳本適用於任何用戶擁有的回購協議,然後發佈git pull。這不是一個真正的實時解決方案,但是如果cron腳本非常簡單,它不會讓您的系統每隔一兩分鐘就調用一次。希望有所幫助。

6

如果不想等待cron,這裏是一個簡單的C包裝器,你會從PHP調用什麼。

#include <unistd.h> 
#include <errno.h> 
#define WEBUID 500 
main(int argc, char ** argv, char ** envp) { 
    if(getuid() != WEBUID) exit(1); 
    /* some more security checks */ 
    if(setuid(geteuid())) perror("setuid error"); 
    envp = 0; /* don't want environment - security problem */ 
    system("/hardcoded/path/to/script.bash", argv, envp); 
} 

這編譯包裝應擁有其根,組「WWW」,應該有「S位」。
chwon root.www wrapper; chmod 4440 wrapper,所以

  • 被執行時,他的有效UID將根
  • 執行它只能組萬維網(Web服務器的組)
  • ,當主叫用戶的UID是不是一個基於web服務器將退出
+0

作品一種享受!多麼棒的思維,謝謝。 – georgiecasey 2013-09-14 22:27:57

2

您需要查看incron(文件系統事件的cron)。讓php寫入一個文件並設置incron以在寫入文件關閉時啓動腳本(incron非常具體)。您的腳本應該也可以清理輸入文件以防止代碼注入並使用lockfile命令以防止多個Web用戶之間的任何競爭條件。

我有一個迷你網絡界面,可以打開匿名FTP或其他服務1小時的密碼。 www以普通privilages運行,就像www-data(php用戶)一樣運行,但incron以root身份調用輸入處理腳本。

邁克

0

使用一個守護進程以root身份運行(也許用C編寫的),這將啓動shell腳本爲您服務。要在PHP腳本內觸發shell腳本執行,只需使用IPC(消息隊列)。

看一看這裏得到一個想法是什麼我談論:http://php.net/manual/en/function.msg-send.php#114831

0

我最近出版的一期工程,使PHP獲得和一個真正的Bash shell(如果需要以root權限)進行交互,它解決了exec()和shell_exec()的限制。在這裏獲得:https://github.com/merlinthemagic/MTS

下載您只需使用下面的代碼後:

$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true); 
$return1 = $shell->exeCmd('/my/bash/script.sh'); 
//the return will be a string containing the return of the command 
echo $return1; 

在安全性方面它遠遠比運行Apache作爲根更好。但讓PHP靠近根目錄總是很棘手。

我建造這個項目實現了2種方式之一根的bash shell:

1)您允許Apache在sudo的蟒蛇的權利。

OR

2)您傳遞根證書對象每次你需要以root設置shell的時候。

挑你的毒藥。 :)閱讀文檔。