我需要在我的网站上编译和运行用户提交的脚本,类似于codepad和ideone所做的。如何对这些程序进行沙箱处理,以便恶意用户不会关闭我的服务器?
具体来说,我想将它们锁定在一个空目录中,防止它们在其外的任何地方读取或写入,避免消耗太多内存或CPU,或者做任何其他恶意行为。
我需要通过沙盒外部的管道(通过stdin / stdout)与这些程序进行通信。
答案 0 :(得分:24)
codepad.org有一些基于geordi的东西,它使用资源限制运行chroot中的所有内容(即限于文件系统的子树),并使用ptrace API来限制不受信任的程序使用系统调用。请参阅http://codepad.org/about。
我之前使用过Systrace,这是另一个限制系统调用的实用程序。
如果策略设置正确,则可以防止不受信任的程序破坏沙箱中的任何内容或访问它不应该访问的任何内容,因此可能不需要将程序放在单独的chroot中并为每次运行创建和删除它们。虽然这会提供另一层保护,但这可能不会受到伤害。
答案 1 :(得分:17)
前段时间我正在寻找一个沙盒解决方案,用于CS学生的自动分配评估系统。与其他一切非常相似,各种属性之间存在权衡:
我最终决定采用基于Linux的多层架构:
0级 - 虚拟化:
通过在特定时间范围内为所有分配使用一个或多个虚拟机快照,可以获得以下优势:
明确区分敏感数据与非敏感数据。
在期间结束时(例如每天一次或每次会话之后),虚拟机将从快照关闭并重新启动,从而删除任何恶意或恶意代码残留。
第一级计算机资源隔离:每个VM都有有限的磁盘,CPU和内存资源,并且无法直接访问主机。
直接网络过滤:通过在内部接口上安装VM,主机上的防火墙可以选择性地过滤网络连接。
例如,用于测试入门编程课程学生的VM可能会阻止所有传入和传出连接,因为该级别的学生不会进行网络编程分配。在更高级别,相应的VM可以例如是阻止所有传出连接,并仅允许来自教师的传入连接。
为基于Web的提交系统提供单独的VM也是有意义的 - 可以将文件上载到评估VM,但不做其他操作。
等级1 - 基本操作系统约束:
在包含传统访问和资源控制机制的Unix操作系统上:
每个沙盒程序都可以作为单独的用户执行,也许可以在单独的chroot
监狱中执行。
严格的用户权限,可能包含ACL。
ulimit
资源限制处理器时间和内存使用情况。
在nice
下执行,以降低对更关键流程的优先级。在Linux上,你也可以使用ionice
和cpulimit
- 我不确定其他系统上存在哪些等价物。
磁盘配额。
每用户连接过滤。
您可能希望将编译器作为稍微特权的用户运行;更多内存和CPU时间,访问编译器工具和头文件e.t.c。
第2级 - 高级操作系统限制:
在Linux上我认为使用Linux安全模块(例如AppArmor或SELinux)来限制对特定文件和/或系统调用的访问。一些Linux发行版提供了一些沙盒安全配置文件,但要使这样的内容正常工作仍然是一个漫长而痛苦的过程。
第3级 - 用户空间沙盒解决方案:
我已成功使用Systrace小规模,如this older answer of mine中所述。还有其他几种适用于Linux的沙盒解决方案,例如libsandbox。此类解决方案可以提供比基于LSM的替代方案可能使用的系统调用更细粒度的控制,但可以对性能产生可测量的影响。
等级4 - 先发制人的打击:
由于您将自己编译代码,而不是执行现有的二进制文件,因此您手中还有一些其他工具:
基于代码指标的限制;例如一个简单的“Hello World”程序永远不应该超过20-30行代码。
对系统库和头文件的选择性访问;如果您不希望用户拨打connect()
,则可能会限制对socket.h
的访问权限。
静态代码分析;禁止汇编代码,“怪异”字符串文字(即shell代码)和使用受限制的系统函数。
一位称职的程序员可能能够绕过这些措施,但随着成本效益比的增加,他们不太可能继续存在。
等级0-5 - 监控和记录:
您应该监视系统的性能并记录所有失败的尝试。您不仅更有可能在系统级别中断正在进行的攻击,而且您可以使用管理方法来保护您的系统,例如:
要求任何安全官员负责此类问题。
找到你那个坚持不懈的小黑客并为他们提供工作。
您需要的保护程度以及您愿意花费的资源来设置它。
答案 2 :(得分:8)
我是@thkala提到的libsandbox的开发人员,我建议将其用于您的项目。
关于@thkala答案的一些补充意见,
connect()
之类的系统函数。这是因为用户代码可以(1)自己声明函数原型而不包括系统头,或者(2)调用底层的kernel-land系统调用而不触及libc
中的包装器函数;