我想知道是否有一种方法可以在Linux的沙箱下运行不受信任的C程序。是什么会阻止程序打开文件,网络连接,分叉,执行等?
这将是一个小程序,是一项家庭作业,它被上传到服务器并在其上执行了单元测试。因此该程序将是短暂的。
我想知道是否有一种方法可以在Linux的沙箱下运行不受信任的C程序。是什么会阻止程序打开文件,网络连接,分叉,执行等?
这将是一个小程序,是一项家庭作业,它被上传到服务器并在其上执行了单元测试。因此该程序将是短暂的。
Answers:
我已经使用Systrace交互地和以自动方式将不受信任的程序沙箱化。它有一个ptrace()
基于后端的后端,允许它在没有特殊特权的Linux系统上使用,以及一个速度更快,功能更强大的后端,需要对内核进行修补。
也可以使用chroot(1)
,在类似Unix的系统上创建沙箱,尽管这并不那么容易或安全。Linux容器和FreeBSD监狱是chroot的更好选择。Linux上的另一种选择是使用安全框架,例如SELinux或AppArmor,这是我对生产系统提出的建议。
如果您告诉您您想做什么,我们将能够为您提供更多帮助。
编辑:
Systrace可以满足您的情况,但是我认为基于Linux安全模型(例如AppArmor或SELinux)的东西是更标准的,因此根据您的分布情况,它是首选的替代方法。
编辑2:
虽然chroot(1)
在大多数(所有?)类Unix系统上都可用,但是它有很多问题:
它可以被打破。如果要在系统上实际编译或运行不受信任的C程序,则特别容易受到此问题的影响。而且,如果您的学生像我的一样,那么有人将试图越狱。
您必须使用任务所需的所有内容创建一个完全独立的文件系统层次结构。您不必在chroot中具有编译器,但是应该包括运行已编译程序所需的任何内容。尽管有实用程序可以帮助解决此问题,但它仍然不是一件容易的事。
您必须维护chroot。由于它是独立的,因此chroot文件不会随您的发行版一起更新。您将必须定期重新创建chroot,或在其中包含必要的更新工具,这实际上要求它是成熟的Linux发行版。您还必须使系统和用户数据(密码,输入文件等)与主机系统保持同步。
chroot()
仅保护文件系统。它不能防止恶意程序打开网络套接字,也不能阻止编写错误的程序占用所有可用资源。
资源使用问题在所有替代方案中都很常见。文件系统配额将阻止程序填充磁盘。适当的ulimit
(setrlimit()
C语言)设置可以防止内存过度使用和任何fork炸弹,并制止CPU消耗。nice(1)
可以降低这些程序的优先级,以便计算机可以毫无问题地用于被认为更重要的任何任务。
我最近写了Linux中沙箱技术的概述。我认为,如果您不介意派生等等,最简单的方法就是使用Linux容器(lxc),在这种环境下这并不重要。您可以为该进程提供一个只读的根文件系统,一个隔离的回送网络连接,并且仍然可以轻松地将其杀死并设置内存限制等。
由于代码甚至无法分配内存,因此Seccomp会有些困难。
Selinux是另一种选择,但我认为它可能比容器还要工作。
您可以使用Qemu快速测试任务。在我5岁的笔记本电脑上,下面的过程不到5秒。
让我们假设学生必须开发一个程序,该程序接受无符号的int,每个int都在自己的行上,直到到达带有“ -1”的行为止。然后,程序应平均所有int并输出“ Average:%f”。这是测试完全隔离的程序的方法:
首先,root.bin
从Jslinux 获得,我们将其用作用户区(它具有tcc C编译器):
wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin
我们要将学生的提交内容放在中root.bin
,因此设置循环设备:
sudo losetup /dev/loop0 root.bin
(您也可以为此使用fuseext2,但它不是很稳定。如果稳定,则不需要root用户)
制作一个空目录:
mkdir mountpoint
挂载root.bin
:
sudo mount /dev/loop0 mountpoint
输入已挂载的文件系统:
cd mountpoint
。
修复权:
sudo chown -R `whoami` .
mkdir -p etc/init.d
vi etc/init.d
:
#!/bin/sh
cd /root
echo READY 2>&1 > /dev/ttyS0
tcc assignment.c 2>&1 > /dev/ttyS0
./a.out 2>&1 > /dev/ttyS0
chmod +x etc/init.d/rcS
将提交内容复制到VM:
cp ~/student_assignment.c root/assignment.c
退出VM的根FS:
cd ..
sudo umount mountpoint
mkfifo /tmp/guest_output
打开一个单独的终端并开始监听来宾输出:
dd if=/tmp/guest_output bs=1
在另一个终端:
qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput
(我在这里仅使用了Ubuntu内核,但是许多内核都可以使用)
当访客输出显示“ READY”时,可以从qemu提示符向VM发送密钥。例如,要测试此分配,您可以
(qemu) sendkey 1
(qemu) sendkey 4
(qemu) sendkey ret
(qemu) sendkey 1
(qemu) sendkey 0
(qemu) sendkey ret
(qemu) sendkey minus
(qemu) sendkey 1
(qemu) sendkey ret
现在Average = 12.000000
应该显示在来宾输出管道上。如果不是,则学生失败。
quit
通过测试的程序在这里:https : //stackoverflow.com/a/14424295/309483。只需使用tcclib.h
代替即可stdio.h
。
尝试使用用户模式Linux。对于CPU密集型作业,它的性能开销约为1%,但是对于I / O密集型作业,它的速度可能慢6倍。
Firejail是执行此操作的最全面的工具之一-它支持seccomp,文件系统容器,功能以及更多功能:
在虚拟机中运行它应该为您提供所有想要的安全性和限制。
QEMU非常适合此操作,所有工作(下载应用程序,更新磁盘映像,启动QEMU,在其中运行应用程序以及保存输出以供以后检索)都可以编写脚本以进行自动化测试。
基于ptrace(strace)检出进行装箱:
“ sydbox ”沙箱和“ pinktrace ”编程库(它是C99,但据我所知有对python和ruby的绑定)。
收集了与以下主题相关的链接:
http://www.diigo.com/user/wierzowiecki/sydbox
(很抱歉,该链接不是直接链接,但信誉点还不够)
这似乎也很有希望。使用syscall拦截器的Linux文件系统沙箱。
好的,感谢所有答案,他们对我有很大帮助。但对于那些提出原始问题的人,我不建议使用它们作为解决方案。为了测试学生作为老师,老师,教授的代码,所有提到的工具都需要大量的工作。我认为这种情况下最好的方法是virtualbox。好的,它模拟了一个完整的x68系统,并且与这种方式的沙盒无关,但是如果我想象我的编程老师,那对他来说将是最好的。因此,在基于debian的系统上进行“ apt-get install virtualbox”安装,其他所有工具都可以访问http://virtualbox.org/。,创建一个vm,添加一个iso,单击install,稍等片刻,幸运的是。设置用户模式linux或进行一些繁琐的strace操作将更加容易...
而且,如果您担心学生会被黑客入侵,我想您可能有一个权限问题,而如果您能证明他们所做的工作中只有一小撮恶意软件,那么您将起诉他们,要求他们起诉生活中的日光灯。您...
同样,如果有一门课,并且其中的1%就是他能做的那样好,那就不要让他们承受如此简单的任务,而给他们一些大的任务,而他们不得不编写更多的代码。集成式学习对每个人都是最好的,所以不要依赖旧的死锁结构。
因此,绝对不要将用于浏览网络和测试软件等重要内容的同一台计算机(例如编写证明和考试)。
对于重要的事情,请使用脱机计算机,对于所有其他事情,请使用联机计算机。
但是对于不是偏执狂老师的其他所有人(不想冒犯任何人,我只是认为,在您开始成为程序员老师之前,您应该学习有关安全性和我们社会的基础知识...)
...我在哪里...其他所有人:
快乐黑客!