SELINUX

SELinux - Security Enhanced Linux

What is SELinux?


SELinux stands for Security Enhanced Linux. SELinux is an implementation of a mandatory access control mechanism that confines user programs and system servers to the minimum amount of privileges that are required to do their jobs in the Linux kernel. SELinux uses a collection of rules collectively known as policies. SELinux checks for allowed operations after standard discretionary access controls are checked. SELinux aims to control which activities a system allows individual users, processes and daemons to perform. This gives an additional security layer to the standard Discretionary Access Control (DAC) methods used for setting permissions on files and directories etc.. SELinux is enabled by default in Red Hat Enterprise Linux (RHEL) and is available in many Linux distributions.



Check for installed SELinux packages


To check which SELinux packages are installed on your RHEL/CentOS system, you can issue one of the following commands:



[root@centos-65 ~]# rpm -qa | grep -i selinux
selinux-policy-targeted-3.7.19-231.el6.noarch
libselinux-utils-2.0.94-5.3.el6_4.1.x86_64
selinux-policy-3.7.19-231.el6.noarch
libselinux-2.0.94-5.3.el6_4.1.x86_64
libselinux-python-2.0.94-5.3.el6_4.1.x86_64

[root@centos-65 ~]# yum list installed | grep -i selinux
libselinux.x86_64       2.0.94-5.3.el6_4.1
libselinux-python.x86_64
libselinux-utils.x86_64 2.0.94-5.3.el6_4.1
selinux-policy.noarch   3.7.19-231.el6  @anaconda-CentOS-201311272149.x86_64/6.5
selinux-policy-targeted.noarch

Determine SELinux Status


SELinux runs in three different modes. These are "Enforcing", "Permissive" and "Disabled":


Enforcing Mode


When in Enforcing mode, the security policy is always enforced.


Permissive Mode


When in Permissive mode SELinux simulates the Enforcing Policy by creating only warning messages. This mode does not enforce any security policies.


Disabled


In this mode SELinux does not enforce any policies. (Not recommended). Normal DAC rules are still used.


Displaying the current SELinux mode


You can identify which SELinux mode your system is running with by issuing the "sestatus" command from the command line.

If you are running with SELinux Enabled, you will see information similar to the screen below. If not, then you will receive a simple message indicating "disabled"



[root@centos-65 ~]# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted

You may also use the getenforce command to display the current status of SELinux:



[root@centos-65 ~]# getenforce
Enforcing

getenforce reports whether SELINUX is running in "enforcing", "permissive" or "disabled" modes.


Enabling and Disabling SELinux


It is possible to dynamically disable SELinux if needed. To do this you can either use the "setenforce" command or simply "echo" a value to the file "/selinux/enforce".

usage: setenforce [ Enforcing | Permissive | 1 | 0 ]

Note, changes made using the setenforce command will not survive a system re-boot.


Using the echo command to disable SELinux


To Enable/Disable SELinux use the "echo" command as per example below. (1 = Enabled - 0 = Disabled):



# cat /selinux/enforce
1

# echo 0 > /selinux/enforce

# cat /selinux/enforce
0

Set SELinux to start at system boot


If you require SELinux to be active after a system re-boot, then you need to confirm that the file:

/etc/sysconfig/selinux has the entry: SELINUX=enforcing

Below is an extract from "/etc/sysconfig/selinux" taken from a CentOS 6.5 system:



[root@centos-65 ~]# cat /etc/sysconfig/selinux 
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

Installing semanage


Before we continue, a useful command for working with SELinux is "semanage. Semanage is used to configure elements of the SELinux policy without requiring modification to or recompilation from policy sources. This includes the mapping from Linux user names to SELinux user identities (which controls the initial security context assigned to Linux users when they login and bounds their authorized role set) as well as security context mappings for various kinds of objects, such as network ports, interfaces, and nodes (hosts) as well as the file context mapping. For more information on "semanage" and its uses, you can view the man pages by issuing "man semanage".

Semanage is not installed by default. You will need to install the following package:

policycoreutils-python.x86_64 : SELinux policy core python utilities



[root@centos-65 lol]# yum install policycoreutils-python.x86_64

The above command will install the "policycoreutils-python" core utility package. (In this example we are using the x86_64 version)


SELinux Context


All files and processes have labels that contain SELinux context. These labels contain user information, roles, type and level (sensitivity) information. It is these context settings that are used to make access control decisions.

SELinux contexts are split into the following sections: user:role:type:level

We can use the "Z" flag in conjunction with many commands to view the context information. Below are some examples using the "ls, ps and id commands.



[root@centos-65 lol]# ls -Z
-rw-rw-r--. john john unconfined_u:object_r:user_home_t:s0 listing.txt

[root@centos-65 lol]# id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

[root@centos-65 lol]# ps -eZ | less

LABEL                             PID TTY          TIME CMD
system_u:system_r:init_t:s0         1 ?        00:00:01 init
system_u:system_r:kernel_t:s0       2 ?        00:00:00 kthreadd
system_u:system_r:kernel_t:s0       3 ?        00:00:00 migration/0
system_u:system_r:kernel_t:s0       4 ?        00:00:00 ksoftirqd/0
system_u:system_r:kernel_t:s0       5 ?        00:00:00 migration/0
system_u:system_r:kernel_t:s0       6 ?        00:00:00 watchdog/0
system_u:system_r:kernel_t:s0       7 ?        00:00:11 events/0
system_u:system_r:kernel_t:s0       8 ?        00:00:00 cgroup
system_u:system_r:kernel_t:s0       9 ?        00:00:00 khelper
system_u:system_r:kernel_t:s0      10 ?        00:00:00 netns

SELinux User


The SELinux user identity contains information that is known to the policy that is authorized an identity known to the policy that is authorized for a specific set or roles and for a specific range of MLS/MCS. Each individual Linux user is mapped to a SELinux user via a SELinux policy. This user mapping can be seen by issuing the semanage login -l command:



[root@centos-65 lol]# semanage login -l

Login Name                SELinux User              MLS/MCS Range            

__default__               unconfined_u              s0-s0:c0.c1023           
root                      unconfined_u              s0-s0:c0.c1023           
system_u                  system_u                  s0-s0:c0.c1023 

The first column is that of the Linux user. The second column shows which SELinux user is being mapped and the third column shows the MLS/MCS Ranges used by (MLS) Multi Level Security and (MCS) Multi Category Security.


SELinux Roles


The role is the second part of the context. Each Linux user is mapped to a SELinux user which is authorized for certain roles. Roles are authorized for domains. Depending on your user, it may be possible to switch roles. TO list the roles available to users we can user the command: semanage user -l

Below is an example taken from a CentOS 6.5 system:



[root@centos-65 lol]# semanage user -l

                Labelling  MLS/       MLS/                          
SELinux User    Prefix     MCS Level  MCS Range                      SELinux Roles

git_shell_u     user       s0         s0                             git_shell_r
guest_u         user       s0         s0                             guest_r
root            user       s0         s0-s0:c0.c1023                 staff_r sysadm_r system_r unconfined_r
staff_u         user       s0         s0-s0:c0.c1023                 staff_r sysadm_r system_r unconfined_r
sysadm_u        user       s0         s0-s0:c0.c1023                 sysadm_r
system_u        user       s0         s0-s0:c0.c1023                 system_r unconfined_r
unconfined_u    user       s0         s0-s0:c0.c1023                 system_r unconfined_r
user_u          user       s0         s0                             user_r
xguest_u        user       s0         s0                             xguest_r

From the above we can see that some mappings have more than one SELinux role where others only have one. Where a user has more than one role, they can switch role by using the command: newrole -r SELinux_Role. The most common use for this is when a user wishes to switch from"staff_r" to "sysadm_r".

The most common roles found on most systems are:

user_r: This role is for regular users.

staff_r: This role is a slightly enhanced version of the user mode.

sysadm_r: This role is for System Administrators.


SELinux Type


Type defines a domain for processes and a type for files.


SELinux Level


SELinux Level is an attribute of MLS and MCS. A MLS range is a pair of levels written as lowlevel-highlevel if the levels differ, or lowlevel if the levels are identical (s0-s0 is the same as s0). Each level is a sensitivity-category pair, with categories being optional. If there are categories, then each level is written as sensitivity:category-set. If there are no categories then it is written as sensitivity.

A mapping files is used to translate mappings into more meaningful output. Below is the "/etc/selinux/targeted/setrans.conf" file taken from a CentOS system:



[root@centos-65 targeted]# cat /etc/selinux/targeted/setrans.conf 
#
# Multi-Category Security translation table for SELinux
# 
# Uncomment the following to disable translation library
# disable=1
#
# Objects can be categorized with 0-1023 categories defined by the admin.
# Objects can be in more than one category at a time.
# Categories are stored in the system as c0-c1023.  Users can use this
# table to translate the categories into a more meaningful output.
# Examples:
# s0:c0=CompanyConfidential
# s0:c1=PatientRecord
# s0:c2=Unclassified
# s0:c3=TopSecret
# s0:c1,c3=CompanyConfidentialRedHat
s0=SystemLow
s0-s0:c0.c1023=SystemLow-SystemHigh
s0:c0.c1023=SystemHigh


SELinux Graphical User Interface - SELinux configuration GUI


A GUI interface to SELinux is available if you are running with a graphical desktop. This interface doesn't come as default and needs to be installed. The package to install can be found by issuing the following command:

"yum search policycoreutils-gui



[root@centos-65 targeted]# yum search policycoreutils-gui
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
 * base: mirror.bytemark.co.uk
 * extras: mirror.bytemark.co.uk
 * updates: mirrors.manchester.m247.com
======================================= N/S Matched: policycoreutils-gui ========================================
policycoreutils-gui.x86_64 : SELinux configuration GUI

From the above I can see that the package to install on my system would be: policycoreutils-gui.x86_64

Below we can see that the command "yum install policycoreutils-gui.x86_64" was issued:



[root@centos-65 targeted]# yum install policycoreutils-gui.x86_64
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
 * base: mirror.bytemark.co.uk
 * extras: mirror.bytemark.co.uk
 * updates: mirrors.manchester.m247.com
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package policycoreutils-gui.x86_64 0:2.0.83-19.39.el6 will be installed
--> Processing Dependency: setools-console for package: policycoreutils-gui-2.0.83-19.39.el6.x86_64
--> Processing Dependency: gtkhtml2 for package: policycoreutils-gui-2.0.83-19.39.el6.x86_64
--> Processing Dependency: gnome-python2-gtkhtml2 for package: policycoreutils-gui-2.0.83-19.39.el6.x86_64
--> Running transaction check
---> Package gnome-python2-gtkhtml2.x86_64 0:2.25.3-20.el6 will be installed
---> Package gtkhtml2.x86_64 0:2.11.1-7.el6 will be installed
---> Package setools-console.x86_64 0:3.3.7-4.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=================================================================================================================
 Package                             Arch                Version                         Repository         Size
=================================================================================================================
Installing:
 policycoreutils-gui                 x86_64              2.0.83-19.39.el6                base              209 k
Installing for dependencies:
 gnome-python2-gtkhtml2              x86_64              2.25.3-20.el6                   base               22 k
 gtkhtml2                            x86_64              2.11.1-7.el6                    base              154 k
 setools-console                     x86_64              3.3.7-4.el6                     base              328 k

Transaction Summary
=================================================================================================================
Install       4 Package(s)

Total download size: 714 k
Installed size: 2.1 M
Is this ok [y/N]: y
Downloading Packages:
(1/4): gnome-python2-gtkhtml2-2.25.3-20.el6.x86_64.rpm                                    |  22 kB     00:00     
(2/4): gtkhtml2-2.11.1-7.el6.x86_64.rpm                                                   | 154 kB     00:00     
(3/4): policycoreutils-gui-2.0.83-19.39.el6.x86_64.rpm                                    | 209 kB     00:00     
(4/4): setools-console-3.3.7-4.el6.x86_64.rpm                                             | 328 kB     00:00     
-----------------------------------------------------------------------------------------------------------------
Total                                                                            630 kB/s | 714 kB     00:01     
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : gtkhtml2-2.11.1-7.el6.x86_64                                                                  1/4 
  Installing : gnome-python2-gtkhtml2-2.25.3-20.el6.x86_64                                                   2/4 
  Installing : setools-console-3.3.7-4.el6.x86_64                                                            3/4 
  Installing : policycoreutils-gui-2.0.83-19.39.el6.x86_64                                                   4/4 
  Verifying  : policycoreutils-gui-2.0.83-19.39.el6.x86_64                                                   1/4 
  Verifying  : gtkhtml2-2.11.1-7.el6.x86_64                                                                  2/4 
  Verifying  : setools-console-3.3.7-4.el6.x86_64                                                            3/4 
  Verifying  : gnome-python2-gtkhtml2-2.25.3-20.el6.x86_64                                                   4/4 

Installed:
  policycoreutils-gui.x86_64 0:2.0.83-19.39.el6                                                                  

Dependency Installed:
  gnome-python2-gtkhtml2.x86_64 0:2.25.3-20.el6                  gtkhtml2.x86_64 0:2.11.1-7.el6                 
  setools-console.x86_64 0:3.3.7-4.el6                          

Complete!

Once complete, you can issue the command: "system-config-selinux" from the command prompt or click on the "System >> Administration >> SELinux Management" menu to open the GUI interface.

For a quick look at the SELinux Graphical User Interface click on the Video below:




Alert Logging and auditd


By default the audit logging daemon should be installed. You can check that this is running by issuing the command:

service auditd status



[root@centos-65 audit]# service auditd status
auditd (pid  1076) is running..

To ensure the daemon is started after a reboot use the command: chkconfig --list auditd



[root@centos-65 ssh]# chkconfig --list auditd
auditd         	0:off	1:off	2:on	3:on	4:on	5:on	6:off

If the auditd entries are "off", you can enable these by issuing the command: chkconfig --level 2345 auditd on

The auditd daemon is responsible for the logging of denial messages. By default these messages are logged in the following location : /var/log/audit/audit.log

The messages that relate to SELinux have a type of "AVC". AVC stands for Access Vector Cache. Below is an AVC alert I generated by deliberately trying to bind the sshd to port "999". As we can see SELinux didn't allow this action. As the audit.log file can contain a lot of other information, it is easier to filter out only the "AVC" denial messages. Thankfully there are many ways of doing this:

grep AVC /var/log/audit.log



[root@centos-65 audit]# grep AVC /var/log/audit/audit.log 
type=AVC msg=audit(1396432387.842:121): avc:  denied  { name_bind } for  pid=2775 comm="sshd" src=999 scontext=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:hi_reserved_port_t:s0 tclass=tcp_socket
type=AVC msg=audit(1396432387.848:122): avc:  denied  { name_bind } for  pid=2775 comm="sshd" src=999 scontext=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:hi_reserved_port_t:s0 tclass=tcp_socket

Another method that can be used for extracting AVC denial messages is an audit tool called: ausearch.


ausearch


"ausearch" is a tool that can query the audit daemon logs for events based on different search criteria. You may also specify a time parameter for narrowing down your results. (now, recent, today, yesterday, this-week, this-month, this-year). For more information see the man pages for "ausearch".

ausearch -m avc --start today



[root@centos-65 audit]# ausearch -m avc --start today
----
time->Wed Apr  2 10:53:07 2014
type=SYSCALL msg=audit(1396432387.842:121): arch=c000003e syscall=49 success=no exit=-13 a0=3 a1=7ff5a525e190 a2=10 a3=7fff22b0c0ec items=0 ppid=1 pid=2775 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=2 comm="sshd" exe="/usr/sbin/sshd" subj=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 key=(null)
type=AVC msg=audit(1396432387.842:121): avc:  denied  { name_bind } for  pid=2775 comm="sshd" src=999 scontext=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:hi_reserved_port_t:s0 tclass=tcp_socket
----
time->Wed Apr  2 10:53:07 2014
type=SYSCALL msg=audit(1396432387.848:122): arch=c000003e syscall=49 success=no exit=-13 a0=3 a1=7ff5a525e130 a2=1c a3=7fff22b0c0ec items=0 ppid=1 pid=2775 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=2 comm="sshd" exe="/usr/sbin/sshd" subj=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 key=(null)
type=AVC msg=audit(1396432387.848:122): avc:  denied  { name_bind } for  pid=2775 comm="sshd" src=999 scontext=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:hi_reserved_port_t:s0 tclass=tcp_socket

SELinux Booleans


Booleans allow an Administrator to change parts of the SELinux policy. This facility allows you to quickly allow or deny permissions. There are several ways to view the current boolean settings within SELinux. You can either use the GUI interface (see above section) or issue a command from the command line:



getsebool -a


"getsebool -a is a command that can be issued from the command line to display the current SELinux boolean settings. If run with no other parameters, you will receive a lot of information back to your screen. You may wish to "pipe" this output to a pager like "less" or "more:

getsebool -a | less

A more specific way would be to "pipe" the output into grep and search for a particular string. For example to only view entries relating to "samba" we could use the command: "getsebool -a | grep samba".

If you know the full boolean name, you can specify this as: getsebool -a boolean_name.



[root@centos-65 ssh]# getsebool -a | grep samba
samba_create_home_dirs --> off
samba_domain_controller --> off
samba_enable_home_dirs --> off
samba_export_all_ro --> off
samba_export_all_rw --> off
samba_portmapper --> off
samba_run_unconfined --> off
samba_share_fusefs --> off
samba_share_nfs --> off
sanlock_use_samba --> off
use_samba_home_dirs --> off
virt_use_samba --> off

semanage boolean -l


Semanage can also be used to view boolean entries within SELinux. Semanage is more verbose by default as it lists a full description:



[root@centos-65 ssh]# semanage boolean -l | grep samba
samba_domain_controller        (off  ,  off)  Allow samba to act as the domain controller, add users, groups and change passwords.
samba_portmapper               (off  ,  off)  Allow samba to act as a portmapper
samba_enable_home_dirs         (off  ,  off)  Allow samba to share users home directories.
samba_export_all_ro            (off  ,  off)  Allow samba to share any file/directory read only.
samba_export_all_rw            (off  ,  off)  Allow samba to share any file/directory read/write.
use_samba_home_dirs            (off  ,  off)  Support SAMBA home directories
samba_create_home_dirs         (off  ,  off)  Allow samba to create new home directories (e.g. via PAM)
cdrecord_read_content          (off  ,  off)  Allow cdrecord to read various content. nfs, samba, removable devices, user temp and untrusted content files
allow_smbd_anon_write          (off  ,  off)  Allow samba to modify public files used for public file transfer services.  Files/Directories must be labeled public_content_rw_t.
samba_share_fusefs             (off  ,  off)  Allow samba to export ntfs/fusefs volumes.
samba_share_nfs                (off  ,  off)  Allow samba to export NFS volumes.
samba_run_unconfined           (off  ,  off)  Allow samba to run unconfined scripts
sanlock_use_samba              (off  ,  off)  Allow sanlock to manage cifs files
virt_use_samba                 (off  ,  off)  Allow virt to manage cifs files

Enabling and Disabling Booleans in SELinux


To enable or disable a boolean entry within SELinux, we can use the command setsebool

Usage: setsebool [-PV] boolean value | bool1=val1 bool2=val2 ...

"setsebool" sets the current setting of a specified SELinux boolean or a list of booleans to a given value.
This value can be "1" or "true" or "on" to enable the boolean, or "0" or "false" or "off" to disable it.

Without the -P option, only the current boolean value is affected; the boot-time default settings are not changed.

If the -P option is given, all pending values are written to the policy file on disk. So they will be persistent across reboots.

The -V option is used to request verbose error messages.


Example - getsebool and setsebool



[root@centos-65 ssh]# getsebool samba_enable_home_dirs
samba_enable_home_dirs --> off

[root@centos-65 ssh]# setsebool samba_enable_home_dirs on
[root@centos-65 ssh]# getsebool samba_enable_home_dirs
samba_enable_home_dirs --> on

[root@centos-65 ssh]# setsebool -P samba_enable_home_dirs on
[root@centos-65 ssh]# getsebool samba_enable_home_dirs
samba_enable_home_dirs --> on

In the above example we used the "getsebool" command to display the current setting for the boolean "samba_enable_home_dirs". We can see from the output that this is currently set to "off".

Next we issued the "setsebool samba_enable_home_dirs on" command. This would change our setting from "off" to "on". As we didn't use the "-P" option, our setting would not survive a re-boot". To rectify this, we would have to issue the command using the "-P" option.


Changing Boolean Execute Permissions for Users


It is possible to restrict users from executing applications within their home directories and the /tmp area. There are sever settings available which can be set using the "setsebool" command.

For persistent settings that can survive a system re-boot, use the setsebool with the "-P" option.


guest_t


To allow users who are within the "guest_t" domain to execute applications from within their home directories and "/tmp" we can issue the following command:



[root@centos-65 ~]# setsebool -P allow_guest_exec_content on
[root@centos-65 ~]# getsebool allow_guest_exec_content
allow_guest_exec_content --> on

To restrict users from executing applications from within their home area we issue the "setsebool" command with the parameter set to "off":



[root@centos-65 ~]# setsebool -P allow_guest_exec_content off
[root@centos-65 ~]# getsebool allow_guest_exec_content
allow_guest_exec_content --> off

user_t


To allow users who are within the "user_t" domain to execute applications from within their home directories and "/tmp" we can issue the following command:



[root@centos-65 ~]# setsebool -P allow_user_exec_content on
[root@centos-65 ~]# getsebool allow_user_exec_content
allow_user_exec_content --> on

To restrict users from executing applications from within their home area we issue the "setsebool" command with the parameter set to "off":



[root@centos-65 ~]# setsebool -P allow_user_exec_content off
[root@centos-65 ~]# getsebool allow_user_exec_content
allow_user_exec_content --> off

staff_t


To allow users who are within the "staff_t" domain to execute applications from within their home directories and "/tmp" we can issue the following command:



[root@centos-65 ~]# setsebool -P allow_staff_exec_content on
[root@centos-65 ~]# getsebool allow_staff_exec_content
allow_staff_exec_content --> on

To restrict users from executing applications from within their home area we issue the "setsebool" command with the parameter set to "off":



[root@centos-65 ~]# setsebool -P allow_staff_exec_content off
[root@centos-65 ~]# getsebool allow_staff_exec_content
allow_staff_exec_content --> off

xguest_t


To allow users who are within the "xguest_t" domain to execute applications from within their home directories and "/tmp" we can issue the following command:



[root@centos-65 ~]# setsebool -P allow_xguest_exec_content on
[root@centos-65 ~]# getsebool allow_xguest_exec_content
allow_xguest_exec_content --> on

To restrict users from executing applications from within their home area we issue the "setsebool" command with the parameter set to "off":



[root@centos-65 ~]# setsebool -P allow_xguest_exec_content off
[root@centos-65 ~]# getsebool allow_xguest_exec_content
allow_xguest_exec_content --> off

Changing SELinux Security Context on files - chcon, restorecon and semanage fcontext


There are several commands at our disposal for modifying the security contexts of files and directories. These commands are "chcon" and "semanage". It is important to note that any changes made using the "chcon" command do not survive a file system relabel, or the execution of the restorecon command. For a persistent change you would use the "semanage fcontext" command.

First lets use the "ls -Z" command to display the current security settings.



[john@centos-65 ~]$ cd ~
[john@centos-65 ~]$ pwd
/home/john
[john@centos-65 ~]$ mkdir test
[john@centos-65 ~]$ cd test
[john@centos-65 test]$ ls -l /etc > listing.txt
[john@centos-65 test]$ ls -Z
-rw-rw-r--. john john unconfined_u:object_r:user_home_t:s0 listing.txt

In the above example, I have created a test directory under my "home" area and created a simple text file called "listing.txt". The SELinux context for "listing.txt"has the following context attributes: unconfined_u user, object_r role, user_home_t type, and s0 for the level.

Now if we wanted to change our type to that of samba_share_t then we could issue the command:

chcon -t samba_share_t listing.txt


chcon example



[john@centos-65 test]$ chcon -t samba_share_t listing.txt
[john@centos-65 test]$ ls -Z
-rw-rw-r--. john john unconfined_u:object_r:samba_share_t:s0 listing.txt

Now if we wanted to restore the original file context back, we can use a command called "restorecon". The restorecon command is used to restore a file or directory's default SELinux security contexts.


restorecon example



[john@centos-65 test]$ ls -Z
-rw-rw-r--. john john unconfined_u:object_r:samba_share_t:s0 listing.txt

[john@centos-65 test]$ restorecon -v listing.txt 
restorecon reset /home/john/test/listing.txt context unconfined_u:object_r:samba_share_t:s0->unconfined_u:object_r:user_home_t:s0

[john@centos-65 test]$ ls -Z
-rw-rw-r--. john john unconfined_u:object_r:user_home_t:s0 listing.txt

From the above output we can see that the default context has now been restored. The "-v" flag is used to show the changes made to the file label.


Persistent SELinux Context changes - semanage fcontext


As we mentioned earlier the "chcon" command context changes will not survive the use of the "restorecon" command or a file system relabel. For a persistent change we would use the semanage fcontext command. Persistent changes are recorded to files located within the "/etc/selinux/targeted/contexts/files" area. (see below)



[john@centos-65 files]$ pwd
/etc/selinux/targeted/contexts/files
[john@centos-65 files]$ ls -l
total 280
-rw-r--r--. 1 root root 272783 Apr  2 11:56 file_contexts
-rw-r--r--. 1 root root   6414 Apr  2 11:56 file_contexts.homedirs
-rw-r--r--. 1 root root    139 Nov 23 16:46 media  

semanage - example


In this example, we will use the same file we used in the previous example. However, we need to issue the command as the "root" user. When using the "semanage" command you should always specify the full path of the file/directory. Notice when we issue the command to check our changes, it initially appears that no change has occurred!:



[root@centos-65 test]# ls -Z
-rw-rw-r--. john john unconfined_u:object_r:user_home_t:s0 listing.txt

[root@centos-65 test]# semanage fcontext -a -t samba_share_t /home/john/test/listing.txt

[root@centos-65 test]# ls -Z
-rw-rw-r--. john john unconfined_u:object_r:user_home_t:s0 listing.txt

The reason for no change being indicated is that the change has been written to a file:

"/etc/selinux/targeted/contexts/files/file.contexts.local"

We can use the "grep" command to quickly find our entry:



[root@centos-65 test]# grep listing.txt /etc/selinux/targeted/contexts/files/file_contexts.local 
listing.txt    system_u:object_r:user_home_t:s0
/home/john/test/listing.txt    system_u:object_r:samba_share_t:s0

We can now issue our "restorecon" command against our file. This time the "samba_share_t" context should now be applied from the entry within the "file_contexts.local" file.



[root@centos-65 test]# restorecon -v /home/john/test/listing.txt
restorecon reset /home/john/test/listing.txt context unconfined_u:object_r:user_home_t:s0->unconfined_u:object_r:samba_share_t:s0
[root@centos-65 test]# ls -Z
-rw-rw-r--. john john unconfined_u:object_r:samba_share_t:s0 listing.txt

From the above we can see that our context change is now displayed.