Linux中的沙盒化
我想创建一个网页应用,让用户可以上传一些C语言代码,并查看这些代码执行的结果(代码会在服务器上编译)。但是用户是不可被信任的,这显然会带来很大的安全隐患。
所以我需要为这些应用创建一个沙盒环境。最基本的,我想限制对文件系统的访问,只允许访问一些指定的目录。我不能直接使用chroot监狱,因为这个网页应用不是以特权用户身份运行的。我想也许可以使用一个suid可执行文件来设置这个监狱。
上传的程序应该比较小,所以执行起来应该很快(最多几秒钟)。因此,我可以在预设的超时时间后杀掉这个进程,但我该如何确保它不会生成新的进程呢?或者如果我无法做到这一点,杀掉整个进程组ID(pgid)是否是一个可靠的方法?
除了“根本不要做这个”之外,最好的解决办法是什么呢?我还有哪些明显的安全问题没有考虑到?
顺便说一下,这个网页应用会用Python编写。
13 个回答
我觉得这样做非常危险,原因有很多。你基本上是在给自己打开一个大门,让任何可以在你系统上找到的漏洞都能被利用(而通常情况下,你只会受到那些可以远程利用的漏洞的影响)。如果可以的话,我建议你不要这样做。
如果你真的想这么做,可能需要使用某种虚拟机来运行用户的代码。比如说,使用KVM,你可以用同一个基础镜像设置多个虚拟机(你甚至可以在已经启动的状态下保存快照,不过我不太确定克隆后会怎样)。这样你就可以按需创建虚拟机,运行用户的代码,返回结果,然后关闭虚拟机。如果你把这些虚拟机彼此隔离,并且与网络隔离,用户可以随意搞破坏,但不会对你的物理服务器造成伤害。在这种情况下,唯一的危险就是可能会有某种漏洞让他们逃出虚拟机……这种情况非常少见,而且随着硬件虚拟化技术的进步,这种情况会变得更加少见。
你提供的这些细节让我觉得你对服务器有管理权限,所以我会基于这个假设来给出建议。
我会把这个问题当作一个批处理系统来处理。也就是说,网页服务器会接受源文件的上传,然后有一个程序会定期检查提交的文件夹,处理文件,最后把结果提交到另一个文件夹,网页应用会不断检查这个文件夹,直到找到结果并显示出来。
有趣的部分是如何安全地执行这些操作。
我选择的操作系统是FreeBSD,所以我会设置一个预先配置好的“监狱”(注意不要和普通的chroot监狱混淆),这个“监狱”会编译、运行并保存输出。然后,对于每个源文件的提交,我会为每次执行启动一个全新的“监狱”,里面放上源文件的副本。
只要这个“监狱”的/dev目录几乎被清空,系统资源限制设置得当,并且流量无法从“监狱”外部路由(绑定到不可路由的地址或简单地通过防火墙限制),我个人会觉得在我管理的服务器上运行这个是安全的。
既然你使用的是Linux,我建议你可以看看用户模式Linux或Linux-VServer,这些概念和FreeBSD的“监狱”非常相似(我自己没用过,但看过相关资料)。还有其他几种类似的系统,可以在这里找到。
这种方法比普通的chroot监狱安全得多,而且比使用完整虚拟化技术(比如qemu/kvm或VMware)要轻量得多。
我不是程序员,所以不太清楚你可以用什么样的AJAX技术来检查结果,但我相信是可以做到的。作为管理员,我觉得这是一个很有趣的项目。祝你玩得开心。 :)
除了其他建议,你可能会觉得这个很有用。
这个内容来自于http://codepad.org/about,也就是codepad.org的介绍页面。