将权限作为沙盒的常规非root用户删除?

时间:2015-07-12 22:28:43

标签: c linux security sandbox privileges

是否可以使用一组C库或系统调用来删除POSIX上的所有用户权限,或者至少在Linux上?请注意,我不会询问如何删除root权限,这就是所有其他StackOverflow搜索结果似乎都在询问和回答的问题。

我希望切换到用户nobody具有相同的效果,但如果可能的话更强。也就是说,我希望我的C应用程序执行以下操作:

  • 以普通用户身份运行, root,且没有setuid文件权限位
  • 保留访问特定文件和打开传出网络连接的能力
  • 自愿且永久地失去在指定(或所有)目录中读取和写入文件的能力,尤其是$HOME
  • 如果可能的话,放弃或沙箱所有其他不必要的能力,比如用accept打开听音插座

到目前为止,我所考虑的事情都不合适:

  • 使用nobody / setuid切换到用户setgid
    • 禁止普通用户切换到其他用户(例如nobody),并且只需转换为root,应用程序就不需要nobody
  • Linux/POSIX.1e Capabilities
    • 功能仅添加root - 类似权限,而不是剥夺普通用户权限
  • 传统seccomp
    • 我的申请需要的不仅仅是exitsigreturnreadwrite

看起来很有趣的东西,但我找不到文档,似乎没有维护,或者似乎是不可移植的:

那么是否有一个记录良好,最好是可移植的方式来放弃不必要的用户权限和沙箱流程而不必先成为root

1 个答案:

答案 0 :(得分:2)

任何解决方案都不可能适用于所有POSIX,因为POSIX没有定义您正在寻找的机制。

仅仅考虑需求和Linux,可能最简单的方法是通过安全模块来实现。 apparmor,selinux,RBAC中的任何一个都可以满足您的需求,但只能通过外部配置文件 - 而不是内置于您应用中的内容。问题可能是在所有这些情况下添加配置文件需要root用户执行此操作(但配置文件也适用于用户进程)。

几乎满足要求的更复杂的解决方案是seccomp。虽然它根本不理解路径(你只能看到指针),但有一些方法可以限制访问:可以为每个线程定义seccomp策略,因此你可以重新设计你的系统以获得一个“路径验证线程”,这不会除了读取路径和返回套接字(如果它们符合您的规范)之外,我们不做任何事情。然后将该线程限制为recv()open()send()。执行其他工作的线程可以删除open()并使用其他服务。

或者,如果您可以在程序启动时配置路径,您可以将它们放入一个数组中,将该页面标记为只读,并设置seccomp策略,该策略只接受来自该数组的文件名open()(即在这种情况下只是一个指针比较。)

在某种程度上,将应用程序拆分为具有非常有限责任的单独进程的方法是您可以在其他系统上复制的方法,但没有与Linux相同的保证。例如,qmail是一种非常小的进程系统,可用作数据管道(简化)。在Linux上你仍然可以将seccomp应用于它们,在Solaris上只删除exec和其他系统上的其他功能......我不知道,但可能你可以做点什么。