I was trying to figure out why this error kept happening while testing salt states for ClamAV:
Mar 26 16:00:43 salt-master clamd: Fri Mar 26 16:00:43 2021 -> ^lchown to user 'root' failed on log file '/var/log/clamd.scan'. Error was 'Permission denied'
Mar 26 16:00:43 salt-master clamd: Fri Mar 26 16:00:43 2021 -> !daemonize() failed: Permission denied
The message itself was being written into the clamd.scan file so ... weird. Of
course, a getenforce 0
made the error stop, so we were clearly dealing with
something selinux-y.
SELinux fcontext
rules should specify the type assigned to files when they are created or when restorcon
is run. This looks "right" on first inspection...
[root@jerry ~]# semanage fcontext -l | egrep /var/log/clam
/var/log/clamd.* all files system_u:object_r:antivirus_log_t:s0
/var/log/clamav.* all files system_u:object_r:antivirus_log_t:s0
/var/log/clamav/freshclam.* regular file system_u:object_r:antivirus_log_t:s0
OK. So the file should be antivirus_log_t
, but it's not:
[root@jerry ~]# ls -lZ /var/log/clamd.scan
-rw-r--r--. root root unconfined_u:object_r:var_log_t:s0 /var/log/clamd.scan
The var_log_t
type is what the file gets when we make the file using a salt state
before the ClamAV daemon starts up. If we remove the file and then systemctl start clamd@scan
then the file gets the "right" antivirus_log_t
type.
Turns out, clamd
isn't DOING anything special. It's just making the file. The difference is
how clamd
gets started.
Clamd running under systemd, as seen by ps -Z
:
system_u:system_r:antivirus_t:s0 29945 ? Ssl 0:17 /usr/sbin/clamd -c /etc/clamd.d/scan.conf
Clamd running in the foreground started by me in the shell:
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 28639 pts/7 Sl+ 0:24 /usr/sbin/clamd --foreground
As a test:
[root@jerry ~]# rm -f /var/log/clamd.scan && touch /var/log/clamd.scan && ls -lZ /var/log/clamd.scan
-rw-r--r--. root root unconfined_u:object_r:var_log_t:s0 /var/log/clamd.scan
OK, touch
doesn't set the type on the file properly. Let's run touch
under a
more restricted SELinux scope:
[root@jerry ~]# setenforce 0
[root@jerry ~]# rm -rf /var/log/clamd.scan
[root@jerry ~]# runcon -c -u system_u -r system_r -t antivirus_t /bin/touch /var/log/clamd.scan
[root@jerry ~]# ls -Z /var/log/clamd.scan
-rw-r--r--. root root system_u:object_r:antivirus_log_t:s0 /var/log/clamd.scan
The setenforce
is necessary because normally SELinux won't allow /bin/touch
to transition
into the antivirus_t
type.