How to add custom SELinux filename transition rules in RHEL7 and later
Environment
- Red Hat Enterprise Linux 7
- Red Hat Enterprise Linux 8
- Red Hat Enterprise Linux 9
Issue
-
The Red Hat Enterprise Linux (RHEL) 7 SELinux User's and Administrator's Guide details a new file name transition feature and gives some policy examples but doesn't make it clear how a sysadmin could easily add a new rule. How can this be done?
-
An fcontext rule like the following makes it possible for
restorecon
to set/var/www/html/*/rwstorage
files to thehttpd_sys_rw_content_t
type:semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html(/.*)?/rwstorage"
However, the
restorecon
is always required, e.g.:~]# mkdir -p /var/www/html/vhost1/rwstorage ~]# stat -c "%C %n" /var/www/html/vhost1/{,rwstorage} unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/vhost1/ unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/vhost1/rwstorage ~]# restorecon /var/www/html/vhost1/rwstorage ~]# stat -c "%C %n" /var/www/html/vhost1/rwstorage unconfined_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html/vhost1/rwstorage
How can we make it so the manual
restorecon
isn't necessary in these situations? (And no we don't want to use the existing"/var/www/html(/.*)?/uploads"
rule.)
Resolution
Using restorecond
-
Some situations can be easily handled by the
restorecond
service (provided by the policycoreutils-restorecond package fromoptional
repository for RHEL 7 andBaseOS
repository for RHEL 8/9).- restorecond allows for adding watch-paths to the lists in
/etc/selinux/restorecond.conf
and/etc/selinux/restorecond_user.conf
- This doesn't solve all situations since the syntax only allows
*
in the last component of the target path (e.g.,/root/.ssh/*
is allowed but/var/www/html/*/rwstorage
is not)
- restorecond allows for adding watch-paths to the lists in
Using file name transition rules
-
See instructions outlined in this blog post by Red Hatter & SELinux guru Dan Walsh:
New SELinux Feature: File Name Transitions -
Alternatively, another Red Hatter wrote a unsupported script that automates the process:
GitHub - ryran/b19scripts/add-file-trans-rule.sh
For example:-
Download the script to a bin dir and make it executable
-
Check the license and the help page
[root@r72 ~]# grep '# ' $(which add-file-trans-rule.sh) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License <gnu.org/licenses/gpl.html> for more details. [root@r72 ~]# add-file-trans-rule.sh -h Usage: add-file-trans-rule.sh <TARGET_FILE> <TARGET_FILE_CLASS> Where TARGET_FILE is the file to get auto-labeled without requiring restorecon. Where TARGET_FILE_CLASS is most likely "file" or "dir" but could be anything returned by "seinfo --class" command. Example: 1. Add a rule to fcontext db first, e.g.: * semanage fcontext -a -t httpd_sys_rw_content_t \ "/var/www/html(/.*)?/rwstoragedir" * semanage fcontext -a -t httpd_sys_rw_content_t \ "/var/www/html/[^/]*/rwstoragefile" 2. Then execute this script, e.g.: add-file-trans-rule.sh /var/www/html/vhost1/bak/rwstoragedir dir add-file-trans-rule.sh /var/www/html/vhost2/rwstoragefile file Note that by default this will set the source process domain to "unconfined_t", which is suitable for triggering on actions that normal unconfined users make. This can be overridden by changing the "PROCESS_DOMAIN" environment variable. Note that the script will prompt for a module name unless the environment variable "NEW_MODULE_NAME" is set. It will also prompt if "NEW_MODULE_NAME" is set to the name of a currently loaded module, as listed by "semodule -l".
-
Create the desired fcontext rule and test that it works, e.g.:
[root@r72 ~]# semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html(/.*)?/rwstorage" [root@r72 ~]# mkdir -p /var/www/html/vhost1/rwstorage [root@r72 ~]# stat -c %C /var/www/html/vhost1/rwstorage unconfined_u:object_r:httpd_sys_content_t:s0 [root@r72 ~]# restorecon /var/www/html/vhost1/rwstorage [root@r72 ~]# stat -c %C /var/www/html/vhost1/rwstorage unconfined_u:object_r:httpd_sys_rw_content_t:s0
-
Execute the script as directed, e.g.:
[root@r72 ~]# add-file-trans-rule.sh /var/www/html/vhost1/rwstorage dir Missing packages Try: yum install selinux-policy-devel setools-console [root@r72 ~]# yum install selinux-policy-devel setools-console -y ... [root@r72 ~]# add-file-trans-rule.sh /var/www/html/vhost1/rwstorage dir Source process domain: "unconfined_t" Parent directory type: "httpd_sys_content_t" Target file: "rwstorage" Target class: "dir" About to create a file name transition policy module based on above specs. Cancel now if any of them are empty or incorrect. The new module will need a name. Names for loaded modules can be seen with the "semodule -l" command. Example: "my-filetrans-rwstorage" Enter a unique name for this new filetrans module: > my-filetrans-rwstorage Creating module files in tempdir: /tmp/tmp.addfiletrans.rwKR0U2CAI Executing: 'make -f /usr/share/selinux/devel/Makefile my-filetrans-rwstorage.pp' Compiling targeted my-filetrans-rwstorage module /usr/bin/checkmodule: loading policy configuration from tmp/my-filetrans-rwstorage.tmp /usr/bin/checkmodule: policy configuration loaded /usr/bin/checkmodule: writing binary representation (version 17) to tmp/my-filetrans-rwstorage.mod Creating targeted my-filetrans-rwstorage.pp policy package rm tmp/my-filetrans-rwstorage.mod.fc tmp/my-filetrans-rwstorage.mod Assuming the above command finished without issue ... The final step requires you to manually install the module yourself Execute the following command: semodule -i /tmp/tmp.addfiletrans.rwKR0U2CAI/my-filetrans-rwstorage.pp After that you should see your module in "semodule -l" You can then disable it with "semodule -d my-filetrans-rwstorage" Or re-enable it with "semodule -e my-filetrans-rwstorage" You can also uninstall (remove) it with "semodule -r my-filetrans-rwstorage"
-
Follow directions to install the module and confirm it works, e.g.:
[root@r72 ~]# semodule -i /tmp/tmp.addfiletrans.rwKR0U2CAI/my-filetrans-rwstorage.pp [root@r72 ~]# rmdir /var/www/html/vhost1/rwstorage [root@r72 ~]# mkdir /var/www/html/vhost1/rwstorage [root@r72 ~]# stat -c %C /var/www/html/vhost1/rwstorage unconfined_u:object_r:httpd_sys_rw_content_t:s0
-
Optionally disable and then re-enable it
[root@r72 ~]# semodule --disable my-filetrans-rwstorage [root@r72 ~]# mkdir -p /var/www/html/vhost2/rwstorage [root@r72 ~]# stat -c %C /var/www/html/vhost2/rwstorage unconfined_u:object_r:httpd_sys_content_t:s0 [root@r72 ~]# semodule --enable my-filetrans-rwstorage
-
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.
Comments