在Linux中的沙箱中运行一个不可信的C程序,防止它打开文件,分叉等?
我想知道是否有一种方法来在Linux下的沙箱下运行不受信任的C程序。 一些会阻止程序打开文件,或networking连接,或分叉,执行等?
这将是一个小程序,一个家庭作业,被上传到服务器,并执行unit testing。 所以该计划将是短暂的。
我已经使用Systrace以交互方式和自动模式对不可信程序进行沙盒处理。 它有一个基于ptrace()
的后端,它允许在Linux系统上使用,而不需要特殊的权限,以及更快,更强大的后端,这需要修补内核。
也可以在使用chroot(1)
类Unix系统上创build一个沙箱,尽pipe这不是那么容易或安全。 Linux Containers和FreeBSD jail是更好的替代scheme。 Linux上的另一个select是使用SELinux或AppArmor这样的安全框架,这就是我所build议的生产系统。
如果你告诉我们你想要做什么,我们将能够帮助你。
编辑:
Systrace可以满足您的需求,但是我认为基于Linux安全模型(比如AppArmor或者SELinux)的东西是更加标准化的,因此也是首选的select,这取决于您的发行版本。
编辑2:
虽然chroot(1)
在大多数(所有)类Unix系统上都可用,但它有很多问题:
-
它可以被打破。 如果您要在您的系统上实际编译或运行不受信任的C程序,则特别容易受到此问题的影响。 如果你的学生和我一样,有人会试图打破监狱。
-
您必须创build一个完整的独立文件系统层次结构,包含您的任务所需的所有内容。 你不必在chroot中有一个编译器,但是应该包含运行编译程序所需的任何东西。 虽然有这方面的帮助,但它仍然不是微不足道的。
-
你必须保持chroot。 由于它是独立的,所以chroot文件将不会随您的发行版一起更新。 您将不得不定期重新创buildchroot,或者在其中包含必要的更新工具,这本质上要求它是一个全面的Linux发行版。 您还必须保持系统和用户数据(密码,input文件等)与主机系统同步。
-
chroot()
只保护文件系统。 它不能阻止恶意程序打开networking套接字或者写入恶意程序,从而窃取每一个可用的资源。
资源使用问题在所有备选scheme中都是常见的。 文件系统配额将阻止程序填充磁盘。 正确的ulimit
(C)中的setrlimit()
设置可以防止内存过度使用和任何分叉炸弹,以及停止CPU猪。 nice(1)
可以降低这些程序的优先级,以便计算机可以用于任何被认为更重要而没有问题的任务。
我最近在Linux上写了沙盒技术的概述 。 我认为你最简单的方法是使用Linux容器(lxc),如果你不介意分叉等等,在这个环境中并不重要。 你可以给进程一个只读的根文件系统,一个孤立的回环networking连接,你仍然可以很容易地杀死它,并设置内存限制等。
Seccomp将会有点困难,因为代码甚至无法分配内存。
Selinux是另一种select,但我认为它可能比集装箱更多的工作。
您可以使用Qemu快速testing作业。 下面的这个程序在我5岁的笔记本电脑上less于5秒。
让我们假设学生必须开发一个程序,每个都有自己的行,直到带有“-1”的行到达。 程序应该平均所有的整数并输出“Average:%f”。 以下是如何testing完全隔离的程序:
-
首先,从Jslinux获取
root.bin
,我们将使用它作为userland(它有tcc C编译器):wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin
-
我们想把学生的提交放在
root.bin
,所以build立循环设备:sudo losetup /dev/loop0 root.bin
(你也可以使用fuseext2,但是它不是很稳定,如果稳定的话,你不需要root)
-
build立一个空目录:
mkdir mountpoint
-
装载
root.bin
:sudo mount /dev/loop0 mountpoint
-
input已安装的文件系统:
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
-
退出虚拟机的根FS:
cd ..
-
sudo umount mountpoint
- 现在图像已经准备就绪,我们只需要运行它。 它将在启动后编译并运行提交。
-
mkfifo /tmp/guest_output
-
打开一个独立的terminal并开始监听客人输出:
dd if=/tmp/guest_output bs=1
-
在另一个terminal:
qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput
(我刚刚在这里使用了Ubuntu内核,但许多内核都可以工作) -
当guest虚拟机输出显示“READY”时,可以从qemu提示符将密钥发送到VM。 例如,要testing这个任务,你可以这样做
(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
应该出现在客人输出pipe道。 如果没有,那个学生就失败了。 - 退出qemu:
quit
通过testing的程序在这里: https : //stackoverflow.com/a/14424295/309483 。 只需使用tcclib.h
而不是stdio.h
。
尝试用户模式的Linux 。 它对CPU密集型作业的性能开销约为1%,但I / O密集型作业的开销可能会降低6倍。
在虚拟机中运行它应该为您提供所有的安全和限制。
QEMU很适合这样的工作(下载应用程序,更新磁盘映像,启动QEMU,在其中运行应用程序,并保存输出供以后检索)可以用于自动化testing运行。
当基于ptrace(strace)签出sanboxing时:
“ sydbox ”沙箱和“ pinktrace ”编程库(这是C99,但据我所知,绑定到python和ruby)。
收集与主题相关的链接:
http://www.diigo.com/user/wierzowiecki/sydbox
(对不起,不直接链接,但没有足够的声望点)
seccomp和seccomp-bpf用最小的努力完成了这个工作: https ://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
Firejail是最全面的工具之一 – 它支持seccomp,文件系统容器,function等等:
好的,谢谢他们帮助我的所有答案。 但我不会build议他们作为提出原问题的人的解决scheme。 所有提到的工具都需要大量的工作来testing学生的代码作为教师,导师,教授。 在这种情况下,最好的办法是在我看来virtualbox。 好吧,它模拟一个完整的x68系统,并与这种方式的沙盒意义无关,但如果我想象我的编程老师,这将是他最好的。 所以,在基于debian的系统上安装“apt-get install virtualbox”,所有其他人转到http://virtualbox.org/ ,创build一个虚拟机,添加一个iso,点击安装,等待一段时间,幸运。 使用user-mode-linux或者执行一些繁重的工作将会容易得多。
如果你担心你的学生侵入你,我想你有权威问题,如果你能在他们的工作中certificate只有一口恶意软件的话,那么一个解决scheme就是威胁他们,您…
同样,如果有一个class级,1%的class级和他做这样的class级一样好,不要让他们做这么简单的任务,给他们一些大的,他们必须编写更多的。 综合学习对每个人来说都是最好的,所以不要在老的僵局结构上传递信息。
而且,从来没有使用同一台计算机做重要的事情(比如写作certificate和考试),你正在使用浏览networking和testing软件等东西。
对于重要的事情使用离线计算机,在其他事情上使用在线计算机。
然而,对于不是任何偏执狂老师的人来说(不想冒犯任何人,我只是认为在开始做程序员老师之前,你应该学习有关安全和社会的基础知识)
…我在哪里…对于其他人:
快乐黑客!