如何像codepad.org和ideone.com网站沙盒你的程序?
我需要在我的网站上编译和运行用户提交的脚本,类似于键盘和ideone 。 我怎样才能沙盒这些程序,使恶意用户不会把我的服务器?
具体来说,我想locking在一个空目录内,防止他们读取或写入任何地方,消耗太多的内存或CPU,或从其他任何恶意的东西。
我将需要通过沙箱外部的pipe道(通过stdin / stdout)与这些程序进行通信。
codepad.org有一些基于geordi的东西,它可以在资源限制的情况下在chroot中运行所有的东西(比如只限于文件系统的一个子树),并且使用ptrace API来限制不受信任的程序使用系统调用。 参见http://codepad.org/about 。
我以前使用Systrace ,另一个用于限制系统调用的工具。
如果策略设置正确,那么不受信任的程序将被阻止破坏沙箱中的任何内容或访问任何不应该的内容,因此可能不需要将程序放在单独的chroot中,并且为每次运行创build和删除它们。 虽然这将提供另一层保护,可能不会伤害。
前一段时间,我正在寻找一个沙盒解决scheme,用于CS学生的自动分配评估系统。 和其他所有东西一样,在各种属性之间有一个折衷:
- 隔离和访问控制粒度
- 性能和易于安装/configuration
我最终决定采用基于Linux的多层体系结构:
-
级别0 – 虚拟化:
通过在特定时间范围内为所有分配使用一个或多个虚拟机快照,可以获得以下几个优点:
-
清晰分离敏感数据和非敏感数据。
-
在期末(例如每天一次或每次会话之后),VM将被closures并从快照重新启动,从而移除任何残留的恶意代码或恶意代码。
-
第一级计算机资源隔离:每个虚拟机具有有限的磁盘,CPU和内存资源,主机不可直接访问。
-
直接networking过滤:通过在内部接口上安装虚拟机,主机上的防火墙可以select性地过滤networking连接。
例如,用于testing介绍性编程课程的学生的虚拟机可能会阻塞所有传入和传出的连接,因为那个级别的学生不会有networking编程任务。 在较高级别上,相应的VM可以例如阻塞所有传出连接,并且只允许来自教员内部的传入连接。
为基于Web的提交系统提供单独的虚拟机也是有意义的 – 可以将file upload到评估虚拟机,但除此之外别无其他。
-
-
1级 – 基本的操作系统限制:
在包含传统访问和资源控制机制的Unix操作系统上:
-
每个沙盒程序可以作为一个单独的用户执行,也许在一个单独的
chroot
监狱里。 -
严格的用户权限,可能带有ACL。
-
限制处理器时间和内存使用量。
-
在
nice
下执行,以减less比较关键的进程的优先级 在Linux上,您也可以使用ionice
和cpulimit
– 我不确定其他系统上存在什么等价物。 -
磁盘配额。
-
每个用户的连接过滤。
您可能想要将编译器作为一个稍微有特权的用户运行; 更多的内存和CPU时间,访问编译器工具和头文件等
-
-
2级 – 高级操作系统限制:
在Linux上,我认为使用Linux安全模块(如AppArmor或SELinux)来限制对特定文件和/或系统调用的访问。 一些Linux发行版提供了一些沙盒安全configuration文件,但是像这样的工作仍然是一个漫长而痛苦的过程。
-
3级 – 用户空间沙盒解决scheme:
正如我以前的回答中所提到的,我已经成功地使用了Systrace 。 还有其他几个适用于Linux的沙盒解决scheme,比如libsandbox 。 这样的解决scheme可以比基于LSM的替代方法对可以使用的系统调用提供更细粒度的控制,但是可以对性能产生可测量的影响。
-
等级4 – 抢先攻击:
由于您将自己编译代码,而不是执行现有的二进制文件,因此您手中还有一些其他工具:
-
基于代码度量的限制; 例如一个简单的“Hello World”程序不应该超过20-30行代码。
-
系统库和头文件的select性访问; 如果你不想让你的用户调用
connect()
你可能会限制对socket.h
访问。 -
静态代码分析; 不允许汇编代码,“怪异的”string文本(即shell代码)和受限制的系统函数的使用。
一个称职的程序员也许可以绕过这些措施,但随着成本收益比的增加,他们将不太可能持续下去。
-
-
等级0-5 – 监控和logging:
您应该监视系统的性能并logging所有失败的尝试。 您不仅可能在系统级别中断正在进行的攻击,还可以使用pipe理手段来保护您的系统,例如:
-
要求任何安全官员负责这些问题。
-
发现你的黑客持续存在并为他们提供工作。
-
您需要的保护程度以及您愿意花费的资源的设置取决于您。
我是@thkala提到的libsandbox的开发者,我推荐它在你的项目中使用。
@ thkala的答案一些额外的评论,
- 将libsandbox分类为用户登陆工具是公平的,但libsandbox并没有集成标准的操作系统级安全机制(即chroot,setuid和资源配额)。
- 限制对C / C ++头文件的访问,或对用户代码的静态分析,并不妨碍
connect()
类的系统函数被调用。 这是因为用户代码可以(1)自己声明函数原型而不包含系统头文件,或者(2)调用底层的kernel-land系统调用而不用触及libc
包装函数; - 编译时保护也值得关注,因为恶意的C / C ++代码可能会耗尽CPU的无限模板recursion或预处理macros扩展;