Discussion:
certmonger post-save scripts & certmonger_unconfined_t domain
Sam Morris
4 years ago
Permalink
Certmonger allows for the configuration of a post-save command to be run after it has obtained new certificates. This can be used to copy the key & certificates out of wherever certmonger is allowed to put them, and save them elsewhere with a particular owner/group, combine the certificate & chain into a single file as required by some software, etc.

The problem comes with SELinux which prevents my post-save scripts from being able to do all of that. I thought the solution was to give the scripts the context of certmonger_unconfined_exec_t, which would cause a transition to the certmonger_unconfined_t domain which is as its name suggests unconfined; but I can't get this to work.

I'm trying to use runcon to simulate certmonger executing a fake script:

# cat /tmp/fakescript
#!/bin/bash
set -eu
id -Z

# /tmp/fakescript
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

# ls -Z /tmp/fakescript
unconfined_u:object_r:certmonger_unconfined_exec_t:s0 /tmp/fakescript

# runcon system_u:system_r:certmonger_t:s0 /tmp/fakescript
runcon: ‘/tmp/fakescript’: Permission denied

Here is the avc denial:

----
type=PROCTITLE msg=audit(27/04/21 16:16:47.156:153492) : proctitle=runcon system_u:system_r:certmonger_t:s0 /tmp/fakescript
type=SYSCALL msg=audit(27/04/21 16:16:47.156:153492) : arch=x86_64 syscall=execve success=no exit=EACCES(Permission denied) a0=0x7ffd8aa768ab a1=0x7ffd8aa75888 a2=0x7ffd8aa75898 a3=0x0 items=0 ppid=177795 pid=177796 auid=sam.admin uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts5 ses=103 comm=runcon exe=/usr/bin/runcon subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=AVC msg=audit(27/04/21 16:16:47.156:153492) : avc: denied { entrypoint } for pid=177796 comm=runcon path=/tmp/fakescript dev="dm-0" ino=33563064 scontext=system_u:system_r:certmonger_t:s0 tcontext=unconfined_u:object_r:certmonger_unconfined_exec_t:s0 tclass=file permissive=0

Even though:

# sepolicy transition -s certmonger_t -t certmonger_unconfined_t
certmonger_t @ certmonger_unconfined_exec_t --> certmonger_unconfined_t

Diving in a little deeper, I can see that certmonger can execute the file:

# sesearch -s certmonger_t -t certmonger_unconfined_exec_t -c file -p execute -A
allow certmonger_t certmonger_unconfined_exec_t:file { execute execute_no_trans getattr ioctl map open read };

... and that the file type is an entrypoint for the certmonger_unconfined_t domain:

# sesearch -s certmonger_unconfined_t -t certmonger_unconfined_exec_t -c file -p entrypoint -A
allow certmonger_unconfined_t certmonger_unconfined_exec_t:file { entrypoint execute getattr ioctl lock map open read };

... and that transition is permitted from certmonger_t:

# sesearch -s certmonger_t -t certmonger_unconfined_t -c process -p transition -A
allow certmonger_t certmonger_unconfined_t:process transition;

Which leaves me scratching my head, unsure why it doesn't work in practice...

--
Sam Morris <https://robots.org.uk/>
PGP: rsa4096/CAAA AA1A CA69 A83A 892B 1855 D20B 4202 5CDA 27B9
_______________________________________________
selinux mailing list -- ***@lists.fedoraproject.org
To unsubscribe send an email to selinux-***@lists.fedoraproject.org
Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: https://lists.fedoraproject.org/archives/list/***@lists.fedoraproject.org
Do not reply to spam on the list, report i
Zdenek Pytela
4 years ago
Permalink
...
Hi,

runcon is a useful tool, but its usage is a bit tricky: it can be used to
run a process in a different context, but only if policy allows it. Namely,
it uses setexeccon(3) to set the new process context and on the very next
execvp(2) the context is checked and the change evaluated.

You are right with your commands how to check the 3 important parts to
allow a transition. However, in your first command, you see the shell is
running in unconfined_t. Is there a transition allowed to certmonger_t?

# sesearch -T -s unconfined_t -c process |grep certmonger_t
<>

No. You would actually need a 3-link chain (certmonger_initrc_exec_t,
certmonger_exec_t, certmonger_unconfined_exec_t), so it'd be worth writing
a custom policy if you need to have it working from console. I still don't
quite understand what is to be done there though. For instance, which
process executes the post-save commands? Are there any audit records when
it fails? Are there additional error messages in journal?
Post by Sam Morris
--
Sam Morris <https://robots.org.uk/>
PGP: rsa4096/CAAA AA1A CA69 A83A 892B 1855 D20B 4202 5CDA 27B9
_______________________________________________
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
https://pagure.io/fedora-infrastructure
--
Zdenek Pytela
Security SELinux team
Sam Morris
4 years ago
Permalink
...
Ah, so I needed to look at the SYSCALL event, which has
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023, in order to
realise that I wasn't really launching the script from the domain that
I thought I was...

Thanks for explaining that.
Post by Zdenek Pytela
I still don't quite understand what is to be done there though. For
instance, which process executes the post-save commands? Are there
any audit records when it fails? Are there additional error messages
in journal?
In the particular case I was debugging, it looks like certmonger
renewed the certificate a long time ago an this useful information
has been rotated away.

So, rather than repeatedly renewing the certificate until I got the
script working, I wanted to use runcon to simulate certmonger running
my script so that I could find out if it was SELinux that prevented the
script from working.

Now I understand that the problem was really my assumption that I 
understood how to use runcon to diagnose this sort of problem. :)

I've now gone back to certmonger and created a tracking request using
the SelfSign CA, which I can renew as many times as I want while
debugging the script. I've used that to prove that
certmonger_unconfined_exec_t does work as expected, and that the
problem was therefore with my post-save script and nothing to do with
SELinux policy.

Since the existence and usage of certmonger_unconfined_t is a bit
under-documented IMO, here's how I proved to myself that this domain
can be used to allow certmonger to launch post-save command scripts
that are able to do things that certmonger itself is not:

This script tries to create a file in /etc, which SELinux policy will
prevent:

$ cat /tmp/fakescript.unconfined
#!/bin/sh
set -eu -o pipefail
id > /etc/fakercert-id -Z

Here's how to use the SelfSign CA to creat a certificate and then
invoke the
script:

# selfsign-getcert request -w -v -I fakecert -f
/etc/pki/tls/certs/fakescript.crt -k
/etc/pki/tls/private/fakescript.key -C /tmp/fakescript.unconfined
New signing request "fakecert" added.
State NEWLY_ADDED_READING_CERT, stuck: no.
State GENERATING_CSR, stuck: no.
State POST_SAVED_CERT, stuck: no.
State MONITORING, stuck: no.


That causes this avc denial; as expected, certmonger_t is not allowed
to modify
etc_t:

type=AVC msg=audit(28/04/21 11:10:01.147:164884) : avc: denied {
create }
for pid=187115 comm=fakescript.unconfined name=fakercert-id
scontext=system_u:system_r:certmonger_t:s0
tcontext=system_u:object_r:etc_t:s0
tclass=file permissive=0


After using chcon to change the type of the script to
certmonger_unconfined_exec_t:

$ ls -Z /tmp/fakescript.unconfined
unconfined_u:object_r:certmonger_unconfined_exec_t:s0
/tmp/fakescript.unconfined


... I can tell certmonger to renew the certificate. In doing so it will
launch the script--now with the right type to trigger transition to
certmonger_unconfined_t:

# getcert resubmit -i fakecert -w -v
Resubmitting "fakecert" to "SelfSign".
State GENERATING_CSR, stuck: no.
State NOTIFYING_ISSUED_SAVED, stuck: no.
State MONITORING, stuck: no.


There's now no avc denial, hurrah! And here's the created file:

# cat /etc/fakercert-id
context=system_u:system_r:certmonger_unconfined_t:s0


I hope someone else finds that helpful some day!
--
Sam Morris <https://robots.org.uk/>
PGP: rsa4096/CAAA AA1A CA69 A83A 892B 1855 D20B 4202 5CDA 27B9

_______________________________________________
selinux mailing list -- ***@lists.fedoraproject.org
To unsubscribe send an email to selinux-***@lists.fedoraproject.org
Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: https://lists.fedoraproject.org/archives/list/***@lists.fedoraproject.org
Do not reply to spam on the list, report it: https://pagure.io/fedo
Zdenek Pytela
4 years ago
Permalink
Hi,

If I understand correctly, your problem is gone now. If you need some
additional help, feel free to reply back.
...
The target context is etc_t, but the only file/dir in the path with this
type should be /etc.
It is a good idea to relabel some parts of the filesystem before in-deep
troubleshooting:

# /sbin/restorecon -Rv /etc

or setup the machine to relabel all filesystems on the next reboot:

# fixfiles onboot
and reboot the system.
...
--
Zdenek Pytela
Security SELinux team
Loading...