我正在开发一个应用程序,人们(任何人)都可以上传代码(Java和可能的C(++)开始),这些代码将在服务器上编译和运行。这当然是一个巨大的安全风险,所有这些都必须适当地沙箱化。 此沙盒不属于此问题的范围。假设已经处理过。
接下来,系统中将有依赖shell命令和PHP的exec(),shell_exec()等函数的函数。需要执行的命令不是很多,主要是java(c),gcc,g ++等。如果需要,可以很容易地列出我们需要的命令列表。用户不可能执行除我们决定之后的其他命令。例如,有人上传了一些java代码并要求服务器编译它。然后服务器将运行javac。用户的输入只能更改javac的参数(使用escapeshellarg()进行转义)。
我想知道我应该采取哪些安全预防措施。我打算使用PHP的安全模式,这样只能执行safe_mode_exec_dir
中的文件。我还计划将shell文件的所有权设置为root:www-data
,以便www-data不能更改权限或所有权,而且还具有类似rwxr-xr--
的权限,以便www-data无法修改文件。但是,从5.4.0开始,安全模式已从PHP中删除。目前这样做的方式是什么?
让完全不同的用户运行这些shell命令是否更安全,甚至不能访问除safe_mode_exec_dir
之外的任何其他目录?我怎么会这样做呢?
另一种选择是让PHP只维护需要完成的事情列表,并让受限用户每分钟左右运行一次cronjob,以遍历列表并执行必要的操作。这会是一种更安全的方法吗?由于最多一分钟的延迟,我宁愿直接从PHP这样做。
我可以完全访问我的服务器但由于政策我不允许使用虚拟化。
答案 0 :(得分:5)
在我看来,获得安全环境来编译和运行脚本的一种简单方法是LXC容器。
你说你不能使用虚拟化,但从技术上讲,这只是流程隔离。就像类固醇上的chroot一样。我有一个容器主机,它本身就是一个虚拟机,到目前为止我没有遇到任何问题。真的LXC不是虚拟化,应该适合您的需求。
以下是一些介绍链接:
例如,您可以为每个游戏创建一个模板容器,其中包含编译和运行上载代码所需的所有库。可以根据需要为cpu,ram和磁盘IO保护和限制此模板。我认为使用lxc.network.flag = down
或lxc.network.type = empty
然后,当代码上传时,您可以克隆模板容器,将代码放入其中并使其构建并运行代码。
所有这些都可以通过从php调用的shell脚本或一系列php系统调用来完成,但听起来不太好。
使用非特权容器是您想要做的事情的必要条件,因为它提供了额外的安全层。
我建议使用Ubuntu 14.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
因此,小工作是使用所需的库创建模板。另一项工作是编写最后调用的脚本。
祝你的项目好运,我希望这会有所帮助。
答案 1 :(得分:1)
答案 2 :(得分:1)
您想要创建一个能够编译java程序并启动它们的服务。
我认为你的问题不是关于如何安全地启动这些程序,因为你认为它已被照顾。
因此,您想知道如何安全地启动shell脚本,您将在其中提供源代码的名称以及javac
的参数。
首先,你有很多事情要做。
您希望使用系统调用这一事实意味着您将在整个Virtualhost中允许exec
。因此,如果您的FTP密码,您的某个PHP文件或任何内容遭到破坏,攻击者可以上传脚本,二进制程序并执行它。
noexec
模式下使用您的网站分区和临时文件夹 open_basedir
限制来限制您可以在PHP中访问的文件,这些限制从safe_mode结束后仍然存在。然后,您将允许open_basedir目录(当然没有noexec标志)escapeshellarg
完成)和 java文件的文件名中的任何可能注入(但我们假设它将在传输之前重命名,以避免在您收到的不同java文件中发生文件冲突)答案 3 :(得分:1)
PHP中的安全模式并不像您想象的那么安全。
safe_mode_exec_dir等函数限制了运行应用程序或脚本的目录(或目录),但此应用程序或脚本可以调用该路径(或路径)之外的其他目录。
每个人都建议你使用LXC,我同意所有这些。这是解决问题的最佳方案,但我会把我的两分钱。
您可以为应用程序的每个用户准备一个LXC容器:
为每个用户创建一个本地用户(分离权限以避免访问或修改来自其他用户的文件),并使用SSH登录LXC容器以执行其中的任务:
此解决方案允许您在登录SSH帐户时快速执行任务,而无需等到每次需要创建/启动LXC容器时执行任务,只需稍加一些开销即可保持运行。
您可以使用SCP向/从LXC发送和接收文件:
你可以"保持清洁"从后台进程发送(使用root用户)killall(-9)与参数" -u",ect或使用" pkill -u ..."或者彻底重新启动容器。
您甚至可以在每次运行任务之前(以及在将必要的工作文件上传到LXC容器之前)重新创建用户(删除其主目录)。
最好的问候。