SELinux
Security Enhanced Linux was initially developed by NSA. It was created to supplement the Discretionary Access Controls (DAC) which is the user, group, world, rwx method. SELinux implements Mandatory Access Controls (MAC) to the system at the kernel level. Where DAC will allow a user to set any file or directory to world read and write they own, the MAC model is outside of direct user controls and prevents mistakes such as this. The default for SELinux is to deny access. In order to obtain access, a rule or policy must exist that allows that access.
SELinux is the bread and butter security model around here. It is required learning. The RedHat SELinux documentation is a good starting place. The core products here use a policy called MLS which is backported from Fedora to RHEL. Read here on how MLS work as a SELinux policy and further Fedora SELinux docs. This explains the path to MLS security. The journal of the MLS developer at RedHat is an excellent background guide.
Dr. Rick Smith intro guide link is now http://www.cryptosmith.com/multilevel |
A Google search on SELinux brings up lots of pages on how to turn off and/or disable SELinux. DON'T DO THAT! BAD GOOGLE! |
SELinux upstream source
The reference policy for SELinux is the source for the allowed access that ships with SELinux implementations for RHEL (and Fedora). It can be downloaded and studied but running it on a RHEL 5 workstation will be quite frustrating. Instead the FOOBAR INC policy should be used. It is available from the koji server. The default install has the policy source in /usr/share/selinux/devel/include
.
SELinux files and commands
Files
- The main location for SELinux configuration files are
/etc/selinux
. Within that directory are subdirectories for the various contexts (mls, strict and targeted) and a few configuration files for general selinux operations. config is the file that sets whether selinux is run at boot up and in what context. semanage.conf determines how libsemanage interacts with the policy manager. restorecond.conf lists locations for restorecond to watch in order to set defaults context at file creation time.
- The main location for SELinux configuration files are
Commands
All of these have man pages. semanage is the central command that is used to fully manage the entire selinux policy and contexts./sbin/fixfiles
/sbin/restorecon
/sbin/setfiles
/usr/bin/audit2allow
/usr/bin/chcat
/usr/bin/secon
/usr/bin/semodule_deps
/usr/bin/semodule_expand
/usr/bin/semodule_link
/usr/bin/semodule_package
/usr/sbin/audit2why
/usr/sbin/genhomedircon
/usr/sbin/load_policy
/usr/sbin/open_init_pty
/usr/sbin/restorecond
/usr/sbin/run_init
/usr/sbin/semanage
/usr/sbin/semodule
/usr/sbin/sepolgen-ifgen
/usr/sbin/sestatus
/usr/sbin/setsebool
/usr/bin/sesearch- ls -Z will show the SELinux context of a file or directory.
As SELinux was originally written by the NSA, they are a good resource for writing SELinux policies.
A more user friendly guide is here
SELinux overview
Once the admin gets some basic terminology under the belt, things become pretty clear.
context
- every file has a context. This is the colon-delimited string from a
ls -Z
command.Some excerpts of file contexts
- from the / directory
drwxr-xr-x root root system_u:object_r:bin_t:s0 bin
drwxr-xr-x root root system_u:object_r:boot_t:s0 boot
drwxr-xr-x root root system_u:object_r:device_t:s0 dev
drwxr-xr-x root root system_u:object_r:etc_t:s0 etc
drwxr-xr-x root root system_u:object_r:home_root_t:s0 home
- and from the /home directory
drwx------ apps apps user_u:object_r:user_home_dir_t:s0 apps
drwx------ jim users user_u:object_r:user_home_dir_t:s0 jim
drwx------ jimtest jimtest user_u:object_r:user_home_dir_t:s0 jimtest
drwxr-xr-x tomcat tomcat user_u:object_r:user_home_dir_t:s0 tomcat - contexts are composed of 4 parts
- user_u
- has nothing to due with the login name. The SELinux user identity is an identity known to the policy that is authorized for a specific set of roles, and for a specific MLS range. Each Linux user is mapped to an SELinux user via SELinux policy. This allows Linux users to inherit the restrictions placed on SELinux users. The mapped SELinux user identity is used in the SELinux context for processes in that session, in order to define what roles and levels they can enter.
SELinux users /usr/sbin/semanage user -l Labeling MLS/ MLS/ SELinux User Prefix MCS Level MCS Range SELinux Roles root user s0 s0-s0:c0.c1023 system_r sysadm_r user_r system_u user s0 s0-s0:c0.c1023 system_r user_u user s0 s0-s0:c0.c1023 system_r sysadm_r user_r
login mappings /usr/sbin/semanage login -l Login Name SELinux User MLS/MCS Range __default__ user_u s0 root root s0-s0:c0.c1023
- has nothing to due with the login name. The SELinux user identity is an identity known to the policy that is authorized for a specific set of roles, and for a specific MLS range. Each Linux user is mapped to an SELinux user via SELinux policy. This allows Linux users to inherit the restrictions placed on SELinux users. The mapped SELinux user identity is used in the SELinux context for processes in that session, in order to define what roles and levels they can enter.
- role_r
- Part of SELinux is the Role-Based Access Control (RBAC) security model. The role is an attribute of RBAC. SELinux users are authorized for roles, and roles are authorized for domains. The role serves as an intermediary between domains and SELinux users. The roles that can be entered determine which domains can be entered - ultimately, this controls which object types can be accessed. This helps reduce vulnerability to privilege escalation attacks.
- type_t
- also called the domain when referring to a process, otherwise a type but still is the third field (_t is optional but customary). The type is an attribute of Type Enforcement. The type defines a domain for processes, and a type for files. SELinux policy rules define how types can access each other, whether it be a domain accessing a type, or a domain accessing another domain. Access is only allowed if a specific SELinux policy rule exists that allows it.
- level
- The level is an attribute of MLS and Multi-Category Security (MCS). An 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, the level is written as sensitivity:category.set. If there are no categories, it is written as sensitivity. Levels s0 through s15 for MLS (multi-level security) otherwise it's always s0. Categories are c0 through c1023. Contiguous category ranges are designated c0.c16. A comma separated list is used for non-contiguous ranges, c0,c3,c5,c25.c100.
- user_u
- every file has a context. This is the colon-delimited string from a
- The security is robust through a combination of Role-Based Access Control (RBAC), Type EnforcementĀ® (TE), and, optionally, Multi-Level Security (MLS). The default for SELinux is to not allow access. Rules are written to allow access.
Domain transition
When a process needs to access either files or data from somewhere outside its own type, this requires a domain transition rule to allow access. Consider the following example:
User perspective
- User enters
passwd
command at shell prompt - User enters and then confirms the new password
System perspective
- shell forks a copy of itself and calls execve() to load the passwd program into the new copy
- passwd program verifies matching new passwords and writes to
/etc/shadow
This is a domain transition.
They are a very common process that gets handles at FOOBAR INC with SELinux Type Enforcement (TE) policyThis rule set allows the user the ability to change their password using the passwd command. SinceTE rules to allow password changeallow unconfined_t passwd_exec_t : file {getattr execute};
allow passwd_t passwd_exec_t : file entrypoint;
allow unconfined_t passwd_t: process transition;/usr/bin/passwd
is SUID root, we want to limit the access of the passwd binary. Since the deault SELinux action is to deny everything we need to write rules to allow passwd to operate and have read/write access to/etc/shadow
. Since the user shell runs in the domain unconfined_t and the/usr/bin/passwd
uses passwd_exec_t, the first rule allows that process an unconfined_t process to call an executable file of type passwd_exec_t. The second rule is an entry point rule. This is a key permission as it allows a program or process to "enter" a domain. By having only the passwd program labeled with thepasswd_exec_t
domain, this limits the files that passwd_t domain processes can act on to just the passwd binary. The passwd_t domain has read/write ability to shadow_t type files.
other passwd_exec_t binaries The |
files vs processes It is typical for the binary file itself to be in the foo_exec_t domain while the running process is in the foo_t domain. This way a single domain transition must occur for running the process as opposed to multiple domain transitions if more than one binary can start a process. |
rule syntax
The general form isallow from to : class { permission [LIN:, permission ]
}
Of course there is an exception: domain transitions are formedallow <to domain> <from domain> : class [LIN:options]
.
Network ports and SELinux
For targeted systems, the ports below 1024 are all marked reserved_port_t and all those over 1023 are marked port_t. So what if you need to add port access to a new application?
- Check to see if there is already a domain associated with that port by running
semanage port -l
and grep for the port number.- If it's already listed then compare the output and see if you are installing the same service on that port. If so, all is good.
- Associate the new application with the port type with
chcon -t <port type> <path/to/newapp/binary>
- Associate the new application with the port type with
- If the port is not listed in the semanage data, then you will need add it under proper domain of the process.
semanage port -a -t <port domain> -p <type> <port number>
where <type> is tcp or udp.- If the proper domain does not exist, this requires adding a new domain and compiling the module.
- Now associate the new port and type with the new app.
- If it's already listed then compare the output and see if you are installing the same service on that port. If so, all is good.
Troubleshooting SELinux
audit2why
This tool takes the AVC errors generated by SELinux and provides details about what failed and why. The typical source for this data is/var/log/audit/audit.log
if auditd is running (which is normal for FOOBAR INC). This file accumulates all SELinux data, both success and failures./usr/sbin/audit2why < /var/log/audit/audit.log
will output a list of failure events and some text explaining what happened.The numbers in the ()'s are timestamps and a rule identifier is after the :.Some example AVC alerts from audit2whytype=AVC msg=audit(1273496538.411:12): avc: denied { read write } for pid=3571 comm="nm-system-setti" path="socket:[9399]" dev=sockfs ino=9399 scontext=system_u:system_r:NetworkManager_t:s0 tcontext=system_u:system_r:system_dbusd_t:s0 tclass=tcp_socket Was caused by: Missing or disabled TE allow rule. Allow rules may exist but be disabled by boolean settings; check boolean settings. You can see the necessary allow rules by running audit2allow with this audit message as input. type=AVC msg=audit(1273851397.042:693): avc: denied { name_bind } for pid=28817 comm="nc" src=2222 scontext=user_u:system_r:tomcat_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket Was caused by: Missing or disabled TE allow rule. Allow rules may exist but be disabled by boolean settings; check boolean settings. You can see the necessary allow rules by running audit2allow with this audit message as input.
audit2allow
This will print out a command to run to allow the process to function. This is typically OK for desktop users in targeted mode but is often too permissive for the high-security needs of our customers.
SELinux Policy Analysis
A gui tool called apol is in the default yum repo that is very useful at looking at how the current system is setup. It can be installed and run from a command shell with apol. You will need to run "File"->"Open" and then load the current policy file from/etc/selinux
as well as select "File Contexts* then "Create and Load" and save an index file somewhere in /tmp and let the tool generate it from "/". The only thing missing is the "Attributes" as text since they are not saved into the binary format.
Simple SELinux exercise
|