April 29th, 2009

Confining Service with SELinux

We have begun working on a guide to define how to confine different services with SELinux.  I have written on this before and am preparing talks on Top three things to understand in fixing SELinux problems.

I think giving real world examples is helpful.

Daniel Thurman posted the following to the fedora-list@redhat.com

I am trying to get my CVS repository setup.  Apparently,
it appears that the repository must be in the root directory,
otherwise I get selinux permission denials.

What I tried to do initially was to locate the repository
on a NTFS filesystem for which the context is fusefs
which could not be changed, no matter what I tried.
I got selinux permission errors.

Giving that up, I moved the repository to a ext3 filesystem
located on a separate drive/partition, mounted on /f-App1,
where the repository is located @ /f-App1/Develop/cvs, and did:

cd /f-App1/Develop/
chown -R cvs:cvs cvs
chcon -R -t cvs_data_t cvs
find cvs -type d -exec chmod 755 {} \;
find cvs -type t -exec chmod 754 {} \;
ln -s /f-App1/Develop/cvs /cvs

and I got selinux complaining that the files are not /cvs rooted.

So I did:

cp -a /f-App1/Develop/cvs  /cvs1
rm -f /cvs
ln -s /cvs1 /cvs

And it worked.

How can I place my repository in a non-rooted, non-standard
repository location and avoid the selinux complaints?

SELinux is all about labeling.  The problem Daniel is having here is the cvs daemon is running as cvs_t.  It is only allowed to read/write certain directories/files based on their labels (cvs_data_t).  He executes the appropriate commands to set the DAC permissions and even attempts to set the label to the correct type for SELinux, cvs_data_t.  The problem is he ignored the directories above.  So cvs_t is not allowed to search through the directories /F-app1/Develop directory to find it's data.  If he had executed  chcon -R -t cvs_data_t /F-app1,  the entire directory tree would have the context cvs_data_t  which the cvs daemon (cvs_t) can read and traverse. 

Directories created under / get a label of default_t, by default.  All files/directories created in these top level directories then inherit the default_t label.  Confined domains can not read default_t since we do not know the value of the data created in these directories.  Therefore is is more secure to deny by default. 

One other common mistake that Daniel is making here is the use of chcon.  chcon changes the labeling of the files/directories, but does not tell the system about this alternate labeling.  If a relabel gets triggered on the system, for any reason, these labels could get changed back to the default.   You need to tell the system about the alternate labeling using the "semanage fcontext" command.

# semanage fcontext -a -t cvs_data_t '/F-app1(/.*)?'
# restorecon -R -v /F-app1

Makes the changes permanent.

One last point, Daniel states that he tried to start put the CVS data repository on an NTFS mount point, but SELinux does not allow the cvs daemon (cvs_t) access to the fusefs (fusefs_t) file system.  Daniel tried to change the label on the NTFS file system, but he quickly found out that NTFS does not support extended attributes and therefore does not support SELinux labels.  

  1. He has two ways to make this work.  He could have made a local modification to SELinux policy using audit2allow, to allow the cvs_t access to fusefs_t.
# grep fusefs /var/log/audit/audit.log | audit2allow -M mycvs
# semodule -i mycvs.pp

This will make a permanent change to SELinux policy that allows cvs_t access to all fusefs file systems.

  1. Another solution would be to just change the file context on this ntfs file system mount point.

mount -o context=system_u:object_r:cvs_data_t:s0 NTFSDEVICE /F-app1

Which would tell the kernel that all files mounted at F-app1 will be labeled cvs_data_t.

If the only fusefs file system on this server is for cvs, the first solution is fine.  Also if you want other confined domains to access the NTFS file system, it might be better.  On the other hand, if you have multiple NTFS/Fusefs file systems it would probably be more secure to only label the one NTFS file system as being accessible by CVS, using the mount option.