扩展安德烈的答案,这是我认为你应该接受的答案。
特权减少
第一步是确定应用工作流程所需的最低权限。据我了解,您需要操纵虚拟卷。您可以配置一个新的 UID 来执行此操作,而无需登录 shell 和其他root功能吗?大多数 Linux 界面都有用于授予权限的配置文件,因此请与开发人员确认您需要使用的命令。
如果可以创建单独的 UID
然后做一个。让你的应用程序那样运行。确保该 UID 没有 bash 和 home,因此如果应用程序被利用,则硬盘驱动器中不应有任何区域具有永久写入权限,尽可能。此外,没有机会在该 UID 上进行远程登录。您可以使用启动器脚本(使用 Upstart、Systemd、Init 等,而不是陷入这些争论)使用此帐户 ID 运行您的应用程序。
如果您必须使用根 UID
然后明白还有root比看起来更多的东西。首先,以 root 身份运行的进程可能会放弃一些被认为持有危险的特权。这些被称为Linux 功能。因此,为您的应用程序编写一个包装器,以丢弃所有不相关的功能。如果您需要保留某些功能,请进行研究以确保它们不会被利用!例如,《利用 Linux 功能》讨论了如何重新获得仅从特定功能开始的完整功能集。
分隔
见安德烈的回答。基本上,让一个小型应用程序执行所有特权操作,以便 (1) 易于查看,您只需要验证 API 并执行正确的输入域验证;(2) 交付的代码更少,因此完全放弃对您的应用程序控制的可利用错误的机会更少。
硬化
在这种情况下旨在保护您的另一个武器是强制访问控制 Linux 安全模块。默认情况下,Linux 允许root覆盖对系统调用进行的大多数自由访问控制检查。但是,LSM 仍然可以在调用上应用它们自己的强制逻辑。这允许 LSM 减少root的权限。
我可以谈论 AppArmor 或 TOMOY Linux,但让我们把小学玩具留给蹒跚学步的孩子吧。您需要研究 SELinux,并真正理解它(该死。是的,这很难)。您需要创建一个 SELinux 角色,并将其应用于您的进程。在 SELinux 中,角色位于身份之上,以对所有系统调用应用策略。角色意味着您可以拥有一个root被禁止在系统上执行任何操作的用户。在这里,您需要识别您需要的系统调用(您可以audit2allow为此使用)并授予角色访问这些系统调用的权限。
获得权限列表后,请务必查看它们,并尽可能仅在适当的资源上允许它们。例如,可以允许角色在 /var/www 上写入文件,但不能在 /var/log 上写入文件。这意味着您可能需要使用特定类型标记系统上的某些文件,并编写自己的脚本来帮助您维护标签。您还需要为您的应用程序创建一个新域,以便您可以编写所谓的域和类型强制策略。该策略将规定您的应用程序在其域中如何只能与特定的其他类型和域进行交互。
总而言之,域类型策略将确保您的进程受到限制,而角色策略将确保您的 UID 受到限制。有一些重叠,但两者都是必要的,因为您可能会犯错误(或有正当需要)导致应用程序转移到另一个限制较少的域。您对应用施加的 SELinux 角色将确保只能向您选择的域进行转换。
您仍然有责任确保您的角色允许的所有域都具有足够低的权限,不会永久损害您的系统。如果 (1) 阻止任何“可利用的”Linux 功能,这很容易实现;(2) 受限应用与其他应用之间没有共享资源;(并且 (3) 您拒绝任何形式的永久存储(请参阅A Note on the Confinement Problem中的无记忆属性),因此受感染的应用程序不会持续存在)。
如果您无法做到这一点,那么您很可能无法保护您的系统,因为该应用程序只需要太多权限。那是时候聘请专家了,这样他们就可以检查您是否错过了什么!