您好,登錄后才能下訂單哦!
這幾天弄的東西涉及到php利用shell腳本與Linux的交互,我們知道利用php運行腳本來訪問Linux是以Apach的身份來執行的,因此它自己能夠所做的事情很少的,因為沒有足夠的權限,這里就涉及到要將為php執行的時候賦予root權限。
接下來介紹的這種方法,我自己是親自做了的,可以實現,但是畢竟有它的缺點,這里跟大家分享一下,希望大家有什么好的做法可以提示一下:
這是利用C來實現互換權限的,如果你想徹底明白到底為什么接下來的程序可以運行成功,請徹底弄清楚SUID與SGID到底起什么作用。
[plain] view plaincopy
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
uid_t uid , euid ;
uid = getuid();
euid= geteuid();
// printf("my uid:%u\n",getuid());
// printf("my euid:%u\n",geteuid());
if(setreuid(euid,uid))
perror("setreuid");
// printf("after setreuid uid:%u\n",getuid());
// printf("after setreuid euid:%u\n",geteuid());
system("/home/houqingdong/myshell/mkdir.sh /home/ hou_test");
return 0;
}
其中的主要函數說明:
1.getuid()所需要的頭文件為:
#include <sys/types.h>
#include <unistd.h>
函數原型:uid_t getuid(void);
函數說明:uid_t是定義在sys/types.h中的,其實就是unsigned int類型,函數返回一個調用程序的真
實用戶的ID。
2. geteuid()
函數原型:uid_t geteuid(void);
函數說明:geteuid()用來取得執行目前進程有效的用戶識別碼。有效的用戶識別碼用來決定進程執行
的權限,借由此改變此值進程可以獲得額外的權限。倘若執行文件的setID位已被設置,該文件執行時,
其進程的euid值便會設成該文件的所有者的uid。例如,執行文件/usr/bin/myshell.sh的權限為:-r-s-
-x--x,其s位即為setID(SUID)位,而當任何用戶在執行myshell.sh時其有效的用戶識別碼會被設成為
myshell.sh所有者的uid,即root的uid值為0.
3. setreuid(); 可以理解為交換ID
編譯該文件: gcc -o run -Wall run.c 生成可執行文件run
接下來做的是最重要的一步,為run賦予suid的權限:chmod u+s run 它的作用是設置uid,當普通用戶執行的時候是以root的權限來執行的,在run.c里面會交換進程的ID,從而利用root的ID為0,來執行,權限就可想而知了。
但 是利用這個方法有一個很不好的地方,在run.c中,我執行的命令是:system("/home/houqingdong/myshell /mkdir.sh /home/ hou_test"); mkdir.sh是我自己寫的腳本,而后面的兩個參數是寫死的,也就是說參數的傳遞非常不方便,當然如果你執行一些不需要傳遞參數的程序,這個方法還是很 可行的,而我想做的是用戶選擇Linux下的某個目錄,可以在這里面創建文件file或者目錄directory,此時的參數就非常不好辦了。
關于這個問題還嘗試了另一種方法:
就是直接將自己寫的shell腳本,執行: chmod 777 mkdir.sh chmod u+s mkdir.sh
這樣我調用mkdir.sh的時候同樣是以root的身份來執行的,但是我在網頁端運行的時候,仍然報錯,初步認定為我要創建文件的那個目錄下 Apache的權限不夠,我嘗試著將權限改為: chmod -R 777 /home/ 然后在運行就可以創建成功了,但是這樣為Apache添加權限的方法是很不正規的吧,我知道如何為Apache添加主目錄和虛擬目錄的權限
但是這樣的就不知道了,總不能都改權限吧。
今天晚上:19:30分,這個困擾了我好久的問題終于解決,其中的原理也終于弄清楚了,總之是利用sudo來賦予Apache的用戶root的執行權限,下面記錄一下:
利用php利用root權限執行shell腳本必須進行以下幾個步驟:(所有步驟都是我親自實驗,若有不妥可指出,謝謝!)
1. 確定一下你的Apache的執行用戶是誰。注:不一定就是nobody,我自行安裝的httpd,我的Apache的用戶就是daemon
2. 利用visudo為你的Apache執行用戶賦予root執行權限,當然還有設置無密碼。注:為了安全起見,這里最好是新建一個用戶,讓他作為Apache的執行用戶即可(修改httpd.conf文件,后面我會指出)
3. 這步就簡單了,編寫你的腳本,利用php的exec,system...函數來執行。
接下來就是詳細的實現過程:
1. 查看一下你的Apache的執行用戶是誰: lsof -i:80 運行之后的結果為:
從圖中我們可以清楚的看到,httpd(也就是Apache)的執行用戶為:exec_shell(注:這是我本機上改過之后的用戶,只是用來說明一下,你的肯定不是這個!)
lsof 就是 List of file 的縮寫,就是列出當前系統打開文件的工具,關于他具體的使用方法可參考:http://club.topsage.com/thread-234763-1-1.html 說的比較不錯
確定了你的Linux上Apache的執行者是誰,下面為了安全起見,新建一個用戶將Apache的執行用戶修改為我們新建的用戶。
2. 新建Apache的執行用戶
useradd your_exec_user 我們知道創建用戶的時候都會默認創建一個用用戶名同樣的用戶組,也就是說現在我們也有一個your_exec_user的用戶組
下面我們修改一下Apache的配置文件,使它的執行用戶改為我們剛才新建的這個用戶your_exec_user :
vi /home/houqingdong/httpd-exe/config/httpd.conf(這個是你的Apache所在的目錄位置)
找到下面的地方,修改為你新建的用戶:your_exec_user
重新啟動Apache: /home/houqingdong/httpd-exe/bin/apachect1 restart -------------> 重啟完之后你可以利用:lsof -i:80 查看一下。
3. 執行visudo(或者是 vi /etc/sudoers) , 為your_exec_user賦予root權限,并且不需要密碼,還有一步重要的修改(我被困擾的就是這個地方)
visudo 找到這個地方,添加your_exec_user,并且設置無需密碼
我之前的時候,做完這里就去執行php腳本去了,結果一直創建不成功,而且很郁悶的是我切換到your_exec_user用戶下直接執行是可以執行成功的。
后來,查看了一下Apache的日志文件,發現:
這里明顯看出,在執行sudo的時候說必須要有一個tty去運行sudo , 知道問題出在哪里問題就好解決了: vi /etc/sudoers 將下面的這句注釋掉:
這是因為默認的情況下,執行sudo需要一個終端,這里注釋掉就可以了。接下來,寫你的shell腳本和php命令吧
4. 這里貼一下我寫的很簡單的一個腳本,就是利用在php端傳來的$directory和$name,在該目錄下創建一個$name的目錄
[plain] view plaincopy
#!/bin/bash
#Program
# This program will execute mkdir: cd $directory ; mkdir $name
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
cd $1
if [ ! -d $2 ]; then
mkdir $2
else
echo "Already exist..."
exit 1
fi
功能很簡單,就是進入到$directory 判斷要創建的目錄名是否存在, 然后創建該目錄 。
構造的php執行函數:(部分)
[php] view plaincopy
if($type=="dir"){
$make_dir_command="/usr/bin/sudo /home/houqingdong/myshell/mkdir.sh /$directory/ $name" ;
echo $make_dir_command;
exec($make_dir_command,$output,$return);
if($return == 0){
echo "<script>alert('Build directory seccuss!');location.href='right.php?id=\"$directory\"';</script>";
}else{
echo "<script>alert('Build directory err!');history.go(-1);</script>";
}
這里順帶提一句:構造的命令里面最好都使用絕對路徑。
5. 在網頁端的執行結果:
提交之后,要過幾秒中才會彈出執行結果的提示信息:
執行成功,在我們的/home/目錄下:
哈哈。。。大功告成!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。