cepces icon indicating copy to clipboard operation
cepces copied to clipboard

Certmonger SELinux issues with /var/log/cepces

Open adam-kosseck opened this issue 2 years ago • 5 comments

Fresh test system built today (RHEL 8.6)

  1. Installed certmonger, cepces, cepces-selinux, cepces-certmonger packages all from EPEL8.
  2. Start certmonger service and see a large number of SELinux denials like this:
# ausearch -m avc -ts today
----
node=vm1.test.local type=PROCTITLE msg=audit(1666851329.447:180): proctitle=<LARGE GUID>
node=vm1.test.local type=PATH msg=audit(1666851329.447:180): item=0 name="/var/log/cepces/" inode=100971704 dev=fd:00 mode=040700 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:var_log_t:s0 nametype=PARENT cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0
node=vm1.test.local type=CWD msg=audit(1666851329.447:180): cwd="/"
node=vm1.test.local type=SYSCALL msg=audit(1666851329.447:180): arch=c000003e syscall=257 success=no exit=-13 a0=ffffff9c a1=7f5b2776e7d0 a2=80441 a3=1b6 items=1 ppid=1326 pid=1596 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="python3" exe="/usr/libexec/platform-python3.6" subj=system_u:system_r:certmonger_t:s0 key=(null)
node=vm1.test.local type=AVC msg=audit(1666851329.447:180): avc:  denied  { write } for  pid=1596 comm="python3" name="cepces" dev="dm-0" ino=100971704 scontext=system_u:system_r:certmonger_t:s0 tcontext=system_u:object_r:var_log_t:s0 tclass=dir permissive=0
----
  1. The above message appears 16 times
  2. No cepces.log file is written, however if SELinux is disabled and Certmonger restarted the logfile appears

This seems like it may be a rule that is missing from the cepces-selinux package?

adam-kosseck avatar Oct 27 '22 06:10 adam-kosseck

It'd be best if you opened a bug at redhat.

dmulder avatar Oct 27 '22 12:10 dmulder

Case 03348450 opened with Red Hat. I'm expecting push-back from support as the binaries were installed from EPEL, but will see how it goes!

adam-kosseck avatar Oct 27 '22 21:10 adam-kosseck

Hi David,

Red Hat support provided an excellent analysis of the issue, so I have included the full text below for you.


First, I understand that you tried to use audit2allow to create a custom policy in an attempt to solve the issue. Please note that the tool should never be used because it produces mostly invalid recommendations which may lower the security on the system in the end.

First step is to remove all the custom modules:

# semodule -r cepces cepces2 cepces3 Let's now check the AVCs. This is the only operation where I use audit2allow to quickly see what's going on:

$ audit2allow < var/log/audit/audit.log

#============= certmonger_t ==============
allow certmonger_t admin_home_t:file { create open read write };
allow certmonger_t var_log_t:dir { add_name write };

Here above we see 2 AVCs related to certmonger_t.

allow certmonger_t admin_home_t:file { create open read write }; states that the process running as certmonger_t tries to create a file labeled with admin_home_t, which is the context of /root directory.

Browsing the audit log (using ausearch -m avc,user_avc -i --input var/log/audit/audit.log, we can see this:

node=vm1.test.local type=PROCTITLE msg=audit(10/27/2022 23:40:42.979:960) : proctitle=/usr/sbin/certmonger -S -p /run/certmonger.pid -n
node=vm1.test.local type=PATH msg=audit(10/27/2022 23:40:42.979:960) : item=0 name=/root/ inode=100663425 dev=fd:00 mode=dir,550 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:admin_home_t:s0 nametype=PARENT cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0
node=vm1.test.local type=CWD msg=audit(10/27/2022 23:40:42.979:960) : cwd=/
node=vm1.test.local type=SYSCALL msg=audit(10/27/2022 23:40:42.979:960) : arch=x86_64 syscall=openat success=no exit=EACCES(Permission denied) a0=0xffffff9c a1=0x5582f73f6d90 a2=O_RDWR|O_CREAT|O_EXCL a3=0x180 items=1 ppid=1309 pid=1969 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=certmonger exe=/usr/sbin/certmonger subj=system_u:system_r:certmonger_t:s0 key=(null)
node=vm1.test.local type=AVC msg=audit(10/27/2022 23:40:42.979:960) : avc:  denied  { create } for  pid=1969 comm=certmonger name=computer.key scontext=system_u:system_r:certmonger_t:s0 tcontext=system_u:object_r:admin_home_t:s0 tclass=file permissive=0

In a nutshell we have the process /usr/sbin/certmonger trying to create /root/computer.key, which is not allowed. I guess it's not certmonger but a child probably.

Let's now check what is available in the policy:

# sesearch -A -s certmonger_t -c file -p create
...
allow certmonger_t certmonger_tmp_t:file { append create getattr ioctl link lock map open read rename setattr unlink write };
...
allow certmonger_t certmonger_var_run_t:file { append create getattr ioctl link lock map open read rename setattr unlink write };
...

Here above we can see it's not possible, but it's possible to create files in /tmp or /var/run. This is because of the following transitions:

# sesearch -T -s certmonger_t -c file -t tmp_t
type_transition certmonger_t tmp_t:file certmonger_tmp_t;
...

# sesearch -T -s certmonger_t -c file -t var_run_t
type_transition certmonger_t var_run_t:file certmonger_var_run_t;

The solution is hence to create the file in a temporary directory instead. If this is not possible, then you need to have your certmonger child be labeled differently, to not have the child execute in the context of the service (certmonger_t), but "somehow unconfined" (:

# sesearch -T -s certmonger_t -c process
...
type_transition certmonger_t certmonger_unconfined_exec_t:process certmonger_unconfined_t;
...

Indeed, once the child executes as certmonger_unconfined_t, it can write to wherever it wants, including admin_home_t:

# sesearch -A -s certmonger_unconfined_t -c file -p create -t admin_home_t
allow files_unconfined_type file_type:file { append audit_access create execute execute_no_trans getattr ioctl link lock map mounton open quotaon read relabelfrom relabelto rename setattr swapon unlink write };

For this to happen, the child process needs to be labeled with certmonger_unconfined_exec_t, which is automatically done when putting the script in the following directory:

# semanage fcontext -l | grep certmonger_unconfined_exec_t
/usr/lib/ipa/certmonger(/.*)?                      all files          system_u:object_r:certmonger_unconfined_exec_t:s0 

For the other AVC on var_log_t:

allow certmonger_t var_log_t:dir { add_name write }; Below is an example:

node=vm1.test.local type=PROCTITLE msg=audit(10/27/2022 23:45:58.564:998) : proctitle=python3 /usr/libexec/certmonger/cepces-submit --server=ca.test.local --keytab=/etc/krb5.keytab
node=vm1.test.local type=PATH msg=audit(10/27/2022 23:45:58.564:998) : item=0 name=/var/log/cepces/ inode=100971704 dev=fd:00 mode=dir,700 ouid=root ogid=root rdev=00:00 obj=system_u:object_r:var_log_t:s0 nametype=PARENT cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0
node=vm1.test.local type=CWD msg=audit(10/27/2022 23:45:58.564:998) : cwd=/
node=vm1.test.local type=SYSCALL msg=audit(10/27/2022 23:45:58.564:998) : arch=x86_64 syscall=openat success=no exit=EACCES(Permission denied) a0=0xffffff9c a1=0x7fb6169c2850 a2=O_WRONLY|O_CREAT|O_APPEND|O_CLOEXEC a3=0x1b6 items=1 ppid=2004 pid=2040 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=python3 exe=/usr/libexec/platform-python3.6 subj=system_u:system_r:certmonger_t:s0 key=(null)
node=vm1.test.local type=AVC msg=audit(10/27/2022 23:45:58.564:998) : avc:  denied  { add_name } for  pid=2040 comm=python3 name=cepces.log scontext=system_u:system_r:certmonger_t:s0 tcontext=system_u:object_r:var_log_t:s0 tclass=dir permissive=0

The root cause is similar, there is no way for the process to create logs. For this to happen, /usr/libexec/certmonger/cepces-submit needs to run unconfined, hence be labeled with certmonger_unconfined_exec_t. This however requires the vendor to fix the contexts through shipping a SELinux policy, because by default everything in /usr/libexec/certmonger/ will run in the context of the parent, certmonger_t, due to the files being labeled with bin_t:

# matchpathcon /usr/libexec/certmonger/cepces-submit
/usr/libexec/certmonger/cepces-submit    system_u:object_r:bin_t:s0

adam-kosseck avatar Nov 03 '22 01:11 adam-kosseck

Note that the feature is currently in development in Fedora!

cryptomilk avatar Nov 03 '22 06:11 cryptomilk

Hi @cryptomilk do you mean that it's being implemented in SELinux on Fedora?

adam-kosseck avatar Nov 07 '22 06:11 adam-kosseck