SElinux沙箱无法从systemd服务启动

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

沙箱无法启动,出现以下错误

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

但是,当我以普通用户的身份从命令行启动服务器而不是启动systemd服务时,它的运行没有问题。

这是semanage login -l的输出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应用程序实际上是一个芹菜工作者。

有两个问题导致此失败。

TL; DR

为了使这个工作,你需要:

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

问题1:MCS范围

当您以普通用户身份从命令行启动服务时,您可能正在运行在以下SELinux环境中。 你可以用id -Z来validation。

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

这个环境有五个部分。

  1. 你的SELinux用户 (unconfined_u)
  2. 你的angular色 (unconfined_r)
  3. 你的域名 (unconfined_t)
  4. 您的MLS范围 (s0-s0)
  5. 你的MCS范围 (c0.c1023)

默认情况下,最新版本的沙箱要求执行sandbox命令的用户具有已定义的MCS范围(请参阅2011年的提交78b077c和提交6c2ad1c )。 当您以普通用户身份运行时,一切正常,因为您已定义了MCS范围。 但是,请查看缺省情况下运行systemd服务的上下文。 (我通过制作一个将SELinux上下文打印到系统日志的脚本得到了这个结果。)

 system_u:system_r:unconfined_service_t:s0 

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

幸运的是,沙箱有一个命令行标志,您可以使用它来显式设置执行上下文的MLS和MCS部分:– --level 。 那就是,当你跑步的时候

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

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

问题2:沙箱域配对

如果您进行上述更改并尝试重新运行您的服务,则会出现新的错误。

/ usr / bin / sandbox:无法将exec上下文设置为system_u:system_r:sandbox_t:s0。 无效的论点

这个错误意味着SELinux不会让你从系统上下文转换到沙箱上下文。 原因是两个不同angular色(system_r / unconfined_r)和沙箱域(sandbox_t)之间的配对。

命令seinfo -rXXXXX -x显示了与angular色“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”配对。 我不知道为什么是这样; 我最好的猜测是,红帽人们只是用普通用户的意图来编写沙盒。 幸运的是,在“system_r”和“sandbox_t”之间添加配对是相当容易的。 使用以下内容创build策略文件(* .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 

根据您的设置,您可能需要在策略文件中添加更多规则,但是从这一点来看, setroubleshootaudit2allow将能够完成大部分工作。

我希望这可以帮助别人!