我的linux系统上有一个用户brftv,我有运行nginx的www-data.
从终端我可以让我的brftv用户运行
sudo /sbin/reboot
它工作正常,因为我将以下内容添加到我的/ etc/sudoers文件的"#user权限规范"部分:
brftv ALL=NOPASSWD: /sbin/halt, /sbin/reboot, /sbin/poweroff www-data ALL=NOPASSWD: /sbin/halt, /sbin/reboot, /sbin/poweroff
但是当我的php文件运行以下代码时,没有任何反应
exec('nohup sudo -u brftv /sbin/reboot');
我在上面的etc/sudoers中添加了www-data行,以防在运行上面的exec()时需要它(尽管我将它作为-u brftv运行,但我不是linux专家,只是认为更好是安全的如果).
运行此exec()的php文件由www-data拥有,chmod为777,因此所有人都应具有从中执行的权限.
我试过通过浏览器运行php文件(将由我假设的用户www-data运行)和终端$ php myFile.php
.
-------------------更新-----------------
我这样做了
sudo chmod u s /sbin/reboot
这允许我系统上的所有用户在没有密码的情况下运行reboot cmd.它可以工作,但我宁愿不把它打开,所以使用/ etc/sudoers的其他解决方案会更好,如果有人会暗示我的问题是什么......
我跟着这个tut http://linux.byexamples.com/archives/315/how-to-shutdown-and-reboot-without-sudo-password/,第二个例子就是我上面的东西,它不起作用为了我..
我会使用一个非常小的C程序来授予只访问PHP组的权限(可能www-data
在你的情况下?),使用可执行文件上的suid位,并执行reboot命令
phpreboot.c:
#include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main() { setuid(0); // for uid to be 0, root char *command = "/sbin/reboot"; execl(command, command, NULL); return 0; // just to avoid the warning (since never returns) }
编译它
gcc -Wall phpreboot.c -o phpreboot
将phpreboot移动到要运行它的位置(必须由PHP访问!)
mv phpreboot /home/private/
以root用户身份(或通过sudo)确保所有者为root,将group设置为www-data,并将权限更改为suid bit(按此顺序)
chown root:www-data phpreboot chmod 4750 phpreboot
结果,ls -l phpreboot
应该是这样的(注意小号在RWS)
-rwsr-x--- 1 root www-data 8565 Jun 12 11:42 phpreboot*
更改PHP脚本来执行phpreboot代替
exec ("/home/private/phpreboot"); // change the path!
只有一个微小的可执行文件将有suid来运行重启程序,只有PHP组才能执行它(当然还有root).
关于setuid和suid位
PHP 获取正在运行的组ID,然后在Linux上执行id groupID
组名称.