前言
一般運維web化會通過web調(diào)用腳本(python或shell腳本為主)或者直接執(zhí)行l(wèi)inux命令,在這里我使用php執(zhí)行l(wèi)inux命令講起义钉。
環(huán)境安裝
安裝環(huán)境是根據(jù)?
0基礎(chǔ)自學(xué)linux運維-2.3-centos7.6安裝LNMP(nginx1.16+mysql5.7+PHP7.3)
這篇文章安裝的LNMP帖烘,其實只要安裝nignx和php就行了逾柿,mysql沒有用到可以不安裝
如果是其它版本的PHP請看一下php.ini中的“disable_functions”倍奢,是否把exec、shell_exec去掉了
PHP程序執(zhí)行函數(shù)
根據(jù)PHP官網(wǎng)知道 php程度執(zhí)行函數(shù)有如下
escapeshellarg?— 把字符串轉(zhuǎn)碼為可以在 shell 命令里使用的參數(shù)
escapeshellcmd?— shell 元字符轉(zhuǎn)義
exec?— 執(zhí)行一個外部程序
passthru?— 執(zhí)行外部程序并且顯示原始輸出
proc_close?— 關(guān)閉由 proc_open 打開的進程并且返回進程退出碼
proc_get_status?— 獲取由 proc_open 函數(shù)打開的進程的信息
proc_nice?— 修改當(dāng)前進程的優(yōu)先級
proc_open?— 執(zhí)行一個命令煮纵,并且打開用來輸入/輸出的文件指針懂鸵。
proc_terminate?— 殺除由 proc_open 打開的進程
shell_exec?— 通過 shell 環(huán)境執(zhí)行命令,并且將完整的輸出以字符串的方式返回醉途。
system?— 執(zhí)行外部程序矾瑰,并且顯示輸出
其中exec砖茸、passthru?隘擎、shell_exec、?system?比較多具體使用方法請點擊直關(guān)鏈接凉夯,這里就不再說了
例子
例1 使用exec命令
ecec官方介紹如下:
建立一個數(shù)據(jù)
mkdir -pv /disk1/t1
echo 'this is a.txt'>/disk1/t1/a.txt
echo 'this is b.txt'>/disk1/t1/b.txt
echo 'this is c1.txt 1'>/disk1/t1/c.txt
echo 'this is c1.txt 2'>>/disk1/t1/c.txt
echo 'this is c1.txt 3'>>/disk1/t1/c.txt
現(xiàn)在要執(zhí)行l(wèi)s -l /disk1/t1命令货葬,用php操作為:
mkdir -pv /disk1/www
cd /disk1/www/
cat>ls.php<<EOF
<?php
exec("ls -l /disk1/t1/a.txt",\$output);
print_r(\$output);
?>
EOF
cat?ls.php
使用php內(nèi)置Web Server
為了能更直觀地看到結(jié)果,我使用了php內(nèi)置的web Server來啟動劲够,端口為8000震桶,格式為:? ? ? ?php -S IP:port,我這里IP是192.168.3.76征绎,端口想設(shè)置為8000蹲姐,故命令為:
#進入要運行的php目錄? ? ? ? ? ? ? ?
cd /disk1/www/?
#執(zhí)行php內(nèi)置web Server
php -S 192.168.3.76:8000
執(zhí)行php
打開瀏覽器輸入:http://192.168.3.76:8000/ls.php,執(zhí)行結(jié)果如下:
例2 使用?shell_exec?命令
如果上面例子可是返回多行結(jié)果會怎樣人柿,把ls.php代碼中
exec("ls -l /disk1/t1/a.txt",\$output);?
改為?
exec("ls -l /disk1/t1",\$output);
顯示所有目錄柴墩,再執(zhí)行試下
再換成用shell_exec試下,語法如下:
把ls代碼改為
$output = shell_exec("ls -l /disk1/t1");
echo "<pre>$output</pre>";
在瀏覽器運行一下:
再把?ls -l /disk1/t1 改為查看 c.txt內(nèi)容
$output = shell_exec("cat /disk1/t1/c.txt");
再按F5刷新一下瀏覽器查看結(jié)果
php權(quán)限問題
改為查看/var/log/messages前3行
$output = shell_exec("head -3 /var/log/messages");
為了能在頁面顯示錯誤凫岖,我在<?php下方添加幾行
ini_set('display_errors',1); //錯誤信息
ini_set('display_startup_errors',1);? ? //php啟動錯誤信息?
error_reporting(-1);? ? ? ? ? ? ? ? ? ? //打印出所有的 錯誤信息?
看似沒問題江咳,好,現(xiàn)在不用php內(nèi)置了哥放,直接用php普通的歼指,我這里是?/disk1/www/hualinux.com/,現(xiàn)在把ls.php復(fù)制過去
cp ls.php /disk1/www/hualinux.com/
在瀏覽器上直接輸入甥雕,發(fā)現(xiàn)空白踩身,為什么呢,因為shell_exec解釋了出錯只返null所以我改用
passthru?命令社露,把代碼改為:
<?php
ini_set('display_errors',1);? ? ? ? ? ? //錯誤信息?
ini_set('display_startup_errors',1);? ? //php啟動錯誤信息?
error_reporting(-1);? ? ? ? ? ? ? ? ? ? //打印出所有的 錯誤信息?
system("head -3 /var/log/messages",$return_var );
echo "return_var: ";
echo $return_var;
?>
運行瀏覽器結(jié)果為:
分析:
因為查看php運行的用戶
查看/var/log/messages日志權(quán)限
[root@vm76 ~]# ll /var/log/messages? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? -rw-------. 1 root root 701881 7月? 24 00:40 /var/log/messages
發(fā)現(xiàn)是除了root其它都不能訪問,解決方法有以下幾種:
方法一:/etc/php-fpm.d/www.conf中設(shè)置user = root 和?group = root,權(quán)限太大重啟不起來赁濒。用python寫的 某塔Linux面板 可是直接用root運行的肮煅佟!不得不說它內(nèi)心的強大拒炎!
方法二:使用shell腳本在腳本寫用expect命令切過去
但這樣會暴露root密碼挪拟,不安全,很危險
方法三:使用Ansible API或SaltStack API接口來實現(xiàn)击你,這樣是不是安全多了
從上圖知道ansible api和salt api玉组,編程語言只有python,可以編寫python腳本丁侄,然后調(diào)用它惯雳,這里我不詳述了。
方法四:給nginx設(shè)置sudo權(quán)限免密碼切換到root鸿摇,因nginx不能遠程登陸石景,只能本地運行
visudo,在100行插入
nginx ALL=(ALL) NOPASSWD: ALL
:wq退出
添加一個腳本名叫l(wèi)s.sh拙吉,并修改ls.php代碼潮孽,如下
[root@vm76 hualinux.com]# cat ls.php
<?php
$output = shell_exec("sh ls.sh");
echo "<pre>$output</pre>";
?>
[root@vm76 hualinux.com]# cat ls.sh
#!/bin/bash
sudo head -3 /var/log/messages
再次執(zhí)行,結(jié)果如下:
方法四因為沒有驗證就可以直接執(zhí)行筷黔,有點不太安全往史,如果php一旦拿到了上傳或修改php文件的權(quán)限,那么對方做什么都可以了佛舱。所以得非常注意椎例。有一些敏感的東西,很重要的東西建議不要直接讓php操作请祖,在sudo中禁止它的行為订歪,即使php被攻破也可以降低影響范圍。
對于修改類要記錄好日志直接發(fā)給ELK日志系統(tǒng)损拢,什么用戶操作的陌粹,登記IP,操作時間福压,執(zhí)行了什么命令掏秩。最好做一個安全層做一下審計,一些敏感操作需要手工審計荆姆。
注意事項:
如果用sudo echo寫入數(shù)據(jù)在腳本中不能用 sudo echo 'xxx'>name.txt 方式蒙幻,要使用sudo sh -c 'echo "xxx">name.txt'方式,如:
sudo sh -c 'echo `date +%F-%H:%M:%S`>>ha.txt'
關(guān)于執(zhí)行shell或python腳本
php執(zhí)行sh腳本或python也是使用上面的php命令胆筒,sh腳本用sh xxx.sh執(zhí)行邮破,python腳本用python xxx.py來執(zhí)行即可