If you are unsure it's SELinux, first try temporarily disabling SELinux enforcing
sudo setenforce 0 SELinux Ref and run the code that was failing. If it is SELinux read on..
I ran into this issue recently and was pretty unfamiliar with SELinux so it was a bit of a learning curve for me. Unlike (DAC) standard posix mode permissions using
chown, SELinux is a lot more granular with it's permissions. It will in certain cases deny specific operations such as connecting to the internet over TCP/443, or allow writing to /foo & /bar, but nowhere else etc. depending on the caller (application).
To view a files (MAC) mandatory access control permissions
ls -Z or users
id -Z with output in the
In my case on Centos7 I had a script called in a logrotate.d conf file with a prerotate script that would upload a logfile before it was rotated. I was having several denials (logged to
/var/log/audit/audit.log). I learned you can use a few tools to generate specific policy package to install. I am creating .rpm packages for our code, so I added all the steps below to the .spec file to generate & install a policy package during time of install.
What you'll need: policycoreutils-python, checkpolicy (might already be installed)
From what I understand if you plan on distributing this security policy the idea is you want to only ship the *.te file and generate the policy onsite so if the definitions that policy relies on get updated, they will be inherited at time of install.
#finding the denial messages
watch "tail /var/log/audit/audit.log | grep 'denied'"
# creating the te (type enforcement) file (human readable security policy)
grep 1561055176.928:11371 /var/log/audit/audit.log|audit2allow -m myapp > myapp.te
# you can also grep a few failures and pipe them all to audit2allow
cat /var/log/audit/audit.log | grep logrotate | audit2allow -m myapp > myapp.te
# you can also use audit2why to give you a little explanation of why it failed sometimes with remediation steps
cat /var/log/audit/audit.log | grep logrotate | audit2why
WARNING During this step I found audit2why reporting my script would work if I ran
setsebool -P nis_enabled 1. While that sounds fine and dandy you should always lookup what the security implications are of running those commands. Setting this may broaden your attack surface, so user beware.
# build a policy module from type enforcement file
checkmodule -M -m -o myapp.mod myapp.te
# build a policy package from policy module
semodule_package -o myapp.pp -m myapp.mod
# load policy package with root privs
semodule -i myapp.pp
I had to do these steps several times until I had accumulated all the tiny permissions my code needed to operate.
-- update --
I ended up running my script inline just before the logrotate cron task so that I didn't have to expand logrotate_t's permissions. I had it in prerotate because I wanted not to rotate the file on failures, which this syntax still satisfies. Using the '&&' syntax if the 1st command fails it won't execute the 2nd.
10 * * * * root /usr/bin/sudo -i -u otheruser /opt/send_logs.sh && /usr/sbin/logrotate -f /path/to/myapp_logrotate.conf > /tmp/myapp_rotate.log 2&1