My current understanding is that you have to manually use restorecon
to apply the desired context to a newly created file or directory unless you are happy with the context that it inherits from its parent directory.
I am wondering if it is possible to automatically apply a context on creation based on its path without having to run restorecon
.
I googled a bit and found this post by Dan Walsh where he mentions restorecond
which uses inotify
to change context on creation. He also points out the obvious problem with it (race condition). Is this the only way to automatically solve the issue of re-context-ing in case a child should not inherit its context from the parent directory?
One problem is that restorecond
does not seem to handle entries the same way as /etc/selinux/targeted/contexts/files/file_contexts
, that is, no regexes and it does not work recursively, so /etc/selinux/restorecond.conf
cannot contain something like
/var/www(/.*)?/logs(/.*)?
or
/var/www/*
or even
/var/www/*/logs
Is there a way to work around this problem?
EDIT:
As per @Michael's answer this should work OOTB if a respective rule exists, but it doesn't:
# rm -rf /var/www/foo
# semanage fcontext -a -t httpd_log_t '/var/www/foo/logs'
# grep '/var/www.*logs' /etc/selinux/targeted/contexts/files/file_contexts*
/etc/selinux/targeted/contexts/files/file_contexts:/var/www(/.*)?/logs(/.*)? system_u:object_r:httpd_log_t:s0
/etc/selinux/targeted/contexts/files/file_contexts.local:/var/www/foo/logs system_u:object_r:httpd_log_t:s0
# matchpathcon /var/www/foo/logs
/var/www/foo/logs system_u:object_r:httpd_log_t:s0
# mkdir -p /var/www/foo/logs
# touch /var/www/foo/logs/quux
# ls -alZ /var/www/foo/logs*
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 .
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 ..
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 quux
# restorecon -vR /var/www/foo
restorecon reset /var/www/foo/logs context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_log_t:s0
restorecon reset /var/www/foo/logs/quux context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_log_t:s0
Best Answer
The kernel makes the following procedure to determine what the file type of a newly created file will be.
In the vast majority of cases, new files inherit the parent directories type. Sometimes this is not desirable -- so a policy writer can create rules based off the conditions of who is doing the labelling and where in order to transition to another type.
This is controlled in policy with the
type_transition
statement, although normally a policy writer will call thefiletrans_pattern
macro instead.In the kernel, these decisions are not based on paths but types (although a minor exception exists in newer policies).
A rule typically looks like this;
type_transition httpd_t var_log_t:file httpd_var_log_t;
In this example, the rule states that. If the process/user performing the file creation is
httpd_t
and the directory the object is being created in isvar_log_t
and the object is classified as afile
, then the new file must be labelled ashttpd_var_log_t
.This, of course has a number of limitations, a good example of this is the condition when you create .htaccess files in apache (in /var/www/html). In this example the default policy of creating a file type with the same type as its parent directory applies, but in reality the proper type of this file is
httpd_sys_htacess_t
not the default ofhttpd_sys_content_t
.This was a known problem for a number of years and was eventually fixed by allowing policy writers to specify the filename that the transition applies to in policy -- unfortunately this features is not available in EL6.
In your specific case -- as you have mentioned there are some workarounds involving restorecond. Other than this you should ideally split your data up with different types by putting them in separate subdirectories where the subdirectory is an adequately labelled type. If this is still not possible, and restorecond is not possible -- the only solution is a post-fix of running restorecon on the file after its creation.
Even the 'newer' named filetrans has problems because ultimately it does not support globbing or regex, which severely limits its functionality to specifically well-named files (like .htaccess).
As it stands at this moment, there exists no in-kernel mechanism as flexible as
restorecon
and its regexes to properly label files correctly to that degree.