使用PHP中的sudo运行shell脚本


Run shell script with sudo from PHP

我目前在我的ubuntu盒子上有一个PHP文件,我想用它从web界面在机器上创建用户(安全blablabla,它都在一个内部网络上,任何意外/故意对系统造成伤害的人都无法访问)我最初尝试使用这个:

    shell_exec("sudo mkdir -m 755 ".escapeshellarg($directory));
    shell_exec("sudo useradd -s /bin/false -d ".escapeshellarg($directory)." -p ".crypt($pass,$salt)." ".escapeshellarg($servername));

但很明显,这暴露了mkdir和useradd都是无密码的sudo'd,所以我没有这么做,而是决定通过在/etc/中创建一个名为"newserver.sh"的shell脚本来减少复杂性,现在我有了这个;

#!/bin/bash
#Var 1 = Directory, Var 2 = Username Var 3 = Password
mkdir "$1"
chmod 755 "$1"
useradd -s /bin/false -d "$1" -p "$3" "$2"
chown "$2" "$1"

它似乎运行得更好,当我从终端运行它时运行得很好,但当PHP使用执行它时

shell_exec("sudo sh /etc/newserver.sh /home/testuser testuser testpass");

它似乎什么都没做(我甚至用和我在终端上运行它时相同的参数进行了测试)

仅供参考,我的sudoers文件中有这一行www-data ALL=(root) NOPASSWD: /etc/newserver.sh

首先,密码必须加密,如下所示:

/etc/newserver.sh /home/testuser testuser "$6$VP9.GI9D$nVjpXIlgoTCLYICNW9ijPqg07opPrjTU2ilYULaT4rut8S9CAmWggMXuOhJ27C5ltwCRfzSxEVgSlReA2i/rH1"

我认为,你应该用"-c"作为论据。

shell_exec("sudo sh -c '"/etc/newserver.sh /home/testuser testuser testpass'"");

以root身份运行有两种方式:

  • 使用sudo(使www-data成为sudoer并不是一个好主意…)
  • 设置setuid

看一看/bin/ping:

-rwsr-xr-x 1 root root /bin/ping

它属于root,但替换"x"(execute)的"s"意味着该程序是setuid:它将始终使用所有者的标识:root执行。ping是一个需要构建ICMP数据包的程序,只有root用户才能操作这些数据包直到最后。

您可以创建一个类似的环境:将命令放在shell脚本中(比如myscript.sh)和:

chown root:root myscript.sh # Give it to root.
chmod u+s myscript.sh # Use setuid on it.

现在,当您运行它时,即使是作为普通用户(或web服务器的www-data…),进程也将以root的身份创建。

危险将setuid(作为root)提供给脚本是非常危险的。你应该小心权限:除了你感兴趣的人之外,不允许任何人运行它。例如,为允许运行此脚本的人创建一个名为myscriptexec的组:

addgroup myscriptexec
chgrp myscriptexec myscript.sh
chmod g+x # Group can execute.
chmod o= myscript.sh # No one executes except root and group members.

然后,根据需要将用户添加到此组。

如果你需要检查你的脚本,我建议你使用一个临时日志文件,用于调试目的:

exec > /tmp/mylog.log
exec 2> /tmp/mylog.log