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