Alwanza dot net homepage link

Alwanza.net:  SELinux Essentials

SELinux is a Security program that is included and is enabled in "Enforcing Mode" by default in RedHat Enterprise 5 and CentOS 5 and newer.
SELinux sets a default "security context" for processes and files.  When used in "Enforcing mode", SELinux prevents processes from performing actions on files or other processes that are outside what their "security context" allows.

On PCI compliant servers we want to keep it running in Enforcing mode.  One example of the good it can do is that, if we had a break-in, it would prevent the intruder from making use of "elevation of privilege" to gain authority outside the "security context" of whatever process was compromised.  For example, Apache would not be permitted to create new users on the host.

Here is the easiest way to configure SELinux (theory):
  1. Put SELinux into Permissive mode when you need to (when something you want to do is blocked, and you suspect SELinux).  Putting SELinux into Permissive mode makes it LOG ONLY the access that when it is in Enforcing mode it would LOG and BLOCK.
  2. Use the information in the LOG to correct the SELinux settings on files/processes and then reset SELinux into Enforcing mode.
SELinux is a huge program/utility and there are multiple ways to accomplish what you need, and tune it into perfection.  This document will not be comprehensive, but will provide you with some tools for running SELinux in Enforcing mode and enough of the basics so that you will be able to search for more detailed answers if you need them.

Tools/Practice:

Enable/Disable SELinux

Is SELinux enabled?
getenforce (command, see responses below)
Enforcing (yes)
Permissive (SELinux is not enforcing rules, but is logging them)
Disabled (SELinux is turned off and completely ineffective)

setenforce 1 (You have just enabled SELinux - check it with getenforce)

sed -i 's/SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
After the above commands, SELinux is in Permissive mode

How to Read Audit Log

Reading the Audit Log doesn't actually help you fix unwanted denials, but it does help you identify what those denials were.  Events in the audit.log are logged from the top down with the most recent entries being at the bottom of the file.

sealert -a /var/log/audit/audit.log

grep denied /var/log/audit/audit.log

or (for nicer formatted output with readable date)

grep denied /var/log/audit/audit.log | ausearch -i | perl -pi -w -e 's/type=AVC\ msg=audit\(//;'| awk -F')' '{ print $1,$2,$3}'

Output Example:
type=AVC msg=audit(1430408350.334:704): avc:  denied { add_name } for pid=3414 comm="sshd" name="apple_servers.xlsx" scontext=system_u:system_r:chroot_user_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:usr_t:s0 tclass=dir

Output Example with readable date:
04/30/2015 08:46:51.831:732 : avc:  denied { write } for pid=3442 comm=sshd name=files dev=sdb1 ino=1798725 scontext=system_u:system_r:chroot_user_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:usr_t:s0 tclass=dir

SCONTEXT and TCONTEXT:
tcontext = Target Security Context:  The current SELinux label on the file, directory. 
scontext = Security Context that would be needed on the file or directory to permit the action you are attempting (that SELinux blocked if entry says "denied").

SELinux blocks actions when there is a mismatch between scontext and tcontext. Scontext and tcontext do not have to be the same, they just need to be compatible.  In general, you will want to correct the tcontext so that it matches or at least is compatible with the scontext.  If the contexts match and SELinux is still denying access, other reasons are possible.

How to Display the Current Security Context (tcontext) on a File or Directory

ls -ldZ /path/to/file
ls -ldZ /path/to/directory

How to Correct Security Contexts

The actual commands that provide the information that will facilitate correcting the security contexts are "audit2allow" or (my favorite) "audit2why" (which requires that you have rpm policycoreutils-python installed).  They need to have the audit log piped through them using cat.  Like so:

This example is specific for sshd audit alerts:
ausearch -c 'sshd' --raw |audit2allow -M my-sshd

cat /var/log/audit/audit.log | audit2allow
cat /var/log/audit/audit.log | audit2why

You will see manuals recommending you do things like this:

cat /var/log/audit/audit.log | audit2allow -m local > local.te
OR
grep <service> /var/log/audit/audit.log| audit2allow -M mypol
semodule -i mypol.pp

I recommend AGAINST that for the following reason:  You won't really know if you are solving the issue because you will never see the output of the command.  From experience, I know that many times this strategy does not work for exactly that reason.  Audit2why is much more likely to give you the answer you really need, so long as you actually read the output.

When "chcon" is the best choice:  chcon changes FILE security contexts for files that have already been imported or installed.  It is the best choice (used in conjunction with restorecon) when you do NOT want similarly installed or imported files to automatically receive the same security context.  In other words, it would be a bad choice to use on a directory where you expect users to be regularly importing or creating new files.

When "setsebool" is the best choice;  The Security Boolean is set either to 1 (true) or 0 (false).  If you include the '-P' switch, the settings will be persistent after reboots. 

To view all the sebooleans that are currently set on your system, use this command:
getsebool -a

To view the custom boolean settings that have been made on your host, you can look at this file:
/var/lib/selinux/targeted/modules/active/booleans.local

You cannot edit that file directly, but you can view other booleans that you have set so that you have an example for future "setsebool" rules and you can review the booleans that you have set so that you can change them if needed.  "setsebool" is the best choice when you want to make permanent and trackable changes to your environment.

Hidden SELinux Denials in the Audit.log

The normal settings on SELinux DO NOT log every denial.  This is to keep the log from getting cluttered with superfluous information, but it is possible that something you are trying to allow is in a Hidden SELinux Denial.  If you are pretty sure you are being blocked by SELinux but the denial is not showing up in the logs, you can set SELinux to log every denial, and after you have finished troubleshooting, set it back to its default.  The statements that are normally unlogged, when you can view them, will begin with "dontaudit".

To Log ALL Denials in SELinux:

semodule --disable_dontaudit -build
OR
semodule -DB

To Return to Logging Defaults:

semodule --build
OR
semodule -B

Practical Example

Here is your SELinux Alert:
type=AVC msg=audit(1431011563.381:3713): avc:  denied { signal } for pid=1273 comm="sshd" scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:system_r:chroot_user_t:s0-s0:c0.c1023 tclass=process
Was caused by:
Missing type enforcement (TE) allow rule.

You can use audit2allow to generate a loadable module to allow this access.

[root@safetruck1 audit]# grep 1273 audit.log |audit2allow

#============= sshd_t ==============

allow sshd_t chroot_user_t:process signal;

[root@safetruck1 audit]#

Did it already set the rule or do I have to manually?  You have to do it manually, but to display in order to be sure:
getsebool -a

allow sshd_t chroot_user_t:process signal;
[root@safetruck1 audit]# igrep 1273 audit.log |audit2allow -M
sftp_chroot_user_process_signal >sftp_chroot_user_process_signal.te
[root@safetruck1 audit]# ls -l
total 1312
-rw-------. 1 root root 1331131 May 7 09:12 audit.log
-rw-r--r--. 1 root root 947 May 7 09:31
sftp_chroot_user_process_signal.pp
-rw-r--r--. 1 root root 197 May 7 09:31
sftp_chroot_user_process_signal.te
[root@safetruck1 audit]# semodule -i sftp_chroot_user_process_signal.pp

Now test to see if the rule is in effect

[root@safetruck1 audit]# grep 1273 audit.log |audit2why
type=AVC msg=audit(1431011563.381:3713): avc:  denied { signal } for pid=1273 comm="sshd" scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:system_r:chroot_user_t:s0-s0:c0.c1023 tclass=process
Was caused by:
Unknown - would be allowed by active policy
Possible mismatch between this policy and the one under which the audit message was generated.

Possible mismatch between current in-memory boolean settings vs. permanent ones.
The above message states that there is a "mismatch" between "current policy" and the denial found in the selinux alert log.
If you see that message, you know you have successfully changed the policy.

References:

wiki.gentoo.org/wiki/SELinux/Tutorials/Where_to_find_SELinux_permission_denial_details
sites.google.com/site/technoidsorg/linux/selinux/selinux-glossary
And many thanks to Gary Smith and his lectures at Linuxfest Northwest!!!!