Wednesday, 11 July 2012

Selinux in Linux

Selinux in Linux

Security-Enhanced Linux (SELinux) is a mandatory access control (MAC) security mechanism implemented in the kernel. SELinux was first introduced in RHEL4 and significantly enhanced in RHEL5.

THE PROBLEMS

In order to better understand why SELinux is important and what it can do for you it is easiest to look at some examples. Without SELinux enabled, discretionary access control (DAC) methods such as file permissions or access control lists (ACLs) are used to grant file access to users. Users and programs alike are allowed to grant insecure file permissions to others or gain access to parts of the system that should not otherwise be necessary for normal operation. For example:

Administrators have no way to control users: A user could set world readable permissions on sensitive files such as ssh keys

Processes can change security properties: A user’s mail files should be readable only by that user, but the mail client software

has the ability to change them to be world readable

Processes inherit user’s rights: Firefox, if compromised, can read a user’s private ssh keys even though it has no reason to do so.

Essentially there are two privilege levels, root and user, and no easy way to enforce the model of least-privilege. Many processes that are launched by root later drop their rights to run as a restricted user and some processes may be run in a chroot jail, but all of these security methods are discretionary.

THE SOLUTION

SELinux follows the model of least-privilege. By default, everything is denied and then a policy is written that gives each element of the system (a service, program, user) only the access required to function. If a service, program or user tries to access or modify a file or resource not necessary for it to function then access is denied and the action is logged. Because SELinux is implemented within the kernel, individual applications do not need to be especially written or modified to work with SELinux. If SELinux blocks an action, this appears as just a normal “access denied” type error to the application.

SELINUX MODES

SELinux has 3 basic modes of operation out of which Enforcing is set as the default mode

Enforcing: The default mode which will enable and enforce the SELinux security policy on the system, denying access and logging actions

Permissive: In Permissive mode, SELinux is enabled but will not enforce the security policy, only warn and log actions. Permissive mode is useful for troubleshooting SELinux issues

Disabled: SELinux is turned off

The SELinux mode can be viewed and changed by using the SELinux Management GUI tool available on the Administration menu or from the command line by running ‘system-config-selinux’ (the SELinux Management GUI tool is part of the policycoreutils-gui package and is not installed by default).

Users who prefer the command line may use the ‘sestatus’ command to view the current SELinux status:

# sestatus

SELinux status: enabled

SELinuxfs mount: /selinux

Current mode: enforcing

Mode from config file: enforcing

Policy version: 21

Policy from config file: targeted

The ‘setenforce’ command may be used to switch between Enforcing andPermissive modes on the fly but note that these changes do not persist

through a system reboot.

To make changes persistent through a system reboot, edit the SELINUX= line in /etc/selinux/config for either ‘enforcing’, ‘permissive’, or ‘disabled’. For example, SELINUX=permissive.

SELINUX POLICY

Earlier we mentioned that SELinux follows the model of least-privilege; by default everything is denied and then a policy is written that gives each element of the system only the access required to function. This description best describes the strict policy. However, such a policy is difficult to write that would be suitable in the wide range of circumstances that a product such as Enterprise Linux is likely to be used. The end result is that SELinux is likely to cause problems for system administrators and end users, and rather than resolve these issues system administrators are likely to just disable SELinux which defeats the purpose.

Luckily, SELinux allows different policies to be written that are interchangeable. The default policy in CentOS 4 and 5 is the targeted policy which “targets” and confines key system processes. In CentOS 4 only 15 defined targets existed (including httpd, named, dhcpd, mysqld) whereas in CentOS 5 this number has risen to over 200 targets. Everything else on the system runs in an unconfined domain and is unaffected by SELinux. The goal is for every process that is installed and running at boot by default to be running in a confined domain. Thetargeted policy is desi

gned to protect as many key processes as possible without adversely affecting the e

nd user experience and most users should be totally unaware that SELinux is even running.

SELINUX ACCESS CONTROL

SELinux has 3 forms of access control:

Type Enforcement (TE): Type Enforcement is the primary mechanism of access control used in the targeted policy

Role-Based Access Control (RBAC): Based around SELinux users (not necessarily the same as the Linux user), but not used in the default targeted policy

Multi-Level Security (MLS): Not used and often hidden in the default targeted policy.

All processes and files have an SELinux security context. Lets see these in action by looking at the SELinux security context of our Apache homepage, index.html: $ ls -Z /var/www/html/index.html -rw-r–r– phil phil system_u:object_r:httpd_sys_content_t /var/www/html/index.html

In addition to the standard file permissions and ownership, we can see the SELinux security context fields: system_u:object_r:httpd_sys_content_t.

This is based upon user:role:type:mls. In our example above, user:role:type fields are displayed and mls is hidden. Within the default targeted policy, typeis the important field used to implement Type Enforcement, in this case httpd_sys_content_t.

Now lets look at the SELinux security context of the Apache web server process, httpd:

$ ps axZ | grep httpd

system_u:system_r:httpd_t 3234 ? Ss 0:00 /usr/sbin/httpd

Here we see the from the type field that Apache is running under the httpd_t type domain.

Finally, lets look at the SELinux security context of a file in our home directory:

$ ls -Z /home/phil/myfile.txt

-rw-r–r– phil phil user_u:object_r:user_home_t /home/phil/myfile.txt

where we see the type is user_home_t, the default type for files in a users home directory.

Access is only allowed between similar types, so Apache running as httpd_t can read /var/www/html/index.html of type httpd_sys_content_t. Because Apache runs in the httpd_t domain, it can not access /home/phil/myfile.txt even though this file is world readable because it’s SELinux security context is not of type httpd_t. If Apache were to be exploited, it would not be able to start any process not in the httpd_t domain (which prevents escalation of privileges) or access any file not in an httpd_t related domain.

TROUBLESHOOTING SELINUX

Sooner or later you may run into situations were SELinux denies access to something and you need to troubleshoot the issue. There are a number of fundamental reasons why SELinux may deny access to a file, process or resource:

A mislabeled file

A process running under the wrong SELinux security context

A bug in policy. An application requires access to a file that wasn’t anticipated when the policy was written and generates an error

An intrusion attempt.

The first 3 we can deal with whereas the 4th case is exactly the intended behaviour.

To troubleshoot any issue, log files are key and SELinux is no different. By default SELinux log messages are written to /var/log/audit/audit.log via the Linux Auditing System (auditd) which is started by default. If auditd is not running then messages are written to /var/log/messages. SELinux log messages are labeled with the “AVC” keyword so that they can be easily filtered from other messages.

Starting with CentOS 5 the SELinux Troubleshooting tool can be used to help analyze log files converting them into a more human-readable format. The tool consists of a GUI tool for displaying messages in human-readable format and possible solutions, a desktop notification icon alerting of new issues and a daemon process (setroubleshootd) that checks for new SELinux AVC alerts and feeds the notification icon (email notifications may also be configured for those not running an X server). The SELinux Troubleshooting tool is provided by the setroubleshoot package and is installed by default. The tool may be launched from the System menu or from the command line:

$ sealert -b

Those not running an X server may generate human-readable reports from the command line:

sealert -a /var/log/audit/audit.log > /path/to/mylogfile.txt

RELABELING FILES

The ‘chcon’ command may be used to change SELinux security context of a file or files/directories in a similar way to how chown or chmod may be used to change the ownership or standard file permissions of a file.

Lets look at some examples.

Using Apache as an example, suppose you want to change the DocumentRoot to serve web pages from a location other than the default /var/www/html directory. Suppose we create a directory (or maybe a mount point) at /html and create our index.html file there:

# mkdir /html

# touch /html/index.html

# ls -Z /html/index.html

-rw-r–r– root root user_u:object_r:default_t /html/index.html

# ls -Z | grep html

drwxr-xr-x root root user_u:object_r:default_t html

we see that both the directory /html and file /html/index.html have the security context type default_t. If we start our web browser and try to view the page SELinux will deny access and log the error because the directory and file(s) have the wrong security context. We need to set the correct security context type for Apache of httpd_sys_content_t:

# chcon -v –type=httpd_sys_content_t /html

context of /html changed to user_u:object_r:httpd_sys_content_t

# chcon -v –type=httpd_sys_content_t /html/index.html

context of /html/index.html changed to user_u:object_r:httpd_sys_content_t

Equally we could have set both in one go using the -R recursive switch:

# chcon -Rv –type=httpd_sys_content_t /html

Modifying security contexts in this manner will persist between reboots unless the complete filesystem is relabeled (see later). To make the security context changes permanent, even through a complete filesystem relabel, we can use the SELinux Management Tool or the ‘semanage’ command from the command line:

semanage fcontext -a -t httpd_sys_content_t “/html(/.*)?”

to add a file context of type httpd_sys_content_t for everything under /html.

RESTORE DEFAULT SECURITY CONTEXTS

The ‘restorecon’ command may be used to restore file(s) default SELinux security contexts.

Again, lets use Apache as an example. Suppose a user edits a copy of index.html in his/her home directory and moves (mv) the file to the DocumentRoot /var/www/html. Whilst the copy (cp) command will typically adopt the destination directory’s or file’s security context, move (mv) will maintain the source’s security context. We could use the ‘chcon’ command to change the security context of the file(s) in question but as the file(s) are now in the default Apache DocumentRoot (/var/www/html) we can just restore the default security contexts for that directory or file(s). To restore just the index.html file, we would use:

# restorecon -v /var/www/html/index.html

or to recursively restore the default security contexts for the whole directory:

# restorecon -Rv /var/www/html

Additionally, if we simply wanted to examine the security contexts of the /var/www/html directory to see if any files needed their security contexts restored, we can use restorecon with the -n switch to prevent any relabelling occurring:

# restorecon -Rv -n /var/www/html

RELABEL COMPLETE FILESYSTEM

Sometimes it is necessary to relabel the complete filesystem although this should only be necessary when enabling SELinux after it has been disabled or when changing the SELinux policy from the default targeted policy to strict. To automatically relabel the complete filesystem upon reboot, do:

# touch /.autorelabel

# reboot

Sometimes a complete filesystem relabel will fail if the system has been upgraded to CentOS-5.2 with SELinux disabled, and SELinux is then enabled. If the above procedure doesn’t correctly perform a complete filesystem relabel, try issuing the ‘genhomedircon’ command first:

# genhomedircon

# touch /.autorelabel

# reboot

ALLOWING ACCESS TO A PORT

We may want a service such as Apache to be allowed to bind and listen for incoming connections on a non-standard port. By default, the SELinux policy will only allow services access to recognized ports associated with those services. If we wanted to allow Apache to listen on tcp port 81, we can add a rule to allow that using the ‘semanage’ command:

# semanage port -a -t http_port_t -p tcp 81

A full list of ports that services are permitted access by SELinux can be obtained with:

# semanage port -l

CUSTOMIZING SELINUX POLICIES

Minor modifications to SELinux policies can be made without modifying and recompiling the policy source by setting boolean values for optional features. Such features include allowing users to share their home directories under Samba or allowing Apache to serve files from users home directories which would otherwise be denied by the SELinux policy.

WHICH BOOLEAN DO I NEED?

getsebool -a

will show you all available booleans on your system which can be changed by you. So take a look at the list that gives you and check the booleans which might be interesting for you against the list below to see if it really does what you think it does.

httpd_can_network_connect (HTTPD Service):: Allow HTTPD scripts and modules to connect to the network.

Looks like it could be the one you need …

setsebool -P httpd_can_network_connect on

will turn that on for you. Et voilà – it works.

system-config-selinux from the policycoreutils-gui package has the same list as the one below. So if you have a GUI available you probably are better off installing that package and making the changes there.

For all others: Here is the

acct_disable_trans (SELinux Service Protection)

Disable SELinux protection for acct daemon

allow_cvs_read_shadow (CVS)

Allow cvs daemon to read shadow

allow_daemons_dump_core (Admin)

Allow all daemons to write corefiles to /.

allow_daemons_use_tty (Admin)

Allow all daemons the ability to use unallocated ttys.

allow_execheap (Memory Protection)

Allow unconfined executables to make their heap memory executable. Doing this is a really bad idea. Probably indicates a badly coded executable, but could indicate an attack. This executable should be reported in bugzilla

allow_execmem (Memory Protection)

Allow unconfined executables to map a memory region as both executable and writable, this is dangerous and the executable should be reported in bugzilla

allow_execmod (Memory Protection)

Allow all unconfined executables to use libraries requiring text relocation that are not labeled textrel_shlib_t

allow_execstack (Memory Protection)

Allow unconfined executables to make their stack executable. This should never, ever be necessary. Probably indicates a badly coded executable, but could indicate an attack. This executable should be reported in bugzilla