首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >让PHP执行shell脚本的正确和安全的方法

让PHP执行shell脚本的正确和安全的方法
EN

Stack Overflow用户
提问于 2015-02-16 14:06:47
回答 4查看 4K关注 0票数 9

我正在开发一个应用程序,人们(任何人)都可以上传代码(首先是C(++) ),这些代码将在服务器上编译和运行。这当然是一个巨大的安全风险,这将是必要的,所有这些都是沙箱正确。这个沙箱不属于这个问题的范围。假定它已经被处理了。

除此之外,系统中还有一些函数将依赖于shell命令和PHP()、shell_exec()等函数。需要执行的命令不多,主要是java(c)、gcc、g++等。如果需要的话,列出我们需要的命令是相当容易的。用户将不可能执行其他命令,除非我们做出决定。例如,有人上传了一些java代码,并要求服务器编译它。然后服务器将运行javac。用户的输入只能更改javac的参数(这些参数是通过转义的escaped ()转义的)。

我想知道我还应该采取什么安全措施。我计划使用PHP的安全模式,以便只执行safe_mode_exec_dir中的文件。我还计划将shell文件的所有权设置为root:www-data,以便www-data不能更改权限或所有权,并且具有类似于rwxr-xr--的权限,以便www-data不能修改文件。但是,安全模式已经从PHP5.4.0PHP5.4.0中删除。现在做这种事的方法是什么?

让一个完全不同的用户运行这些shell命令是否更安全,这个用户甚至不能访问safe_mode_exec_dir以外的任何其他目录?那我该怎么做呢?

另一种选择是让PHP只维护一个需要做的事情的列表,让受限制的用户每分钟运行一次cron作业,遍历列表并执行必要的操作。这会是一种更安全的方法吗?由于延迟了一分钟,我更愿意直接从PHP执行此操作。

我完全可以访问我的服务器,但是由于策略的原因,我不允许使用虚拟化.。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-02-17 18:54:52

在我看来,获得一个安全的环境来编译和运行脚本的一个好的、简单的方法是一个LXC容器。

您说您不能使用虚拟化,但从技术上讲,它只是进程隔离。就像类固醇上的色度。我有一个容器主机,它本身就是一个VM,到目前为止,我对它没有任何问题。实际上,LXC不是虚拟化,应该适合您的需要。

以下是一些介绍性链接:

例如,您可以使用所有所需的库创建每个游戏的模板容器,以编译和运行上传的代码。根据cpu、ram和磁盘IO的需要,可以对此模板进行保护和限制。我认为用lxc.network.flag = downlxc.network.type = empty关闭网络也是个好主意。

然后,当代码被上传时,您可以克隆模板容器,将代码放入其中,并让它构建并运行代码。

所有这些都是通过从php调用的shell脚本来完成的,或者是通过一系列php系统调用来完成的,但这听起来不太好。

对于您想要做的事情,必须使用非特权容器,因为它提供了额外的安全层。

我建议使用Ubuntu14.04作为LXC主机。我认为通过适当的工具来编译和运行代码的经过调整的busybox模板是你能得到的最轻的容器。

以下是我的想法:

代码语言:javascript
复制
// 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

因此,小任务是使用所需的库创建模板。另一项工作是编写最终被调用的脚本。

祝你的项目好运,我希望这会有所帮助。

票数 6
EN

Stack Overflow用户

发布于 2015-02-16 14:14:34

实际上,当给予用户这种自由时,唯一真正安全的步骤是为每个用户会话创建一个新的虚拟实例,并在会话结束后立即将其“烧掉”。如果您想要某种持久性,请在下次他们访问时在一个新实例上执行它们的输入。即使这样,也有很大的开发空间,但对系统的损害应该是有限的。

票数 1
EN

Stack Overflow用户

发布于 2015-02-21 20:07:53

您希望创建一个能够编译java程序并启动它们的服务。

我发现,您的问题不是如何安全地启动这些程序,因为您假设它已经被处理好了。

因此,您想知道如何安全地启动一个shell脚本,在该脚本中,您将给出源代码的名称和javac的参数。

首先,你有很多事情要做。

要使用系统调用这一事实意味着您将在整个Virtualhost中允许使用exec 。因此,如果您的FTP密码、一个PHP文件或其他任何文件被泄露,攻击者就可以上传脚本、二进制程序并执行它。

  1. 您必须让您的网站分区和临时文件夹由PHP在noexec 模式下使用,在fstab中使用。
  2. 您必须使用open_basedir限制限制您可以在PHP中访问的文件,这些限制从safe_mode结束后一直保存下来。然后您将允许使用open_basedir目录(当然,该目录没有noexec标志)。
  3. 包含脚本和脚本的目录将具有root.www-data权限,并且www-data不能写入
  4. 您必须保护传递给脚本的参数(您已经用escapeshellarg完成了这一操作)和在java文件的文件名中的任何可能的注入(但我们假设它将在传输之前被重命名,以避免您将收到的不同java文件中的文件名冲突)。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28543235

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档