文件上下文策略更新与使用竞争条件

文件上下文策略更新与使用竞争条件

我有一个 Ansible 剧本,其中一个任务添加了 SELinux 文件上下文,并且以下任务应该使用该新上下文 - 即,如有必要,修复目录的文件上下文。

当我运行剧本时,看起来第二个任务仍然使用旧的文件上下文策略。这意味着它没有按预期修复目录的上下文。仅在我第二次运行播放后,上下文才被修复。

第一次运行的输出示例:

TASK [web : add file contexts] ****
# Addition to semanage file context mappings
+/srv/fubar(/.*)?      a      system_u:object_r:httpd_sys_content_t:s0
changed: [example.org]

TASK [create webroot] **********
--- before
+++ after
@@ -1,7 +1,7 @@
 {
     "path": "/srv/fubar",
     "secontext": [
-        "unconfined_u",
+        "system_u",
         "object_r",
         "var_t",
         "s0"

changed: [example.org]

而立即重新执行剧本会产生:

TASK [web : add file contexts] ****
ok: [example.org]

TASK [create webroot] *******
--- before
+++ after
@@ -3,7 +3,7 @@
     "secontext": [
         "system_u",
         "object_r",
-        "var_t",
+        "httpd_sys_content_t",
         "s0"
     ]
 }

changed: [example.org]

正如预期的那样,进一步的执行不会产生任何变化。

Ansible 任务如下所示:

- name: add file contexts
  sefcontext:
      target: '/srv/fubar(/.*)?'
      setype: httpd_sys_content_t
      state: present

- name: create webroot
  file:
      state: directory
      dest: /srv/fubar
      owner: juser
      group: juser
      mode: '0755'
      setype: _default
      seuser: _default

我在这里缺少什么?

一般来说,更新 SELinux 文件上下文时是否存在一些竞争条件?

在查看日志文件时,有一些 SELinux 消息表明该策略已重新加载 - 但就在执行下一个任务之前。这也匹配sefcontext 模块文档其中指出默认情况下启用 SELinux 策略重新加载。

答案1

这实际上取决于 Ansible 的调用方式。

即使使用 SSH 多路复用(默认启用)和 SSH 管道(通常推荐),Ansible(自 2.9.11 起)也会重新登录并在新的 Python 进程中运行每个任务。

在该环境中,添加的文件上下文在文件任务中立即可见。

但是,当您使用以下命令运行剧本时Mitogen 连接插件启用后,连续任​​务将在同一个 Python 进程中执行。然后文件上下文更改实际上在进程级别进行缓存。

它被缓存是因为 Ansible 调用selinux.matchpathcon()(in selinux_default_context(), module_utils/basic.py) 来获取默认文件上下文。事实证明,它matchpathcon()已被弃用,并在第一次调用时在内部缓存所有文件上下文。一个可能的修复方法是让sefcontext模块调用selinux.matchpathcon_fini()在调用策略重新加载后。

这种情况发生在有丝分裂原连接插件,因为它非常擅长重用 ssh 连接和 python 进程。这是一件好事,因为这极大地加快了剧本的执行速度。

也可以看看

Puppet 中的类似问题- 由于 Puppet 作为代理运行 - 所有任务始终在同一进程中运行 -matchpathcon()当系统的 SELinux 策略中的文件上下文发生更改时,Puppet 还使用 API,而不刷新其缓存。

相关内容