我正在尝试构build一个Web应用程序(在Linux服务器上运行),用户将在其中上载可执行文件,可执行文件将针对服务器上可用的特定input(通过STDIN提供)运行,输出(从STDOUT读取)将被返还给用户。
当然,我不希望用户能够在我的服务器上做任何恶意的事情。 我想在沙箱中运行可执行文件,否则会阻止可执行文件执行敏感的系统调用。
我不知道从哪里开始。 我检查了用户模式的Linux ,但它似乎有太多的开销(许多可执行文件将并行运行,并为每一个虚拟机是太多的开销)。
我应该如何继续?
编辑 :我知道这是一个通常避免。 我知道有风险。 把它看作是你为了学习如何完成而要做的事情。 我曾经在CodePad和geordi等地方看过 ,有时这是一件非常方便的事情。
您正在承担运行不可信代码的巨大风险。 如果我想到的问题的答案是“从我的服务器上的任意用户运行不受信任的代码”,我会完全重新思考我想要做什么以及我的项目的基本假设。
你可以尝试librestrict 。
它是一个小型库,在启动给定的可执行文件之前被devise为LD_PRELOAD-ed,基本上是通过chroot()进入一个给定的目录,然后移除所有function(除了基于白名单的function),然后setuid()用户,阻止给定的可执行文件做恶心的事情。
这个程序的好处之一就是在系统加载了所有必要的库之后,它就是chroot(),因此如果你幸运的话(它不需要dl()一些其他库),你可以使用一个空目录,作为一个chroot()环境。
虽然有点老,没有证件,可以试一试,我可以帮你一把。
我认为在VM中运行可执行文件是最好的select。 例如,在#bash IRC频道上有一个bot,它允许执行任意shell代码……通过在一个基于qemu的VM中运行它,然后捕获该进程的标准输出。 UML可能是一个相当好的解决scheme。
新的东西( http://lguest.ozlabs.org/ )可能更好。 这是“容器”机制,而不是全面的“虚拟化”解决scheme; 就像Solaris Zones一样。 我不知道这个项目现在是什么状态。
它必须是一个可执行文件吗? 你能限制上传的程序,例如某些脚本语言(python,ruby)的源代码,这些脚本语言具有某种types的沙盒执行环境。 或者像C#或Java的字节码? 至lessC#和Java已经build立了允许和禁止操作的安全机制。
然后,您可以更轻松地限制上传的程序可以做和不能做的事情。
我尝试了类似的方法,并select了启用grsecurity的内核和只读绑定挂载,以在主机和沙箱之间共享系统文件。 然后,testing应用程序在chroot-ed沙箱中启动。 完成后,所有属于沙箱用户的进程都将被SIGKILL和任何用户可修改的文件清除并从原来的文件中删除。 虽然它可能不像虚拟机那样完全安全,但是在正确完成之后它会非常接近。 这个优点是开销less得多。