代码之家  ›  专栏  ›  技术社区  ›  Frank

在Linux的沙箱中运行不受信任的C程序,防止它打开文件、分叉等。?

  •  105
  • Frank  · 技术社区  · 14 年前

    我想知道是否存在一种在Linux下的沙盒下运行不可信C程序的方法。会阻止程序打开文件、网络连接、分叉、执行等的东西?

    它将是一个小程序,一个家庭作业,被上传到一个服务器上,并在服务器上执行单元测试。所以这个计划是短暂的。

    11 回复  |  直到 10 年前
        1
  •  47
  •   Catskul    11 年前

    我用过 Systrace 以交互方式和自动模式对不受信任的程序进行沙盒处理。它有一个 ptrace() -基于后端,它允许在没有特殊权限的Linux系统上使用,以及一个更快更强大的后端,它需要修补内核。

    也可以在类Unix系统上使用 chroot(1) ,尽管这并不那么容易或安全。 Linux Containers FreeBSD jails 是chroot更好的替代品。Linux上的另一种选择是使用安全框架,如 SELinux AppArmor ,这就是我对生产系统的建议。

    如果你告诉我们你到底想做什么,我们就能帮你更多。

    编辑:

    Systrace对你的案子有用,但我认为 Linux Security Model 像AppArmor或SELinux是一个更标准的选择,因此更受欢迎,取决于您的分布。

    编辑2:

    克洛特(1) 大部分(全部)都有吗类似于Unix的系统,它有很多问题:

    • 它可以被打破。如果要在系统上实际编译或运行不受信任的C程序,则特别容易遇到此问题。如果你的学生和我一样,有人会试图越狱。

    • 您必须创建一个完全独立的文件系统层次结构,其中包含任务所需的所有内容。您不必在chroot中有编译器,但是应该包括运行编译程序所需的任何东西。虽然有一些实用程序可以帮助解决这个问题,但它仍然不是微不足道的。

    • 你必须保持脚掌。因为它是独立的,chroot文件不会随发行版一起更新。您必须定期重新创建chroot,或者在其中包含必要的更新工具,这实际上要求它是一个成熟的Linux发行版。您还必须使系统和用户数据(密码、输入文件e.t.c.)与主机系统保持同步。

    • chroot() 只保护文件系统。它不能防止恶意程序打开网络套接字,也不能防止写得不好的程序吸干所有可用的资源。

    资源使用问题在所有替代方案中都很常见。 Filesystem quotas 将阻止程序填充磁盘。适当的 ulimit ( setrlimit() 在C)设置可以防止内存过度使用和任何叉子炸弹,以及停止CPU的猪。 nice(1) 可以降低这些程序的优先级,以便计算机可以用于任何被认为更重要的任务而没有问题。

        2
  •  18
  •   Justin Cormack    9 年前

    我写了一篇 overview of sandboxing techniques in Linux 最近。我认为最简单的方法是使用Linux容器(lxc),如果你不介意分叉等等,这在这个环境中并不重要。你可以给进程一个只读的根文件系统,一个独立的环回网络连接,你仍然可以很容易地杀死它并设置内存限制等。

    Seccomp将有点困难,因为代码甚至不能分配内存。

    Selinux是另一种选择,但我认为它可能比容器更有用。

        3
  •  6
  •   Community kfsone    7 年前

    您可以使用Qemu快速测试作业。在我5岁的笔记本电脑上,下面的过程不到5秒。

    让我们假设学生必须开发一个程序,该程序接受无符号整数,每一个都在他们自己的行上,直到一个带“-1”的行到达。然后,程序应平均所有整数,并输出“平均值:%f”。下面是如何测试完全隔离的程序:

    1. 首先,得到 root.bin 在Jslinux中,我们将使用它作为userland(它有tcc C编译器):

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

    2. 我们想把学生的意见写进去 根.bin ,因此设置循环设备:

      sudo losetup /dev/loop0 root.bin

      (您也可以使用fuseext2进行此操作,但它不是很稳定。如果它稳定下来,你就不需要根来做任何事情)

    3. 使目录为空:

      mkdir mountpoint

    4. 安装 根.bin :

      sudo mount /dev/loop0 mountpoint

    5. 输入挂载的文件系统:

      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. 将提交内容复制到虚拟机:

      cp ~/student_assignment.c root/assignment.c

    11. 退出VM的根FS:

      cd ..

    12. sudo umount mountpoint
    13. 现在图像准备好了,我们只需要运行它。它将编译并在启动后运行提交。
    14. mkfifo /tmp/guest_output
    15. 打开一个单独的终端并开始监听来宾输出:

      dd if=/tmp/guest_output bs=1

    16. 在另一个终端:

      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发送密钥。 例如,要测试此分配,可以执行

      (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 应该出现在来宾输出管道上。如果没有,那学生就失败了。

    19. 退出qemu: quit

    通过测试的程序如下: https://stackoverflow.com/a/14424295/309483 . 只是使用 tcclib.h 而不是 stdio.h .

        4
  •  5
  •   pts    14 年前

    尝试 User-mode Linux . 对于CPU密集型作业,它的性能开销约为1%,但对于I/O密集型作业,它可能慢6倍。

        5
  •  3
  •   Laurent Parenteau    14 年前

    在虚拟机中运行它可以为您提供所需的所有安全性和限制。

    QEMU 这非常适合,所有的工作(下载应用程序、更新磁盘映像、启动QEMU、在其中运行应用程序,以及保存输出以备以后检索)都可以编写脚本,以便自动运行测试。

        6
  •  3
  •   Grzegorz Wierzowiecki    14 年前

    当基于Pracle(Strues)签出进行三击时:

    " 赛德堡 “沙盒和” 品脱比赛 “编程库(它是C99,但据我所知,它绑定了python和ruby)。

    收集到与主题相关的链接:

    http://www.diigo.com/user/wierzowiecki/sydbox

    (很抱歉没有直接链接,但是还没有足够的信誉点)

        7
  •  3
  •   cptaffe    8 年前

    seccomp和seccomp bpf以最少的努力完成此任务: https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt

        8
  •  2
  •   Federico    8 年前

    Firejail是最全面的工具之一—它支持seccomp、文件系统容器、功能等:

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

        9
  •  1
  •   thoaionline    14 年前

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

    http://sandbox.sourceforge.net

    祝你好运!

        10
  •  1
  •   mauron85    6 年前

    这似乎也很有希望。使用syscall截获的Linux文件系统沙盒。

    https://github.com/adtac/fssb

        11
  •  -2
  •   rohySeentrusted    10 年前

    好吧,多亏他们给了我很多帮助。但我不会建议他们中的任何一个来解决最初的问题。所有提到的工具都需要做大量的工作来测试学生作为老师、导师、教授的代码。在这种情况下,最好的方法是在我看来virtualbox。好的,它模仿一个完整的X68系统,与沙箱的意义没有任何关系,但是如果我想象我的编程老师,那对他来说是最好的。所以“apt get install virtualbox”在基于debian的系统上,所有其他的 http://virtualbox.org/ ,创建一个vm,添加一个iso,单击install,等待一段时间,然后走运。它将更容易使用,如设置用户模式linux或做一些重strace的事情。。。

    如果你担心你的学生攻击你,我想你有一个权威问题,解决这个问题的办法就是威胁他们,如果你能证明他们给你的工作中有一点恶意,你就可以把他们告上法庭。。。

    另外,如果有一个类,并且有1%的类是他能做的最好的,不要让他们厌烦这些简单的任务,给他们一些大的任务,他们必须编码更多。整合学习对每个人都是最好的,所以不要依赖于旧的僵持结构。。。

    当然,千万不要用同一台电脑做一些重要的事情(比如写证明和考试),比如浏览网页和测试软件。

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

    然而,对于其他不是偏执狂的老师(不想冒犯任何人,我只是认为你应该在开始成为程序员老师之前学习安全和我们社会的基本知识…)

    ... 我在哪里。。。对于其他人:

    快乐黑客!!