在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完全隔离的程序:

  1. 首先,从Jslinux获取root.bin ,我们将使用它作为userland(它有tcc C编译器):

    wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin

  2. 我们想把学生的提交放在root.bin ,所以build立循环设备:

    sudo losetup /dev/loop0 root.bin

    (你也可以使用fuseext2,但是它不是很稳定,如果稳定的话,你不需要root)

  3. build立一个空目录:

    mkdir mountpoint

  4. 装载root.bin

    sudo mount /dev/loop0 mountpoint

  5. input已安装的文件系统:

    cd mountpoint

  6. 修复权限:

    sudo chown -R `whoami` .

  7. mkdir -p etc/init.d
  8. 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 
  9. chmod +x etc/init.d/rcS

  10. 将提交复制到VM:

    cp ~/student_assignment.c root/assignment.c

  11. 退出虚拟机的根FS:

    cd ..

  12. sudo umount mountpoint
  13. 现在图像已经准备就绪,我们只需要运行它。 它将在启动后编译并运行提交。
  14. mkfifo /tmp/guest_output
  15. 打开一个独立的terminal并开始监听客人输出:

    dd if=/tmp/guest_output bs=1

  16. 在另一个terminal:

    qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput (我刚刚在这里使用了Ubuntu内核,但许多内核都可以工作)

  17. 当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 
  18. 现在Average = 12.000000应该出现在客人输出pipe道。 如果没有,那个学生就失败了。

  19. 退出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

这个图书馆应该为你的目标服务

http://sandbox.sourceforge.net

祝你好运!

Firejail是最全面的工具之一 – 它支持seccomp,文件系统容器,function等等:

https://firejail.wordpress.com/features-3/

好的,谢谢他们帮助我的所有答案。 但我不会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软件等东西。

对于重要的事情使用离线计算机,在其他事情上使用在线计算机。

然而,对于不是任何偏执狂老师的人来说(不想冒犯任何人,我只是认为在开始做程序员老师之前,你应该学习有关安全和社会的基础知识)

…我在哪里…对于其他人:

快乐黑客!