是否可以使用一组 C 库或系统调用来放弃 POSIX 上的所有用户权限,或者至少在 Linux 上?请注意,我不是在询问如何放弃 root
权限,这是所有其他 StackOverflow 搜索结果似乎都在询问和回答的问题。
我想要与切换到用户 nobody
相同的效果,但如果可能的话更强大。也就是说,我希望我的 C 应用程序执行以下操作:
- 以普通用户身份运行,不是
root
,并且没有 setuid 文件权限位 - 保留访问特定文件和打开传出网络连接的能力
- 自愿并永久失去读取和写入指定(或所有)目录中文件的能力,尤其是
$HOME
- 如果可能,放弃或沙盒化所有其他非必要的能力,例如使用
accept
打开监听套接字
到目前为止我考虑过的不符合要求的事情:
- 使用
setuid
/setgid
切换到用户nobody
- 禁止普通用户切换到其他用户(如
nobody
),应用程序不应该要求root
只是为了切换到nobody
.
- 禁止普通用户切换到其他用户(如
- Linux/POSIX.1e Capabilities
- Capabilities只增加
root
类权限,不带走普通用户权限
- Capabilities只增加
- 繁体 seccomp
- 我的应用程序需要的不仅仅是
exit
、sigreturn
、read
和write
- 我的应用程序需要的不仅仅是
看起来很有趣的东西,但我找不到文档,似乎没有维护,或者看起来不可移植:
那么,是否有一种记录完备、最好是可移植的方法来放弃非必要的用户权限并将进程沙盒化,而不必首先成为 root
?
最佳答案
不太可能有任何解决方案适用于所有 POSIX,因为 POSIX 没有定义您正在寻找的机制。
只看需求和 Linux,可能最简单的方法是通过安全模块来满足它们。 apparmor、selinux、RBAC 中的任何一个都可以满足您的需求,但只能通过外部配置文件——而不是应用程序内置的东西。问题可能是在所有这些情况下添加配置文件需要 root 用户执行(但配置文件也适用于用户进程)。
稍微复杂一点但几乎可以满足要求的解决方案是seccomp。虽然它根本不理解路径(你只能看到指针),但有一些方法可以限制访问:可以为每个线程定义 seccomp 策略,因此你可以重新设计你的系统以具有“路径验证线程”,这不会' 除了读取路径和返回套接字(如果它们符合您的规范)之外做任何事情。然后将该线程限制为只有 recv()
、open()
和 send()
。执行其他工作的线程然后可以放弃 open()
并使用其他服务。
或者如果您可以在程序启动时配置路径,您可以将它们放入一个数组中,将该页面标记为只读,并设置 seccomp 策略,该策略将只接受带有文件名的 open()
来自该数组(在这种情况下,这只是一个指针比较)。
在某种程度上,将应用程序拆分为职责非常有限的单独进程的方法是您可以在其他系统上复制的方法,但没有与 Linux 相同的保证。例如 qmail 是一种由非常小的进程组成的系统,它作为数据管道工作(简化)。在 Linux 上,您仍然可以对它们应用 seccomp,在 Solaris 上,只需删除 exec
和其他功能,在其他系统上...我不知道,但也许您可以做一些事情。
关于c - 放弃作为沙盒的常规非 root 用户的权限?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31373203/