Alwanza dot net homepage link  SELinux Essentials

SELinux is a Security program that is included and is ON (meaning: 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 many ways to accomplish the same thing and there are ways to tune it into perfection.  That is not what this document is about.  This document is about giving you the ability to use SELinux in enforcing tools using a few memorable commands and files.
  3. Tools/Practice:

    • getenforce - command output displays "current mode" for SELinux (Enforcing/Permissive)
    • sestatus - like a verbose getenforce
    • setenforce 0 - command that will set SELinux to Permissive Mode
    • setenforce 1 - command that will set SELinux to Enforcing mode
    • /var/log/audit/audit/audit.log (see below how to read)
    • audit2allow
    • audit2why
    • /etc/selinux/targeted/modules/active/booleans.local (see below how to read/use)
    • chcon
    • restorecon
    • setsebool
    • getsebool -a
    • ls -lZ /path/to/file
    • ls -ldZ /path/to/directory

    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 = the Security Context of the action you are trying to do (that was blocked if entry says "denied").
    tcontext = Target Security Context:  how the file, directory or whatever you are acting on is currently labeled.

    As you can imagine, selinux blocks actions when there is a mismatch between scontext and tcontext, that is not to say that scontext and tcontext should be the same, they just need to be compatible.  If the contexts match and SELinux is still denying access, other reasons are possible.

    How to Display the Current Security Context 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
    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 persistant 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:

    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
    semodule -DB

    To Return to Logging Defaults:

    semodule --build
    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
    -rw-r--r--. 1 root root 197 May 7 09:31
    [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.

    And many thanks to Gary Smith and his lectures at Linuxfest Northwest!!!!