让PHP执行shell脚本的正确且安全的方法
我正在开发一个应用程序,人们(任何人)都可以上传将在服务器上编译和运行的代码(Java和可能的C++)。这当然是一个巨大的安全风险,所有这些都需要适当的沙盒不过,这个沙箱不在这个问题的范围之内。假设已经解决了这个问题 接下来,系统中将有一些函数依赖于shell命令和PHP的exec()、shell_exec()等函数。需要执行的命令并不多,主要是java(c)、gcc、g++,等等。如果需要的话,列出我们需要的命令是相当容易的。一旦我们决定,用户将不可能执行其他命令。例如,有人上传一些java代码并要求服务器编译。然后服务器将运行javac。用户的输入只能更改javac的参数(使用escapeshellarg()转义) 我想知道我还应该采取什么安全预防措施。我计划使用PHP的安全模式,这样只有让PHP执行shell脚本的正确且安全的方法,php,linux,shell,security,permissions,Php,Linux,Shell,Security,Permissions,我正在开发一个应用程序,人们(任何人)都可以上传将在服务器上编译和运行的代码(Java和可能的C++)。这当然是一个巨大的安全风险,所有这些都需要适当的沙盒不过,这个沙箱不在这个问题的范围之内。假设已经解决了这个问题 接下来,系统中将有一些函数依赖于shell命令和PHP的exec()、shell_exec()等函数。需要执行的命令并不多,主要是java(c)、gcc、g++,等等。如果需要的话,列出我们需要的命令是相当容易的。一旦我们决定,用户将不可能执行其他命令。例如,有人上传一些java代
safe\u模式\u exec\u dir
中的文件才能执行。我还计划将shell文件的所有权设置为root:www-data
,这样www-data就不能更改权限或所有权,并且还计划拥有类似rwxr-xr--
的权限,这样www-data就不能修改该文件。但是,从5.4.0起,PHP中已删除了安全模式。目前做这类事情的方式是什么
让完全不同的用户运行这些shell命令会更安全吗?除了safe\u mode\u exec\u dir
,这些用户甚至无法访问任何其他目录?那我该怎么做呢
另一种选择是让PHP只维护一个需要完成的事情的列表,并让一个受限制的用户每隔一分钟左右运行一次cronjob,以遍历该列表并执行必要的操作。这是一种更安全的方法吗?由于最多一分钟的延迟,我更愿意直接从PHP执行此操作
我可以完全访问我的服务器,但由于政策的原因,我不允许使用虚拟化。实际上,当给人们这种自由时,唯一真正安全的步骤是为每个用户会话启动一个新的虚拟实例,并在会话关闭时“烧掉”它。
如果您想要某种持久性,可以对他们的输入进行分类,并在下次他们访问时在新实例上运行它。即使这样,也有很大的利用空间,但对系统的破坏应该是有限的。在我看来,一个好的简单方法是使用LXC容器来获得一个安全的环境来编译和运行脚本 您说您不能使用虚拟化,但从技术上讲,它只是流程隔离。就像服用类固醇的白痴。我有一个容器主机,它本身就是一个VM,到目前为止我还没有遇到任何问题。实际上,LXC不是虚拟化,应该适合您的需要 以下是一些介绍链接:
lxc.network.flag=down
或lxc.network.type=empty
关闭网络也是一个好主意
然后,当上传代码时,您可以克隆模板容器,将代码放入其中,让它生成并运行代码
所有这些都可以通过一个从php调用的shell脚本来完成,或者通过一系列php系统调用来完成,但这听起来并不好
对于你想做的事情,使用非特权容器是必须的,因为它提供了额外的安全层
我建议使用Ubuntu14.04作为LXC主机。我认为一个经过调整的busybox模板和适当的工具来编译和运行代码是您可以得到的最轻的容器
以下是我的想法:
// clone the prepared template
lxc-clone -o myTemplate -n newContainer
// put the code archive in the new container
cp path/to/code path/to/container/and/where/you/want
// Start the container as a daemon
lxc-start -n newContainer -d
// Then launch the right script for the type of code in the container
lxc-attach -n newContainer -- su containeruser -c /path/to/script.sh
因此,小任务是创建具有所需LIB的模板。另一项工作是编写最后调用的脚本
祝您的项目好运,我希望这会有所帮助。您希望创建一个能够编译java程序并启动它们的服务 我不理解你的问题不是关于如何安全地启动那些程序,因为你认为它已经被处理好了 因此,您想知道如何安全地启动shell脚本,在该脚本中,您将给出源代码的名称以及
javac
的参数
首先,你有很多事情要做
您希望使用系统调用的事实意味着您将在整个虚拟主机中允许exec
。因此,如果您的FTP密码、一个PHP文件或任何东西被泄露,攻击者可以上传脚本、二进制程序并执行。
open\u basedir
限制可以在PHP中访问的文件,这些限制在安全模式结束后仍然存在。然后,您将使用open_basedir允许目录(当然没有noexec标志)escapeshellarg
)和java文件名中的任何潜在注入(但我们假设它在传输之前将被重命名,以避免您将收到的不同java文件中的文件名冲突)PHP中的安全模式并不像您想象的那样安全 Functi