Troubleshooting SELinux is not as straightforward as it may seem as at the time of writing this book, there is no integration with SELinux to return SELinux-related events back to the applications. Usually, you will find that access is denied with no further description of it in log files.
Make sure that setroubleshoot-server
and setools-console
are installed by executing the following command:
~# yum install -y setroubleshoot-server setools-console
If you have X server installed on your system, you can also install the GUI, as follows:
~# yum install -y setroubleshoot
Make sure that auditd
, rsyslog
, and setroubleshootd
are installed and running before reproducing the issue.
There are several ways to detect SELinux issues.
This is a classic issue where the SELinux context of a file is incorrect, causing the application trying to access the file to fail.
In this case, the context of /var/www/html/index.html
is set to system_u:object_r:user_home_t:s0
instead of system_u:object_r:httpd_sys_content_t:s0
, causing httpd
to throw a 404
. Take a look at the following command:
# ls -Z /var/www/html/index.html -rw-r--r--. apache apache system_u:object_r:user_home_t:s0 /var/www/html/index.html ~#
Use the following command to look for denied or failed entries in the audit log:
~# egrep 'avc.*denied' /var/log/audit/audit.log ype=AVC msg=audit(1438884962.645:86): avc: denied { open } for pid=1283 comm="httpd" path="/var/www/html/index.html" dev="dm-5" ino=1089 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:user_home_t:s0 tclass=file ~#
You can look for SELinux messages in /var/log/messages
via the following command:
~# grep 'SELinux is preventing' /var/log/messages Aug 6 20:16:03 localhost setroubleshoot: SELinux is preventing /usr/sbin/httpd from read access on the file index.html. For complete SELinux messages., run sealert -l dc544bde-2d7e-4f3f-8826-224d9b0c71f6 Aug 6 20:16:03 localhost python: SELinux is preventing /usr/sbin/httpd from read access on the file index.html. ~#
Use the audit search tool to find SELinux errors, as follows:
~# ausearch -m avc time->Thu Aug 6 20:16:02 2015 type=SYSCALL msg=audit(1438884962.645:86): arch=c000003e syscall=2 success=yes exit=25 a0=7f1bcfb65670 a1=80000 a2=0 a3=0 items=0 ppid=1186 pid=1283 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) type=AVC msg=audit(1438884962.645:86): avc: denied { open } for pid=1283 comm="httpd" path="/var/www/html/index.html" dev="dm-5" ino=1089 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:user_home_t:s0 tclass=file type=AVC msg=audit(1438884962.645:86): avc: denied { read } for pid=1283 comm="httpd" name="index.html" dev="dm-5" ino=1089 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:user_home_t:s0 tclass=file ~#
Once we restore the context of /var/www/html/index.html
to its original, the file is accessible again. Take a look at the following commands:
~# restorecon /var/www/html/index.html ~# ls -Z /var/www/html/index.html -rw-r--r--. apache apache system_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html ~#
It's not always easy to determine whether a file has the correct context. To view the actual SELinux context and compare it to what it should be without modifying anything, execute this command:
~# matchpathcon -V index.html index.html has context system_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0 ~#
This tells you what the current context is and what it should be.
As you can see in the preceding syslog example, the output comes with the following command:
... run sealert -l dc544bde-2d7e-4f3f-8826-224d9b0c71f6
This command provides you with a richer description of the problem:
~# sealert -l dc544bde-2d7e-4f3f-8826-224d9b0c71f6 SELinux is preventing /usr/sbin/httpd from read access on the file index.html. ***** Plugin catchall_boolean (89.3 confidence) suggests ****************** If you want to allow httpd to read user content Then you must tell SELinux about this by enabling the 'httpd_read_user_content' boolean. You can read 'None' man page for more details. Do setsebool -P httpd_read_user_content 1 ***** Plugin catchall (11.6 confidence) suggests ************************** If you believe that httpd should be allowed read access on the index.html file by default. Then you should report this as a bug. You can generate a local policy module to allow this access. Do allow this access for now by executing: # grep httpd /var/log/audit/audit.log | audit2allow -M mypol # semodule -i mypol.pp Additional Information: Source Context system_u:system_r:httpd_t:s0 Target Context system_u:object_r:user_home_t:s0 Target Objects index.html [ file ] Source httpd Source Path /usr/sbin/httpd Port <Unknown> Host localhost.localdomain Source RPM Packages httpd-2.4.6-31.el7.rhel.x86_64 Target RPM Packages Policy RPM selinux-policy-3.13.1-23.el7_1.7.noarch Selinux Enabled True Policy Type targeted Enforcing Mode Permissive Host Name localhost.localdomain Platform Linux localhost.localdomain 3.10.0-229.4.2.el7.x86_64 #1 SMP Wed May 13 10:06:09 UTC 2015 x86_64 x86_64 Alert Count 1 First Seen 2015-08-06 20:16:02 CEST Last Seen 2015-08-06 20:16:02 CEST Local ID dc544bde-2d7e-4f3f-8826-224d9b0c71f6 Raw Audit Messages type=AVC msg=audit(1438884962.645:86): avc: denied { read } for pid=1283 comm="httpd" name="index.html" dev="dm-5" ino=1089 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:user_home_t:s0 tclass=file type=AVC msg=audit(1438884962.645:86): avc: denied { open } for pid=1283 comm="httpd" path="/var/www/html/index.html" dev="dm-5" ino=1089 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:user_home_t:s0 tclass=file type=SYSCALL msg=audit(1438884962.645:86): arch=x86_64 syscall=open success=yes exit=ENOTTY a0=7f1bcfb65670 a1=80000 a2=0 a3=0 items=0 ppid=1186 pid=1283 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm=httpd exe=/usr/sbin/httpd subj=system_u:system_r:httpd_t:s0 key=(null) Hash: httpd,httpd_t,user_home_t,file,read ~#
This will actually give you more details about the problem at hand, and it will also make a couple of suggestions. Of course, in this case, the real solution is to restore the SELinux context of the file.
If you have installed a graphical desktop environment, you will get a notification each time your system encounters an "AVC denied" alert:
Clicking on the icon will present you with the following dialog:
Clicking on the Troubleshoot button will provide you with additional information and a (or multiple) possible solution(s) for your problem, as shown in the following screenshot:
In this case, the first option (the one marked with a green line) is the correct solution.
Some AVC denial messages may not be logged when SELinux denies access. Applications and libraries regularly probe for more access than is actually required to perform their tasks. In order to not flood the audit logs with these kinds of messages, the policy can silence the AVC denials that are without permissions using dontaudit
rules. The downside of this is that it may make troubleshooting SELinux denials more difficult.
To disable the dontaudit
rules, execute the following command:
~# semanage dontaudit off
This will disable the dontaudit
rules and rebuild the SELinux policy.
It is advisable to reenable the dontaudit
rules when you're done troubleshooting as this may flood your disks. You can do this by executing the following command:
~# semanage dontaudit on
To get a full list of dontaudit
rules, run the following:
~# sesearch --dontaudit Found 8361 semantic av rules: dontaudit user_ssh_agent_t user_ssh_agent_t : udp_socket listen ; dontaudit openshift_user_domain sshd_t : key view ; dontaudit user_seunshare_t user_seunshare_t : process setfscreate ; dontaudit ftpd_t selinux_config_t : dir { getattr search open } ; dontaudit user_seunshare_t user_seunshare_t : capability sys_module ; dontaudit xguest_dbusd_t xguest_dbusd_t : udp_socket listen ; dontaudit tuned_t tuned_t : process setfscreate ; ... ~#
If you know the domain that you wish to check for dontaudit
rules, add the -s
argument followed by the domain, as shown here:
~# sesearch --dontaudit -s httpd_t Found 182 semantic av rules: dontaudit httpd_t snmpd_var_lib_t : file { ioctl read write getattr lock open } ; dontaudit domain rpm_var_lib_t : file { ioctl read write getattr lock append } ; dontaudit httpd_t snmpd_var_lib_t : dir { ioctl read getattr lock search open } ; dontaudit domain rpm_var_lib_t : dir getattr ; dontaudit httpd_t snmpd_var_lib_t : lnk_file { read getattr } ; ... ~#