SElinux 沙盒无法从 systemd 服务启动

SElinux 沙盒无法从 systemd 服务启动

我有一台运行用户提交代码的服务器,用于评估。我编写了一个 systemd 服务来启动一个 python 应用程序,然后该应用程序使用 SElinux 沙箱运行提交的代码。

沙盒启动失败,错误如下

/usr/bin/sandbox: User account must be setup with an MCS Range

但是,当我以普通用户身份从命令行启动我的服务器,而不是由 systemd 服务启动它时,它可以正常运行。

这是输出semanage login -l

Login Name           SELinux User         MLS/MCS Range        Service

__default__          unconfined_u         s0-s0:c0.c1023       *
root                 unconfined_u         s0-s0:c0.c1023       *
system_u             system_u             s0-s0:c0.c1023       *

我对 SELinux 的了解非常有限,由于它在由普通用户启动时有效,我猜测这与 system_u 有关?

运行 Fedora 20。

该 python 应用程序实际上是一个 celery worker。

答案1

有两个问题导致此操作失败。

总结

为了实现此功能,您需要:

  1. sandbox使用选项运行--level
  2. 安装我下面显示的策略。

问题 1:MCS 范围

当您以普通用户身份从命令行启动服务时,您可能正在以下 SELinux 上下文中运行。您可以使用 进行验证id -Z

unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

该背景分为五个部分。

  1. 你的SELinux 用户(无限制)
  2. 你的角色(无限制)
  3. 你的领域(不受限制)
  4. 你的MLS 系列(s0-s0)
  5. 你的MCS 范围(c0.c1023)

默认情况下,最新版本的 sandbox 要求执行 sandbox 命令的用户定义 MCS 范围(参见提交 78b077c提交 6c2ad1c从 2011 年开始)。当您以普通用户身份运行时,一切都正常,因为您定义了 MCS 范围。但是,请查看 systemd 服务默认运行的上下文。(我通过编写一个将其 SELinux 上下文打印到 syslog 的脚本来获得此信息。)

system_u:system_r:unconfined_service_t:s0

哎呀!我们没有 MCS 范围!这就是您在 systemd 服务中运行沙盒时出现错误的原因。

幸运的是,sandbox 有一个命令行标志,您可以使用它来显式设置执行上下文的 MLS 和 MCS 部分:--level。也就是说,当您运行

sandbox --level "s0" /path/to/my/command

那么沙盒将不再尝试提取当前上下文的 MCS 范围。

问题 2:沙盒域配对

但是,如果您进行上述更改并尝试重新运行您的服务,您将收到一个新的错误。

/usr/bin/sandbox:无法将执行上下文设置为 system_u:system_r:sandbox_t:s0。参数无效

该错误意味着 SELinux 不允许您从 systemd 上下文转换到沙盒上下文。原因在于两个不同角色 (system_r/unconfined_r) 和沙盒域 (sandbox_t) 之间的配对。

该命令seinfo -rXXXXX -x显示了与角色“XXXXX”合法的域配对列表。让我们查找 sandbox_t。

$ sudo seinfo -runconfined_r -x | grep sandbox_t
     chrome_sandbox_t
     sandbox_t
$ sudo seinfo -rsystem_r -x | grep sandbox_t
     sshd_sandbox_t
     chrome_sandbox_t

因此,“sandbox_t”可与“unconfined_r”配对,但不能与“system_r”配对。我不知道为什么会这样;我最好的猜测是,Red Hat 的人编写沙盒的目的是只让普通用户运行它。幸运的是,在“system_r”和“sandbox_t”之间添加配对相当容易。创建一个包含以下内容的策略文件(*.te 扩展名)。

policy_module(sandbox_system, 1.0);
require {
    type sandbox_t;
}
role system_r types sandbox_t;

如果将文件命名为“sandbox_system.te”,则可以通过运行以下命令来安装它。

$ make -f /usr/share/selinux/devel/Makefile sandbox_system.pp
$ sudo semodule -i sandbox_system.pp

现在,如果您重新运行seinfo,您应该会看到正确的配对。

$ sudo seinfo -rsystem_r -x | grep sandbox_t
     sshd_sandbox_t
     chrome_sandbox_t
     sandbox_t

根据您的设置,您可能需要在策略文件中添加更多规则,但从现在开始,排除故障audit2allow就能完成大部分工作。

我希望这可以帮助别人!

相关内容