如何创建需要 root 权限的 Linux 应用程序?

信息安全 linux 应用安全 ubuntu
2021-09-08 06:05:12

我正在为 Ubuntu 开发一个指标,它应该执行的任务之一是chmod -x一个chmod +x特定的根拥有的二进制文件(/usr/lib/x86_64-linux-gnu/notify-osd准确地说)。据我了解,我的选择是:

  • pkexec 每次运行命令(为了用户体验,我有点想避免);
  • 由于指标是在 python 中,我可以使用setuidC 编写一个带有位集的二进制文件。但是,有人告诉我这种方法是不受欢迎的;
  • 启动一个“代理”,它将作为 root 运行并且只执行一个特定的任务,指示器将与那个“代理”通信

我的问题确实是,就安全性和用户体验而言,哪种方法最好?我应该如何实现一个应用程序,该应用程序需要以 root 身份完成一项非常具体的任务,而其余任务则以普通用户身份完成。

2个回答

这个问题真的没有一个正确的答案。这是安全性和可用性之间的权衡。

每次使用 pkexec 运行命令(为了用户体验,我有点想避免);

如果目标受众没有“CLIphobia”,sudo如果“每次”在 15 分钟内,这里可能会非常棒。

但从安全的角度来看,我建议使用 pkexec。我认为它可以被信任,因为它预先安装在发行版中,不像一些快速破解的 setuid 包装器或守护程序。

由于指标在 python 中,我可以有一个用 C 编写的 setuid 位设置的二进制文件。但是,有人告诉我这种方法不受欢迎;

我听说过setuid 包装器的唯一问题是,如果它们被利用,它们可以用木马覆盖自己,但这与 setuid-to-/root/ 二进制文件无关,因为以 root 身份运行的进程上的任何利用都意味着你反正搞砸了。

我遇到的唯一问题也不适用于 setuid-to-/root/ 二进制文件,这是因为我不了解所有的 unix 用户 ID,忘记设置真实用户 ID、保存的用户 ID 及其组 ID 等价物,这意味着 /drops/ 特权的程序仍然可以重新获得它们。

不赞成 setuid 包装器可能还有其他原因,但我还没有听说过。如果没有其他人可以找到不赞成 setuid 包装器的原因,那么 setuid 包装器将是一个非常好的选择。

启动一个“代理”,它将作为 root 运行并且只执行一个特定的任务,指示器将与那个“代理”通信

如果您创建一个守护进程来执行该任务,请使其尽可能简单,并确保未经授权的用户无法与其通信。

我可以想到两种选择:(1)使用授权客户端知道的密码,守护进程知道,而未经授权的客户端不知道。密码必须存储在 chmod 为 400 的文件中并由 root 拥有。

(2) 在套接字上使用 unix 权限,以防止任何其他本地用户甚至尝试(ab)使用守护程序。 https://stackoverflow.com/questions/20171747/how-to-create-unix-domain-socket-with-a-specific-permissions

选项二在 UX 中被认为不太安全且更加不一致。用户可能不明白为什么当他们以不同的用户身份登录时它不会工作,当它发生时真的很糟糕。

首先,我想解决标题中的问题:

如何创建需要 root 权限的 Linux 应用程序?

除非您绝对、肯定地要求它们,否则不要要求或获得全部的 root 特权。相反,正如user2313067在评论中指出的那样,使用功能来自man 7 capabilities

从内核 2.2 开始,Linux 将传统上与超级用户关联的权限划分为不同的单元,称为功能,可以独立启用和禁用。功能是每个线程的属性。

Linux 2.2 于 1999 年初发布,因此在我撰写本文时已经超过 17 年。即使对于广泛分布的软件,现在拒绝在不支持功能的内核上运行当然也不是不合理的。

具体来说,在这种情况下,您的进程将需要该CAP_FOWNER功能,其中包括告诉内核:

绕过通常要求进程的文件系统 UID 与文件的 UID 匹配的操作的权限检查(例如 , chmod(2)) ,不包括由utime(2)涵盖的那些操作CAP_DAC_OVERRIDECAP_DAC_READ_SEARCH

其次,一般来说,最好的方法是在范围内尽可能地限制任何扩展权限。在您的情况下,这可能意味着一个小程序旨在打开或关闭相关文件上的可执行位,仅此而已。创建一个小程序,可能使用硬编码的相关文件名(#define如果您使用 C,我建议使用宏,或者如果您使用另一种语言,则建议使用类似的机制),它将单个单字符参数作为输入,该参数表示可执行文件是否位应该打开或关闭。做大量的健全性检查,然后调用stat()chmod()不是/usr/bin/stat 和 /bin/chmod) 直接使用适当的参数。这样,即使您的小程序中存在错误,也很难利用它来做任何超出预期的事情。用完整的路径调用这个程序,并确保它不能被任何未经授权的用户使用(当然也不能被任何人修改)。考虑静态编译它以降低库预加载器攻击的风险。

第三,首先考虑为什么需要更改可执行位。您是否正在使用全局状态来管理本地问题可能有一种方法可以完成您正在尝试做的事情,而无需首先诉诸文件权限更改。确保您已用尽所有其他合理的选项,然后再求助于更改持久的全局系统状态。