我想知道是否存在在Linux下的沙箱下运行不受信任的C程序的方法。有什么东西阻止程序打开文件,网络连接,分叉,执行等?
这将是一个小程序,一个家庭作业,上传到服务器并在其上执行单元测试。所以该计划将是短暂的。
答案 0 :(得分:45)
我已经使用Systrace以交互方式和自动方式对不受信任的程序进行沙盒化。它有一个基于ptrace()
的后端,允许在没有特殊权限的Linux系统上使用它,以及需要修补内核的更快,更强大的后端。
也可以使用chroot(1)
在类Unix系统上创建沙箱,尽管这不是那么容易或安全。 Linux Containers和FreeBSD jails是chroot的更好选择。 Linux上的另一个替代方案是使用像SELinux或AppArmor这样的安全框架,这是我为生产系统提出的建议。
如果您告诉您想要做什么,我们将能够为您提供更多帮助。
修改强>
Systrace适用于您的情况,但我认为基于Linux Security Model的AppArmor或SELinux是一种更标准的,因此更受欢迎的选择,具体取决于您的发行版。
编辑2:
虽然chroot(1)
可用于大多数(所有?)类Unix系统,但它有很多问题:
它可以被打破。如果要在系统上实际编译或运行不受信任的C程序,则特别容易受到此问题的影响。如果你的学生和我的学生一样,有人会试图突破监狱。
您必须创建一个完整的独立文件系统层次结构,其中包含您的任务所需的所有内容。您不必在chroot中有编译器,但应包含运行编译程序所需的任何内容。虽然有一些实用程序可以帮助解决这个问题,但它仍然不是一件容易的事。
你必须保持chroot。由于它是独立的,因此chroot文件不会随您的发行版一起更新。您将不得不定期重新创建chroot,或者在其中包含必要的更新工具,这实际上要求它是一个完整的Linux发行版。您还必须使系统和用户数据(密码,输入文件e.t.c.)与主机系统保持同步。
chroot()
仅保护文件系统。它不会阻止恶意程序打开网络套接字或者写得不好的程序来吸收所有可用资源。
资源使用问题在所有替代方案中都很常见。 Filesystem quotas将阻止程序填满磁盘。正确的ulimit
(C中的setrlimit()
)设置可以防止内存过度使用和任何分叉炸弹,并阻止CPU占用。 nice(1)
可以降低这些程序的优先级,以便计算机可以用于任何被认为更重要且没有问题的任务。
答案 1 :(得分:18)
我最近写了overview of sandboxing techniques in Linux。我认为你最简单的方法是使用Linux容器(lxc),如果你不介意分叉等等,这在这个环境中并不重要。您可以为进程提供只读的根文件系统,隔离的环回网络连接,您仍然可以轻松地终止它并设置内存限制等。
Seccomp会有点困难,因为代码甚至无法分配内存。
Selinux是另一种选择,但我认为它可能比容器更多的工作。
答案 2 :(得分:6)
您可以使用Qemu快速测试作业。在我5岁的笔记本电脑上,此程序不到5秒钟。
让我们假设学生必须开发一个程序,该程序采用无符号整数,每个都在自己的行上,直到与#34; -1"到达。然后程序应平均所有的整数和输出"平均值:%f"。以下是如何测试完全隔离的程序:
首先,从Jslinux获取root.bin
,我们将其用作userland(它具有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
。
答案 3 :(得分:5)
试试User-mode Linux。对于CPU密集型作业,它的性能开销约为1%,但对于I / O密集型作业,它可能会慢6倍。
答案 4 :(得分:3)
在虚拟机中运行它应该为您提供所需的所有安全性和限制。
QEMU非常适合这一点,并且所有工作(下载应用程序,更新磁盘映像,启动QEMU,在其中运行应用程序以及保存输出以供以后检索)都可以编写脚本自动化测试运行。
答案 5 :(得分:3)
当基于ptrace(strace)结账时进行sanboxing时:
“ sydbox ”沙盒和“ pinktrace ”编程库(它是C99但据我所知有绑定到python和ruby)。
收集与主题相关的链接:
http://www.diigo.com/user/wierzowiecki/sydbox
(抱歉没有直接链接,但还没有足够的声望点)
答案 6 :(得分:3)
seccomp和seccomp-bpf以最少的努力完成此任务:https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
答案 7 :(得分:2)
Firejail是最全面的工具之一 - 它支持seccomp,文件系统容器,功能等:
答案 8 :(得分:1)
这个图书馆应该很好地为你的目标服务
祝你好运!答案 9 :(得分:1)
这似乎也很有希望。使用系统调用拦截的Linux文件系统沙箱。
答案 10 :(得分:-1)
如果你害怕你的学生乱砍你,我猜你有一个权威问题,如果你只能证明一口中的男性用品,那么就会威胁到他们会起诉他们的生活日光。他们给你的工作......
此外,如果有一个班级,并且1%的班级和他能做到这样的事情一样好,不要让他们承担这么简单的任务,并给他们一些大的,他们必须编写更多的代码。综合学习对每个人来说都是最好的,所以不要在旧的僵局结构上传播......
原因是,从不使用相同的计算机来处理重要的事情(比如写证明和考试),而是用于浏览网页和测试软件等事情。
使用离线计算机处理重要事项,使用在线计算机处理所有其他事情。
然而对于其他不是偏执教师的人(不想冒犯任何人,我只是认为你应该在开始担任程序员老师之前学习有关安全和社会的基础知识......)
......我...在哪里为其他人:
快乐的黑客攻击!!