在 Linux 的沙箱中运行不受信任的 C 程序,以防止它打开文件、分叉等?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4249063/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Run an untrusted C program in a sandbox in Linux that prevents it from opening files, forking, etc.?
提问by Frank
I was wondering if there exists a way to run an untrusted C program under a sandbox in Linux. Something that would prevent the program from opening files, or network connections, or forking, exec, etc?
我想知道是否有办法在 Linux 的沙箱下运行不受信任的 C 程序。会阻止程序打开文件、网络连接、分叉、执行等的东西?
It would be a small program, a homework assignment, that gets uploaded to a server and has unit tests executed on it. So the program would be short lived.
这将是一个小程序,一个家庭作业,上传到服务器并在其上执行单元测试。因此,该计划将是短暂的。
采纳答案by thkala
I have used Systraceto sandbox untrusted programs both interactively and in automatic mode. It has a ptrace()
-based backend which allows its use on a Linux system without special privileges, as well as a far faster and more poweful backend which requires patching the kernel.
我已经使用Systrace以交互方式和自动模式对不受信任的程序进行沙箱处理。它有一个ptrace()
基于 -based 的后端,允许它在没有特殊权限的 Linux 系统上使用,以及一个更快、更强大的后端,需要修补内核。
It is also possible to create a sandbox on Unix-like systems using chroot(1)
, although that is not quite as easy or secure. Linux Containersand FreeBSD jailsare a better alternative to chroot. Another alternative on Linux is to use a security framework like SELinuxor AppArmor, which is what I would propose for production systems.
也可以使用在类 Unix 系统上创建沙箱chroot(1)
,尽管这并不那么容易或安全。Linux Containers和FreeBSD jails是 chroot 的更好替代品。Linux 上的另一种选择是使用安全框架,如SELinux或AppArmor,这是我为生产系统提出的建议。
We would be able to help you more if you told as what exactly it is that you want to do.
如果您告诉我们您想要做什么,我们将能够为您提供更多帮助。
EDIT:
编辑:
Systrace would work for your case, but I think that something based on the Linux Security Modellike AppArmor or SELinux is a more standard, and thus preferred, alternative, depending on your distribution.
Systrace 适用于您的情况,但我认为基于Linux 安全模型(如 AppArmor 或 SELinux)的东西是更标准的,因此是首选的替代方案,具体取决于您的发行版。
EDIT 2:
编辑2:
While chroot(1)
is available on most (all?) Unix-like systems, it has quite a few issues:
虽然chroot(1)
在大多数(所有?)类 Unix 系统上都可用,但它有很多问题:
It can be broken out of. If you are going to actually compile or run untrusted C programs on your system, you are especially vulnerable to this issue. And if your students are anything like mine, someone WILL try to break out of the jail.
You have to create a full independent filesystem hierarchy with everything that is necessary for your task. You do not have to have a compiler in the chroot, but anything that is required to run the compiled programs should be included. While there are utilities that help with this, it's still not trivial.
You have to maintain the chroot. Since it is independent, the chroot files will not be updated along with your distribution. You will have to either recreate the chroot regularly, or include the necessary update tools in it, which would essentially require that it be a full-blown Linux distribution. You will also have to keep system and user data (passwords, input files e.t.c.) synchronized with the host system.
chroot()
only protects the filesystem. It does not prevent a malicious program from opening network sockets or a badly-written one from sucking up every available resource.
它可以被打破。如果您要在系统上实际编译或运行不受信任的 C 程序,则您特别容易受到此问题的影响。如果你的学生和我一样,有人会试图越狱。
您必须创建一个完全独立的文件系统层次结构,其中包含您的任务所需的一切。您不必在 chroot 中安装编译器,但应包含运行已编译程序所需的任何内容。虽然有一些实用程序可以帮助解决这个问题,但它仍然不是微不足道的。
您必须维护 chroot。由于它是独立的,因此 chroot 文件不会随您的发行版一起更新。您将不得不定期重新创建 chroot,或者在其中包含必要的更新工具,这基本上要求它是一个成熟的 Linux 发行版。您还必须保持系统和用户数据(密码、输入文件等)与主机系统同步。
chroot()
只保护文件系统。它不能阻止恶意程序打开网络套接字或编写错误的程序占用所有可用资源。
The resource usage problem is common among all alternatives. Filesystem quotaswill prevent programs from filling the disk. Proper ulimit
(setrlimit()
in C) settings can protect against memory overuse and any fork bombs, as well as put a stop to CPU hogs. nice(1)
can lower the priority of those programs so that the computer can be used for any tasks that are deemed more important with no problem.
资源使用问题在所有替代方案中都很常见。文件系统配额将阻止程序填满磁盘。适当的ulimit
(setrlimit()
在 C 中)设置可以防止内存过度使用和任何 fork 炸弹,以及阻止 CPU 猪。nice(1)
可以降低这些程序的优先级,以便计算机可以毫无问题地用于任何被认为更重要的任务。
回答by thoaionline
This library should serve your goal well
这个图书馆应该很好地服务于你的目标
http://sandbox.sourceforge.net
http://sandbox.sourceforge.net
Good luck!
祝你好运!
回答by Laurent Parenteau
Running it inside a virtual machine should offer you all the security and restrictions you want.
在虚拟机中运行它应该为您提供所有您想要的安全性和限制。
QEMUwould be a good fit for that and all the work (downloading the application, updating the disk image, starting QEMU, running the application inside it, and saving the output for later retrieval) could be scripted for automated tests runs.
QEMU非常适合这种情况,并且所有工作(下载应用程序、更新磁盘映像、启动 QEMU、在其中运行应用程序,并保存输出以供以后检索)都可以编写脚本以进行自动化测试运行。
回答by pts
Try User-mode Linux. It has about 1% performance overhead for CPU-intensive jobs, but it may be 6 times slower for I/O-intensive jobs.
尝试用户模式 Linux。对于 CPU 密集型作业,它有大约 1% 的性能开销,但对于 I/O 密集型作业可能会慢 6 倍。
回答by Grzegorz Wierzowiecki
When it goes about sanboxing based on ptrace (strace) check-out:
当涉及基于 ptrace (strace) 签出的沙箱时:
"sydbox" sandbox and "pinktrace" programming library ( it's C99 but there are bindings to python and ruby as far as I know).
“ sydbox”沙箱和“ pinktrace”编程库(它是C99,但据我所知有python和ruby的绑定)。
Collected links related to topic:
收集到的与主题相关的链接:
http://www.diigo.com/user/wierzowiecki/sydbox
http://www.diigo.com/user/wierzowiecki/sydbox
(sorry that not direct links, but no enough reputation points yet)
(对不起,不是直接链接,但还没有足够的声望点)
回答by Justin Cormack
I wrote an overview of sandboxing techniques in Linuxrecently. I think your easiest approach would be to use Linux containers (lxc) if you dont mind about forking and so on, which don't really matter in this environment. You can give the process a read only root file system, an isolated loopback network connection, and you can still kill it easily and set memory limits etc.
我最近写了一篇关于 Linux 沙盒技术的概述。我认为你最简单的方法是使用 Linux 容器(lxc),如果你不介意分叉等等,这在这种环境中并不重要。你可以给进程一个只读的根文件系统,一个隔离的环回网络连接,你仍然可以轻松地杀死它并设置内存限制等。
Seccomp is going to be a bit difficult, as the code cannot even allocate memory.
Seccomp 会有点困难,因为代码甚至无法分配内存。
Selinux is the other option, but I think it might be more work than a container.
Selinux 是另一种选择,但我认为它可能比容器更有效。
回答by Janus Troelsen
You can use Qemu to test assignments quickly. This procedure below takes less than 5 seconds on my 5 year old laptop.
您可以使用 Qemu 快速测试作业。下面这个过程在我 5 岁的笔记本电脑上花费的时间不到 5 秒。
Let's assume the student has to develop a program that takes unsigned ints, each on their own line, until a line with "-1" arrives. The program should then average all the ints and output "Average: %f". Here's how you could test program completely isolated:
让我们假设学生必须开发一个程序,该程序采用无符号整数,每个整数都在自己的行上,直到出现带有“-1”的行。然后程序应该对所有整数求平均值并输出“Average: %f”。以下是完全隔离测试程序的方法:
First, get
root.bin
from Jslinux, we'll use that as the userland (it has the tcc C-compiler):wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin
We want to put the student's submission in
root.bin
, so set up the loop device:sudo losetup /dev/loop0 root.bin
(you could use fuseext2 for this too, but it's not very stable. If it stabilizes, you won't need root for any of this)
Make an empty directory:
mkdir mountpoint
Mount
root.bin
:sudo mount /dev/loop0 mountpoint
Enter the mounted filesystem:
cd mountpoint
.Fix rights:
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
Copy the submission to the VM:
cp ~/student_assignment.c root/assignment.c
Exit the VM's root FS:
cd ..
sudo umount mountpoint
- Now the image is ready, we just need to run it. It will compile and run the submission after booting.
mkfifo /tmp/guest_output
Open a seperate terminal and start listening for guest output:
dd if=/tmp/guest_output bs=1
In another terminal:
qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput
(I just used the Ubuntu kernel here, but many kernels will work)When the guest output shows "READY", you can send keys to the VM from the qemu prompt. For example, to test this assignment, you could do
(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
Now
Average = 12.000000
should appear on the guest output pipe. If it doesn't, the student failed.- Quit qemu:
quit
首先,
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
退出虚拟机的根文件系统:
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
应该出现在来宾输出管道上。如果没有,学生失败了。- 退出 qemu:
quit
A program passing the test is here: https://stackoverflow.com/a/14424295/309483. Just use tcclib.h
instead of stdio.h
.
通过测试的程序在这里:https: //stackoverflow.com/a/14424295/309483。只需使用tcclib.h
代替stdio.h
.
回答by rohySeentrusted
ok thanks to all the answers they helped ME a lot. But i would suggest none of them as an solution for the person who asked the original question. All mentioned tools require to much work for the purpose to test students code as a teacher,tutor,prof. The best way in this case would be in my opinion virtualbox. Ok, its emulates an complete x68-system and has nothing to do with the meaning of sandboxing in this way but if i imagine my programming teacher it would be the best for him. So "apt-get install virtualbox" on debian based systems, all others head over to http://virtualbox.org/, create a vm, add an iso, click install, wait some time and be lucky. It will be much easier to use as to set up user-mode-linux or doing some heavy strace stuff...
好的,感谢他们对我的帮助很大的所有答案。但是我不建议将它们作为提出原始问题的人的解决方案。所有提到的工具都需要做很多工作才能测试学生作为教师、导师、教授的代码。在这种情况下,我认为最好的方法是 virtualbox。好吧,它模拟了一个完整的 x68 系统,与沙箱的意义无关,但如果我想象我的编程老师,这对他来说是最好的。所以在基于 debian 的系统上“apt-get install virtualbox”,所有其他人都转到http://virtualbox.org/,创建一个虚拟机,添加一个iso,点击安装,等待一段时间并幸运。设置用户模式linux或做一些繁重的strace事情会更容易使用......
And if you have fears about your students hacking you i guess you have an authority problem and a solution for that would be threaten them that you will sue the living daylights out of them if you can prove just one bite of maleware in the work they give you...
如果你担心你的学生攻击你,我想你有一个权威问题,一个解决方案会威胁到他们,如果你能证明他们所做的工作中只有一口恶意软件,你就会起诉他们。你...
Also if there is a class and 1% of it is as good as he could do such things, dont bore them with such simple tasks and give them some big ones where they have to code some more. Integrative learning is best for everyone so dont relay on old deadlocked structures...
此外,如果有一个班级,并且有 1% 的人能做这样的事情,那么不要让他们厌烦这么简单的任务,并给他们一些大的任务,他们必须在那里编写更多代码。综合学习对每个人都是最好的,所以不要依赖旧的死锁结构......
And of cause, never use the same computer for important things (like writing attestations and exams), that you are using for things like browsing the web and testing software.
当然,切勿将同一台计算机用于重要的事情(例如撰写证明和考试),而不要将其用于浏览网页和测试软件之类的事情。
Use an off line computer for important things and an on line computer for all other things.
使用离线计算机处理重要的事情,使用在线计算机处理所有其他事情。
However to everyone else who isnt a paranoid teacher (dont want to offend anybody, i am just the opinion that you should learn the basics about security and our society before you start being a programmers teacher...)
然而,对于其他不是偏执老师的人(不想冒犯任何人,我只是认为您应该在开始成为程序员老师之前学习有关安全和我们社会的基础知识......)
... where was i ... for everyone else:
......我在哪里......对于其他人:
happy hacking !!
快乐黑客!!
回答by cptaffe
seccomp and seccomp-bpf accomplish this with the least effort: https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
seccomp 和 seccomp-bpf 以最少的努力完成此操作:https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
回答by Federico
Firejail is one of the most comprehensive tools to do that - it support seccomp, filesystem containers, capabilities and more:
Firejail 是最全面的工具之一——它支持 seccomp、文件系统容器、功能等: