Gentoo Logo

Disclaimer : This document is not valid and is not maintained anymore.


[ << ] [ < ] [ Home ] [ > ] [ >> ]


4. Permissive, Unconfined, Disabled or What Not...

Content:

4.a. SELinux States

Introduction

When SELinux is available, it will generally be in one of three states on your system: disabled, permissive or enforcing.

Disabled

When getenforce returns "Disabled", then SELinux is not running on your system. Even though it might be built in your kernel, it is definitely disabled. Your system will still run with regular discretionary access controls (the usual permission rules for standard Linux environments) but the mandatory access controls are not active.

When SELinux is disabled, it also means that files, directories, etc that are modified or created will not get the proper SELinux context assigned to them. When you later start your system with SELinux enabled (permissive or enforcing), issues will arise since the SELinux subsystem will not know which label the files have (it will default the label to one that is not accessible by most domains).

The best way to go forward in such case is to boot in permissive mode and then relabel the entire file system:

Code Listing 1.1: Relabeling the entire file system

# rlpkg -a -r

Permissive

When SELinux is enabled in permissive mode (getenforce returns "Permissive"), then SELinux is enabled and it has a policy loaded. Every access a process makes is checked against the policy rules and, if an access is not allowed, it will be logged (unless the denial is marked as dontaudit) but it will not be prohibited.

The permissive mode is perfect to get acquainted with SELinux and have the system made ready for future "enforcing" mode. While running in permissive mode, applications that are not SELinux aware will behave as if SELinux is not running. This is perfect to validate if a problem is caused by SELinux or not: if in permissive mode the problem still persists, then it is not caused by SELinux.

There is one caveat though: if the application is SELinux-aware (it knows that it can run in a SELinux environment and is able to make SELinux-specific calls) it might still react differently. Although this is often (but not always) a bad programming practice, some applications check if SELinux is enabled and base their functional flow on the results, regardless of the state being permissive or enforcing.

To find out if an application is SELinux aware, simply check if it is linked against libselinux (with ldd or scanelf - part of app-misc/pax-utils):

Code Listing 1.2: Checking if /bin/ls is SELinux-aware

# scanelf -n /bin/ls
 TYPE     NEEDED FILE
ET_DYN   libselinux.so.1,librt.so.1,libc.so.6   /bin/ls

Enforcing

If getenforce returns "Enforcing", then SELinux is loaded and will act based on the policy. When a process tries some activity that is not allowed by the policy, it will be logged (unless a dontaudit is set) and the activity will not go through. This is the only mode where you can truely say that SELinux is active, because it is only now that the policy is acted upon.

Switching States

Depending on your Linux kernel configuration, you can switch between states using one of the following methods. The kernel configuration however can be made so that some of these options are disabled (for instance, a fully hardened system will not allow disabling SELinux in any way).

Using the command setenforce:

Code Listing 1.3: Switching between enforcing and permissive

(Switching to permissive mode)
# setenforce 0

(Switching to enforcing mode)
# setenforce 1

Using the kernel boot option enforcing:

Code Listing 1.4: Switching between enforcing and permissive through boot options

(The following GRUB kernel line would boot in permissive mode)
kernel /kernel-2.6.39-hardened-r8 root=/dev/md3 rootflags=data=journal enforcing=0

Using the /etc/selinux/config SELINUX variable:

Code Listing 1.5: /etc/selinux/config SELINUX setting

# cat /etc/selinux/config
# This file controls the state of SELinux on the system on boot.

# 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 four values:
#       targeted - Only targeted network daemons are protected.
#       strict   - Full SELinux protection.
#       mls      - Full SELinux protection with Multi-Level Security
#       mcs      - Full SELinux protection with Multi-Category Security 
#                  (mls, but only one sensitivity level)
SELINUXTYPE=strict

When you want to switch from permissive to enforcing, it is recommended to do so in the order given above:

  1. First boot up in permissive mode, log on, verify that your context is correct (id -Z) and then switch to enforcing (setenforce 1). You can now test if your system is still working properly.
  2. Next, boot with enforcing=1 as kernel parameter (unless you boot with an initramfs, see earlier in this handbook). This way, your system will boot in enforcing mode, but if things go haywire, you can just reboot, leave out the option and be back in permissive mode
  3. Finally, edit /etc/selinux/config to persist this change.

Domain-permissive Mode

You can also opt to mark a single domain permissive while running the rest of the system in an enforcing state. For instance, to mark mplayer_t as a permissive domain (which means that SELinux does not enforce anything):

Code Listing 1.6: Marking mplayer_t as permissive

# semanage permissive -a mplayer_t

With the -d option, you can remove the permissive mark again.

4.b. SELinux Policy Types

Introduction

Next to the SELinux state, SELinux also offers different policy types. These types differentiate themselves in specific SELinux features that are enabled or disabled. Within Gentoo, three are supported (and a fourth is available): targeted, strict, mcs (and mls).

The type used on a system is declared in /etc/selinux/config:

Code Listing 2.1: The SELINUXTYPE information in /etc/selinux/config

# cat /etc/selinux/config
# This file controls the state of SELinux on the system on boot.

# 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 four values:
#       targeted - Only targeted network daemons are protected.
#       strict   - Full SELinux protection.
#       mls      - Full SELinux protection with Multi-Level Security
#       mcs      - Full SELinux protection with Multi-Category Security 
#                  (mls, but only one sensitivity level)
SELINUXTYPE=strict

strict (without unconfined domains)

The strict policy type is the policy type that was described in the earlier chapters, and coincidentally the type that is the easiest to understand. With the strict policy type, each and every application runs in a domain that has limited privileges. Although there are highly privileged domains, they are never truely unlimited in their privileges.

targeted (using unconfined domains)

The targeted policy type is similar to the strict one, with one major addition: support for unconfined domains. Applications (or users) that run in an unconfined domain are almost unlimited in their privileges. The unconfined domains are usually used for users and user applications, but also the init system and other domains are marked as "unconfined" domains.

The idea behind the targeted policy is that network-facing services are running in (confined) regular domains whereas the rest uses the standard discretionary access controls offered by Linux. These other domains are running as "unconfined".

mcs (using multiple categories)

The introduction of mls and mcs offers the ability for multi-tenancy: multiple instances of the same application should be able to run, but each instance should be confined with respect to the others (instead of all these processes running in the same domain and, hence, the same privileges).

A simple example is virtualization: a virtual guest which runs in the qemu_t domain needs write privileges on the image file that contains the guest operating system. However, if you run two guests, you do not want each guest to write to the other guests' file. With regular domains, you will need to provide this. With mcs, you can give each running instance a specific category (number) and only grant it write privileges to the guest file with the correct category (number).

mls (using multiple security levels)

The mls policy type is available but not yet supported by Gentoo Hardened. With this policy type, it is possible to give sensitivity levels on files and resources as well as domains. Sensitivity levels can best be expressed in terms of public, private, confidential or strictly confidential. With MLS, you can mark a file as one (or a set of) sensitivity level(s) and ensure that only domains with the right sensitivity level can access it.

Switching Types

It is not recommended to switch between types often. At best, you choose your policy type at install time and stick with it. But it is not impossible (nor that hard) to switch between types.

Make sure that your POLICY_TYPES variable in make.conf contains the target policy type already and that the SELinux policy packages have been built since. If that isn't the case, edit the POLICY_TYPES variable to include the target policy type, and rebuild all SELinux policy packages using emerge $(qlist -IC sec-policy).

Now switch your system to permissive mode using setenforce 0 or, if your system does not allow switching the mode, edit /etc/selinux/config to have the system boot in permissive mode. If you cannot use setenforce 0 then you need to reboot now so that the system is in permissive mode.

Next, edit /etc/selinux/config and change the SELINUXTYPE variable from the current policy type to the new one. This will tell SELinux to load the right policy at boot time.

Now go to the built policy modules in /usr/share/selinux because we need to load in the new policy (as you are currently still running with the old type). The next example shows how to do this if you come from a strict policy type and want to go to mcs:

Code Listing 2.2: Loading in the mcs policy

# cd /usr/share/selinux/mcs
# semodule -b base.pp -i $(ls *.pp | grep -v base.pp | grep -v unconfined.pp)

You are now running with the mcs policy loaded, but will have lots of denials if you do anything on the file system, because the files on your file system are not labeled correctly: the mcs policy type requires the labels to have a sensitivity label on them, which isn't the case if you use the strict policy. So let's relabel the entire file system, including those locations that might be hidden because other file systems are mounted on top of it.

Code Listing 2.3: Relabeling the entire file system

(Substitute "strict" with your SELINUXTYPE, and use "lib" instead of "lib64"
if you have a 32-bit system)
# rlpkg -a -r
# mount -o bind / /mnt/gentoo
# setfiles -r /mnt/gentoo /etc/selinux/strict/contexts/files/file_contexts /mnt/gentoo/dev
# setfiles -r /mnt/gentoo /etc/selinux/strict/contexts/files/file_contexts /mnt/gentoo/lib64
# umount /mnt/gentoo

Finally, edit /etc/fstab and update the rootcontext= parameters to include a sensitivity label as well (in case you switched towards mcs or mls) or not anymore (in case you switched to targeted or strict).

Code Listing 2.4: Changing /etc/fstab

# Example when switching from strict to mcs
tmpfs  /tmp  tmpfs  defaults,noexec,nosuid,rootcontext=system_u:object_r:tmp_t:s0  0 0

With all these steps now completed, reboot to ensure that everything is still working correctly (even the boot-up).


[ << ] [ < ] [ Home ] [ > ] [ >> ]


Print

View all

Page updated January 22, 2013

Summary: Your system can be in many SELinux states. In this chapter, we help you switch between the various states / policies.

Chris PeBenito
Author

Sven Vermeulen
Author

Chris Richards
Author

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.