saltstack-formulas / openssh-formula

http://docs.saltstack.com/en/latest/topics/development/conventions/formulas.html
Other
90 stars 297 forks source link

Needs workaround for RedHat-family 6.x with SELinux enabled ("check_cmd execution failed ... Permission denied") (fix included) #147

Open johnnybubonic opened 5 years ago

johnnybubonic commented 5 years ago

In RHEL/CentOS 6.10 with SELinux set to enforcing, the following access violation will occur when testing the new sshd_config with check_cmd (openssh/config.sls, line 17):

type=AVC msg=audit(1548598945.937:183): avc:  denied  { open } for  pid=13492 comm="sshd" name="__salt.tmp.BYA0jz" dev=dm-0 ino=410972 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:initrc_tmp_t:s0 tclass=file

Which, according to audit2allow -w, is because:

(...)
    Was caused by:
        Missing type enforcement (TE) allow rule.

        You can use audit2allow to generate a loadable module to allow this access.

This issue was reported in the (as yet unresolved) https://github.com/saltstack-formulas/openssh-formula/issues/98.

There are two ways around this.

The hacky way:

diff --git a/openssh/config.sls b/openssh/config.sls
index 9fbe895..7ada708 100644
--- a/openssh/config.sls
+++ b/openssh/config.sls
@@ -14,7 +14,9 @@ sshd_config:
     - user: {{ openssh.sshd_config_user }}
     - group: {{ openssh.sshd_config_group }}
     - mode: {{ openssh.sshd_config_mode }}
+    {%- if not ((grains['os_family'] == 'RedHat') and (grains['osmajorrelease'] == 6) and (salt['grains.get']('selinux:enforced', False) == 'Enforcing')) %}
     - check_cmd: {{ openssh.sshd_binary }} -t -f
+    {%- endif %}
     {%- if openssh.sshd_config_backup  %}
     - backup: minion
     {%- endif %}

or the proper way - by using selinux.module_install, you can install an SELinux policy that will allow the tmp file to be read by check_cmd.

I have taken the liberty of generating this policy. In the interest of transparency for those that wish to use it, here's how (all commands assume root):

  1. yum -y install policycoreutils-python (if you currently don't have the audit2allow program installed)
  2. grep 'name="__salt.tmp.' /var/log/audit/audit.log > /tmp/avc_err
  3. cat /tmp/avc_err | audit2allow -m salt.openssh_formula.fix_centos6_selinux > salt.openssh_formula.fix_centos6_selinux.te
  4. checkmodule -M -m -o salt.openssh_formula.fix_centos6_selinux.mod salt.openssh_formula.fix_centos6_selinux.te
  5. semodule_package -o salt.openssh_formula.fix_centos6_selinux.pp -m salt.openssh_formula.fix_centos6_selinux.mod
  6. Then, of course, one would NORMALLY install via semodule -i salt.openssh_formula.fix_centos6_selinux.pp but in this case, SaltStack should install this.

Here are those files that are generated:

salt.openssh_formula.fix_centos6_selinux.te:


module salt.openssh_formula.fix_centos6_selinux 1.0;

require {
    type initrc_tmp_t;
    type sshd_t;
    class file open;
}

#============= sshd_t ==============
# Created by GitHub user johnnybubonic
# Fix for: https://github.com/saltstack-formulas/openssh-formula/issues/147
allow sshd_t initrc_tmp_t:file open;

salt.openssh_formula.fix_centos6_selinux.mod (binary file; in Base64)[0]:

jf98+Q8AAABTRSBMaW51eCBNb2R1bGUCAAAACgAAAAEAAAAIAAAAAAAAACgAAABzYWx0Lm9wZW5z
c2hfZm9ybXVsYS5maXhfY2VudG9zNl9zZWxpbnV4AwAAADEuMEAAAAAAAAAAAAAAAAAAAAAAAAAA
AQAAAAEAAAAEAAAAAAAAAAEAAAABAAAAAQAAAAAAAABmaWxlBAAAAAEAAABvcGVuAQAAAAEAAAAI
AAAAAQAAAAAAAABvYmplY3RfckAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAA
AAACAAAAAgAAAAwAAAABAAAAAQAAAAEAAAAAAAAAQAAAAAAAAAAAAAAAaW5pdHJjX3RtcF90BgAA
AAIAAAABAAAAAQAAAAAAAABAAAAAAAAAAAAAAABzc2hkX3QAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAQAAAAEAAAAABAAAAAAAA
AAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAQAAAAAAAAABAAAAAAAAAEAAAAAAAAAA
AAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAEAAAAA
AAAAAQAAAAAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAEAAAAAAAAAAwAAAAAAAABAAAAAAAAAAAAA
AABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAABAAAAQAAAAEAAAAABAAAAAAAA
AAEAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAA
QAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAQAAAAQAAABmaWxlAQAAAAEAAAABAAAAAQAAAAgAAABvYmplY3RfcgIAAAABAAAAAQAA
AAIAAAAMAAAAaW5pdHJjX3RtcF90AQAAAAEAAAABAAAABgAAAHNzaGRfdAEAAAABAAAAAQAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA

salt.openssh_formula.fix_centos6_selinux.pp (binary file; in Base64)[0]:

j/98+QEAAAABAAAAEAAAAI3/fPkPAAAAU0UgTGludXggTW9kdWxlAgAAAAoAAAABAAAACAAAAAAA
AAAoAAAAc2FsdC5vcGVuc3NoX2Zvcm11bGEuZml4X2NlbnRvczZfc2VsaW51eAMAAAAxLjBAAAAA
AAAAAAAAAAAAAAAAAAAAAAEAAAABAAAABAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAZmlsZQQAAAAB
AAAAb3BlbgEAAAABAAAACAAAAAEAAAAAAAAAb2JqZWN0X3JAAAAAAAAAAAAAAABAAAAAAAAAAAAA
AABAAAAAAAAAAAAAAAAAAAAAAgAAAAIAAAAMAAAAAQAAAAEAAAABAAAAAAAAAEAAAAAAAAAAAAAA
AGluaXRyY190bXBfdAYAAAACAAAAAQAAAAEAAAAAAAAAQAAAAAAAAAAAAAAAc3NoZF90AAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAAAA
AEAAAABAAAAAAQAAAAAAAAACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAEAAAAAAAAA
AQAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAA
AAAAQAAAAEAAAAABAAAAAAAAAAEAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAABAAAAAAAAAAMA
AAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAQAA
AEAAAABAAAAAAQAAAAAAAAABAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAA
AAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAEAAAAZmlsZQEAAAABAAAAAQAAAAEAAAAIAAAAb2Jq
ZWN0X3ICAAAAAQAAAAEAAAACAAAADAAAAGluaXRyY190bXBfdAEAAAABAAAAAQAAAAYAAABzc2hk
X3QBAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==

[0] To decode base64 back into a binary file, copy the entire base64 string to a file (e.g. selinuxpolicy.b64) and then do base64 -d selinuxpolicy.b64 > newfilename. newfilename is the reassembled file. You can pipe it as well: echo '<base64_string>' | base64 -d > newfilename - but if you do it this way, you must remove the linebreaks.

You SHOULD only need the salt.openssh_formula.fix_centos6_selinux.pp file. Use a file.manage to get that in place if:

and then apply it with selinux.module_install.

I have tested the policy and it does indeed work.

I have confirmed the following works on a fresh install of CentOS 6.10:

{%- if ((grains['os_family'] == 'RedHat')
      and (grains['osmajorrelease'] == 6)
      and (salt['grains.get']('selinux:enforced', False) == 'Enforcing')) %}
Install_selinux_helpers:
  pkg.installed:
    - name: policycoreutils
    - name: policycoreutils-python

Copy_module:
  file.managed:
    - source: salt://roles/common/files/ssh/salt.openssh_formula.fix_centos6_selinux.pp
      source_hash: d2f5ce648d7953e284a3e0a6d74bb9c9dc41636683b0b5e790761a04fcdd050168509b65f197f393ca4dcd4570ab97f755705c63c50ee1396e67a3a1fa01f21c
      name: /var/tmp/salt.openssh_formula.fix_centos6_selinux.pp
      user: root
      group: root
      mode: 0400

Install_module:
  selinux.module_install:
    - name: /var/tmp/salt.openssh_formula.fix_centos6_selinux.pp

Enabling_module:
  selinux.module:
    - name: salt.openssh_formula.fix_centos6_selinux
      module_state: 'Enabled'
{%- endif %}
alxwr commented 5 years ago

@johnnybubonic Thanks for the extensive documentation of the proper fix!

I'm leaning towards a cleaner version of "the hacky way" based on #151, because a) decoupling formulas (selinux/openssh) reduces need for maintenance. b) I think a simple use_check_cmd: False in osfingermap.yaml is sufficient to prevent the original bug.

Nevertheless I would add proper documentation in pillar.example on 1) how to set the flag based on grains. (use_check_cmd: {{ salt['grains.get']('selinux:enforced', False) != 'Enforcing' }}) 2) how to do it properly, which will essentially be a link to this Issue.

johnnybubonic commented 5 years ago

@alxwr -

true, and agreed on all points, and it DOES reduce dependencies. sometimes KISS is best. :) thanks for reviewing this!