我的Linux系统上有一个用户brftv,我有运行nginx的WWW数据。
从终端我可以让我的brftv用户运行sudo /sbin/reboot
由于我在/etc/sudoers文件的“用户权限规范”部分添加了以下内容,所以它工作得很好:
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数据行,以防在运行上面的exec()时有必要(尽管我以-u brftv的身份运行它,但我不是Linux专家,只是想以防万一,最好是安全的)。
运行这个exec()的php文件归WWW数据所有,chmod是777,因此所有人都有权从中执行。
我试过通过浏览器(假设由用户www data运行)和终端$php myFile.php运行php文件。
------------更新-----------
我做了这个
sudo chmod u s /sbin/reboot
它允许我系统上的所有用户在没有密码的情况下运行reboot命令。它是有效的,但我不想让它那么开放,所以其他的解决方案有/etc/sudoers会更好,如果有人知道我的问题是什么…
我遵循了这个tuthttp://linux.byexamples.com/archives/315/how-to-shutdown-and-reboot-without-sudo-password/的规则,第二个例子几乎就是我上面提到的那些对我不起作用的东西。
最佳答案:
我将使用一个非常小的C程序来只授予对PHP组的访问权限(在您的情况下可能是www-data,在可执行文件上使用suid位,然后执行reboot命令
phpreboot.c:#include
#include
#include
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/
作为根(或通过sudo),确保owner为根,group设置为www data,并将权限更改为具有suid位(按此顺序)
chown root:www-data phpreboot
chmod 4750 phpreboot
结果,ls -l phpreboot应该类似(注意rws中的s)
-rwsr-x--- 1 root www-data 8565 Jun 12 11:42 phpreboot*
将php脚本改为执行phpreboot
exec ("/home/private/phpreboot"); // change the path!
只有一个很小的可执行文件会有suid来运行reboot程序,并且只有php组能够执行它(当然还有root)。
关于setuid and suid bit
phpget the running group idthen on linux doingid groupIDgives the group name.