When we think that the context of a file is wrong, we need to correct the context. SELinux offers several methods to do so, and some distributions even add in more. We can use tools such as
restorecon (together with
rlpkg (Gentoo), and
fixfiles. Of course, we could also use the
setfattr command, but that would be the least user-friendly approach for setting contexts.
Let’s see how we can set context expressions in a more manageable way.
Using context expressions
In the SELinux policy, a list of regular expressions is kept that informs the SELinux utilities and libraries what the context of a file (or other filesystem resource) should be. Though this expression list is not enforced on the system directly, administrators and SELinux utilities use it to see whether a context is correct, and to reset contexts to what they are supposed to be. You can find the list itself in
/etc/selinux/targeted/contexts/files in the various
As an administrator, we can query this list through
semanage fcontext as follows:
# semanage fcontext -l SELinux fcontext type Context / directory system_u:object_r:root_t:s0 ... /vmlinuz.* symbolic link system_u:object_r:boot_t:s0 /xen(/.*)? all files system_u:object_r:xen_image_t:s0 ...
An example of a tool that queries this information is
matchpathcon, Understanding SELinux Decisions and Logging:
# matchpathcon /srv/web/localhost/htdocs/dokuwiki /srv/web/localhost/htdocs/dokuwiki system_u:object_r:var_t:s0
Not all the entries are visible through the
semanage application though. Entries related to specific user home directories (such as
/home/lisa/.ssh) are not shown as these entries depend on the Linux user (and, more importantly, its associated SELinux user).
- A regular expression that matches one or more paths
- The classes to which the rule is applicable, but translated into a more human-readable format
- The context to assign to the resources that match the expression and class list
The class list allows us to differentiate contexts based on the resource class. The
semanage fcontext output uses human-readable identifiers: resource classes can be a regular file (
--), a directory (
-d), a socket (
-s), a named pipe (
-p), a block device (
-b), a character device (
-c), or a symbolic link (
-l). When it says all files, the line is valid regardless of the class.
Right now, we have not defined such rules yet, but after the next section, even defining custom SELinux context expressions will no longer hold any secrets. An important property of the context list is how SELinux prioritizes its application – after all, we could easily have two expressions that both match a certain resource or path. Within SELinux, the most specific rule wins. The logic used is as follows (in order):
- If line A has a regular expression and line B doesn’t, then line B is more specific.
- If the number of characters before the first regular expression in line A is less than the number of characters before the first regular expression in line B, then line B is more specific.
- If the number of characters in line A is less than in line B, then line B is more specific.
- If line A does not map to a specific SELinux type (the policy editor has explicitly told SELinux not to assign a type) and line B does, then line B is more specific.
There is a caveat with the rule order, however. When additional rules are added through
semanage (which we describe in the next section), then SELinux’s utilities apply the rules in the order they were added rather than their specificity. So, instead of the most specific rule, the most recently added rule that matches the path is used.
Registering file context changes
Because changing an SELinux context using
chcon is often just a temporary measure, it is seriously recommended to only use
chcon when testing the impact of a context change. Once the change is acceptable, we need to register it through
semanage. For instance, to permanently mark
/srv/web (and all its subdirectories) as
httpd_sys_content_t, and the DokuWiki
conf/ folders as
httpd_sys_rw_content_t (to allow the web server to modify these resources), we need to execute the following:
# semanage fcontext -a -t httpd_sys_content_t "/srv/web(/.*)?" # semanage fcontext -a -t httpd_sys_rw_content_t "/srv/web/localhost/htdocs/dokuwiki/data(/.*)?" # semanage fcontext -a -t httpd_sys_rw_content_t "/srv/web/localhost/htdocs/dokuwiki/conf(/.*)?" # restorecon -Rv /srv/web
What we do here is register
/srv/web and its subdirectories as
httpd_sys_content_t and the two writable directories as
semanage. Then, we use
restorecon to (recursively) reset the contexts of
/srv/web to the value registered in the context list. This is the recommended approach for setting contexts on most resources.
These registrations are local (custom) context expressions and are stored in a separate configuration file (
file_contexts.local). Considering the priority of (locally added) expressions, it is important to have the most specific entries added last, as otherwise the more broadly defined rule for
httpd_sys_content_t would be applied to the entire directory. This is unlike the priority rules for (policy added) expressions that do have the concept of most specific rule wins.
semanage fcontext application can also be used to inform SELinux that a part of the filesystem tree should be labeled similarly as a different location on the filesystem. Such an equivalency rule allows us to use different paths for application installations or file destinations and tell
semanage to apply the same contexts as if the destination were the default.
Let’s make this more visible through an example, and have everything under
/srv/web be labeled in a similar manner to the files at
/var/www (including subdirectories), so
/srv/web/icons gets the same context as
/var/www/icons. We use the
-e option of
semanage fcontext to create such an equivalency as follows:
# semanage fcontext -a -e /var/www /srv/web # restorecon -Rv /srv/web
This will create a substitution entry so that anything under
/srv/web gets the same label as if it were at the same location under
Most distributions already configure a few equivalency rules that we can read as follows:
# cat /etc/selinux/targeted/contexts/files/file_contexts.subs_dist /run /var/run ... /sysroot/tmp /tmp
semanage fcontext -l command will show these equivalent locations at the end of its output as well.
Optimizing recursive context operations
restorecon application resets the SELinux context of files and other resources based on the context definitions managed through the SELinux policy and
semanage fcontext. When applying
restorecon in a recursive fashion against directories, this might take a while. To improve performance in this situation, the SELinux authors support the skipping of
-D option to
restorecon, an additional extended attribute will be written to the main directory that contains a hash of the file context definitions used when invoking the command:
# restorecon -RD /home
Subsequent invocations of
-D will check this hash to see whether any of the file context definitions that impact this directory have been modified (using
semanage fcontext). If there aren’t, then the restore operation will be skipped:
# restorecon -RvD /home Skipping restorecon as matching digest on: /home
# semanage fcontext -a -t httpd_user_content_t "/home/[^/]*/cgi-bin(/.*)?" # restorecon -RvD /home Relabeled /home/lisa/cgi-bin from staff_u:object_r:user_home_t:s0 to staff_u:object_r:httpd_user_content_t:s0 Updated digest for: /home
restorecon_xattr command can be used to manage these extended attributes (view or delete) and show how the attributes are formed:
# restorecon_xattr -v /home specfiles SHA1 digest: 7ed69be330ad60811481e455ca8e5ab0b1556036 calculated using the following specfile(s): /etc/selinux/targeted/contexts/files/file_contexts.subs_dist ... /etc/selinux/targeted/contexts/files/file_contexts.local.bin /home Digest: 7ed69be330ad60811481e455ca8e5ab0b1556036 Match
digest referenced is the
security.sehash extended attributes. More recent user space tools use the latter, and apply their logic to each subdirectory, whereas older user space utilities use the former and only apply their logic on the selected directory.
The disadvantage of the
security.restorecon_last usage is that it does not work with subdirectories: if we apply a recursive
restorecon operation against
/, then this tool will ignore the digest on
/home. With the
security.sehash usage, a recursive operation against
/ will check the digest for
/home as well.
Using customizable types
Some SELinux types are meant for files whose paths cannot be accurately defined by administrators or where the administrator does not want the context to be reset when a relabeling operation is triggered. For these purposes, SELinux supports what it calls customizable types. When tools that manage file contexts (such as
restorecon) encounter a file with a customizable type set, they will not revert its context to the registered context definition.
The customizable types are declared in the
customizable_types file inside
/etc/selinux/targeted/contexts. To have
restorecon relabel such files, administrators need to pass the force reset option (
-F) before the tool resets the contexts.
Let’s look at the contents of this
$ cat /etc/selinux/targeted/contexts/customizable_types container_file_t sandbox_file_t ... httpd_user_content_t git_session_content_t home_bin_t user_tty_device_t
$ chcon -t home_bin_t ~/convert.sh
Marking other types as customizable requires updating the
customizable_types file, as there is no user command that adds or removes type definitions from this list. Because this file can be overwritten when the distribution or administrator pushes out a new policy package, it needs to be governed carefully.
That said, the use of customizable types has its advantages. As an administrator, we might want to create and support specific types as usable by end users who can use
chcon to set the contexts of individual files in their home directory. By having those types marked as customizable types, a relabeling operation against
/home will not reset those contexts.
When the target type is not a customizable type, administrators generally prefer to use
semanage fcontext to add an expression and
restorecon to fix the context of the files. Most administrators will use directory-based labeling: this is much easier to maintain, and much easier to explain to end users. Many will even use this approach for customizable types:
# semanage fcontext -a -t home_bin_t "/home/[^/]*/bin(/.*)?"
With this command, user binaries and scripts located in the
~/bin directory will be labeled as
Compiling the different file_contexts files
/etc/selinux/targeted/contexts/files directory, five different
file_contexts files can be found:
file_contextsfile itself (without any suffix) is the basic expression file provided by the SELinux policy offered through the Linux distribution.
file_contexts.localfile contains the locally added rules (through the
semanage fcontextcommand, which we covered earlier in this chapter).
file_contexts.homedirsfile contains the expressions for the user home directories. When new user mappings are created and managed through
semanage user, this file is adjusted to reflect the new situation.
file_contexts.subs_distfile contains equivalency rules, provided by the distribution’s SELinux policy, which tell SELinux to consider one part of the filesystem as having the same labeling rules as another location.
file_contexts.subsfile contains locally managed equivalency rules (through the
Alongside those files, you will find associated
*.bin files (so
file_contexts.bin for the
file_contexts.local.bin for the
file_contexts.local file, and so on). These
*.bin files are automatically created, but in case of a discrepancy, administrators can rebuild the files themselves as well using the
# cd /etc/selinux/targeted/contexts/files # sefcontext_compile file_contexts.local
These files contain the same information as the main file, but are precompiled to make lookups faster. Unless the tools detect that the
*.bin files are older than their source files, the SELinux utilities will use the compiled versions of these files.
Exchanging local modifications
When local modifications are registered through
semanage fcontext, they only apply to a single system. If local definitions need to be reapplied on various systems, administrators can extract the local modifications and import them on another system.
To export the local modifications, use
# semanage export -f local-mods.conf
The file that contains the local modifications (
local-mods.conf in the example) can be adjusted at will. This allows administrators to remove all lines except those they want to apply on other systems.
# semanage import -f ./local-mods.conf
The imported settings are immediately registered. Of course, in case of filesystem changes (
semanage fcontext), don’t forget to run
restorecon against the target directories.