SELinux/Installation

From Gentoo Wiki
Jump to: navigation, search

Getting a SELinux-powered Gentoo installation doesn't require weird actions. What is needed is to install Gentoo Linux with the correct profile, correct kernel configuration and some file system relabeling. It is seriously recommended to use SELinux together with other hardening improvements (such as PaX / grSecurity).

Installing Gentoo (Hardened)

This document assumes the reader starts with an existing Gentoo Linux system which needs to be converted to Gentoo with SELinux. It is possible to make the right decisions during a Gentoo installation to immediately start with a SELinux system. However, this article is focusing on a conversion of an existing system as that is the most common approach.

Performing a standard installation

Install Gentoo Linux according to the Gentoo Handbook installation instructions. It is recommended to use the hardened stage 3 tarballs and hardened-sources kernel instead of the standard ones, but standard stage installations are also supported for SELinux. Perform a full installation to the point that the system is booted into a (primitive) Gentoo base installation.

Choosing a SELinux policy type

Gentoo supports four policy types within SELinux: strict, targeted, mcs and mls.

The differentiation between strict and targeted is based upon the unconfined domain. When loaded, the processes on the system that are not specifically confined within a particular policy module will be part of the unconfined domains whose purpose is to allow most activities by default (rather than deny by default). As a result, processes that run inside unconfined domains have no restrictions apart from those already enforced by standard Linux security. Although running without the unconfined domains is considered more secure, it will also be more challenging for the administrator to make sure the system still functions properly as there are no policy modules for each and every application "out there".

Next to targeted and strict, administrators can opt for mcs to allow categorization of resources. This is useful on multi-tenant systems such as web servers, virtualization hosts, ... where multiple processes will be running, most of them in the same security domain, but in different categories. Note though that to take advantage of the additional category support, either the applications themselves (such as the web server or hypervisor tools) need to configure the SELinux categories (so they need to support SELinux) or the administrator will need to script around to start the individual instances with separate categories. Otherwise, mcs is just the same as targeted or strict.

Finally, Gentoo also provides mls to support a true multi-level security system. However, MLS is currently still considered experimental in Gentoo and as such not recommended.

In case of mcs or mls, the unconfined USE flag needs to be used to enable or disable unconfined domains in these policy types. The strict policy store does not use the USE flag at all (as it does not support unconfined domains at all) and the targeted policy store (which uses unconfined domains) requires the USE flag set.

Save the choice for the policy store in /etc/portage/make.conf. That way, Portage will only install the policy modules for that SELinux policy store. By default, the SELinux profiles enable strict and targeted (with strict being the default active type).

FILE /etc/portage/make.confSetting the supported policy stores
POLICY_TYPES="strict"

Multiple stores can be defined, although only one store can be active at any point in time. This is handled through the SELinux configuration itself, which is covered later in the installation.

Setting file system contexts

If the /tmp location is a tmpfs-mounted file system, then it is necessary to tell the kernel that the root context of this location is tmp_t instead of tmpfs_t, which is the default context assigned to tmpfs-mounted file systems.

Note
A context is a label assigned to a resource, and is what SELinux bases its access control decisions on. See type enforcement for more information, or our quick introduction to SELinux.
Note
systemd automatically relabeles /tmp, /dev and /run. You don't need the entries then.

To configure the /tmp mount, edit the /etc/fstab file:

FILE /etc/fstabSetting the rootcontext for the /tmp mount
# For a "targeted" or "strict" policy type:
tmpfs  /tmp  tmpfs  defaults,noexec,nosuid,rootcontext=system_u:object_r:tmp_t  0 0
  
# For an "mls" or "mcs" policy type:
tmpfs  /tmp  tmpfs  defaults,noexec,nosuid,rootcontext=system_u:object_r:tmp_t:s0  0 0

Next, set the next line in /etc/fstab to configure the context for the /run location:

FILE /etc/fstabSetting the rootcontext for the /run mount
# For a "targeted" or "strict" policy type:
tmpfs  /run   tmpfs  mode=0755,nosuid,nodev,rootcontext=system_u:object_r:var_run_t  0 0
  
# For an "mls" or "mcs" policy type:
tmpfs  /run   tmpfs  mode=0755,nosuid,nodev,rootcontext=system_u:object_r:var_run_t:s0  0 0

Change the Gentoo profile

Switch the Gentoo profile to the right SELinux profile (for instance, hardened/linux/amd64/no-multilib/selinux).


root #eselect profile list
Available profile symlink targets:
  [1]   default/linux/amd64/13.0
  [2]   default/linux/amd64/13.0/selinux
  [3]   default/linux/amd64/13.0/desktop
  [4]   default/linux/amd64/13.0/desktop/gnome
  [5]   default/linux/amd64/13.0/desktop/gnome/systemd
  [6]   default/linux/amd64/13.0/desktop/kde
  [7]   default/linux/amd64/13.0/desktop/kde/systemd
  [8]   default/linux/amd64/13.0/developer
  [9]   default/linux/amd64/13.0/no-multilib
  [10]  default/linux/amd64/13.0/x32
  [11]  hardened/linux/amd64  *
  [12]  hardened/linux/amd64/selinux
  [13]  hardened/linux/amd64/no-multilib
  [14]  hardened/linux/amd64/no-multilib/selinux
  [15]  hardened/linux/amd64/x32
  [16]  hardened/linux/uclibc/amd64
root #eselect profile set 12
Warning
Do not rebuild the system right now - wait until this is instructed by this document later. Rebuilding the system will pull in SELinux policies which could make the system unreachable if we reboot after it without taking proper countermeasures.

Starting from the profile change, Portage will warn after every installation that it was "Unable to set SELinux security labels". This is to be expected, because the tools and capabilities that Portage requires to set the security labels aren't available yet. This warning will vanish the moment the SELinux installation is completed.

Don't update the system yet - a couple of packages need to be installed first in a particular order that Portage isn't aware of.

Updating make.conf

Take a look at the following SELinux related USE flags and decide which ones to enable or disable.

USE flag Description
peer_perms The peer_perms capability controls the SELinux policy network peer controls. If set, the access control mechanisms that SELinux uses for network based labeling are consolidated. This setting is recommended as the policy is also updated to reflect this. If not set, the old mechanisms (NetLabel and Labeled IPsec) are used side by side.
open_perms The open_perms capability enables the SELinux permission "open" for files and file-related classes. Support for the "open" call was added a bit later than others so support was first made optional. However, the policies have matured sufficiently to have the open permission set.
ubac When disabled, the SELinux policy is built without user-based access control.
unconfined When set, policy builds (except for the "strict" policy) will include the unconfined module (thus allowing unconfined domains to exist on the system).

Update the USE variable in /etc/portage/make.conf or in an appropriate /etc/portage/package.use location for the sec-policy/selinux-base package.

Installing a SELinux kernel

The default Linux kernels offer SELinux support.

root #emerge --ask sys-kernel/gentoo-sources

Next, reconfigure the kernel with the appropriate security settings. This includes, but is not limited to

  • Support for extended attributes in the various file systems
  • Support system-call auditing
  • Support for SELinux

Below a quick overview of the recommended settings can be found.

KERNEL Enabling SELinux
Under "General setup"
[*] Auditing support
[*]   Enable system-call auditing support
  
Under "File systems"
  (For each file system you use, make sure extended attribute support is enabled)
<*> Second extended fs support
[*]   Ext2 extended attributes
[ ]     Ext2 POSIX Access Control Lists
[*]     Ext2 Security Labels
[ ]   Ext2 execute in place support
  
<*> Ext3 journalling file system support
[ ]   Default to 'data=ordered' in ext3
[*]   Ext3 extended attributes
[ ]     Ext3 POSIX Access Control Lists
[*]     Ext3 Security Labels
  
<*> The Extended 4 (ext4) filesystem
[*]   Ext4 extended attributes
[ ]     Ext4 POSIX Access Control Lists
[*]     Ext4 Security Labels
  
<*> JFS filesystem support
[ ]   JFS POSIX Access Control Lists
[*]   JFS Security Labels
[ ]   JFS debugging
[ ]   JFS statistics
  
<*> XFS filesystem support
[ ]   XFS Quota support
[ ]   XFS POSIX ACL support
[ ]   XFS Realtime subvolume support (EXPERIMENTAL)
[ ]   XFS Debugging Support
  
<*> Btrfs filesystem (EXPERIMENTAL)
[ ]   Btrfs POSIX Access Control Lists
  
Under "Security options"
[*] Enable different security models
[*] Socket and Networking Security Hooks
[*] NSA SELinux Support
[ ]   NSA SELinux boot parameter
[ ]   NSA SELinux runtime disable
[*]   NSA SELinux Development Support
[ ]   NSA SELinux AVC Statistics
(0)   NSA SELinux checkreqprot default value
[ ]   NSA SELinux maximum supported policy format version
    Default security module (SELinux) --->

Do not forget to set the Default security module to SELinux. Otherwise, the security=selinux boot parameter has to be set in the bootloader configuration.

Build and install the new Linux kernel and its modules.

Reboot

With the above changes made, reboot the system.

Configure SELinux

In the second part of the SELinux installation, we cover the installation of the proper utilities, relabel the entire file system and configure the policy.

Installing policies and utilities, part one

First, install the sys-apps/checkpolicy and sys-apps/policycoreutils packages. Although these will be pulled in as dependencies of the SELinux policy packages themselves, a one-time installation is needed in advance.

root #emerge --ask -1 checkpolicy policycoreutils

Next, install the base SELinux policy package. This package provides the SELinux configuration file which needs to be adjusted prior to building all other SELinux packages. As the sys-apps/policycoreutils package is deployed, Portage would attempt to enable its SELinux support. However, as SELinux is currently not properly configured, it is necessary to disable its SELinux support through FEATURES="-selinux":

root #FEATURES="-selinux" emerge -1 selinux-base

Configuring the SELinux policy

The main SELinux configuration file is now at /etc/selinux/config. It needs to be edited to set two important values: SELINUX and SELINUXTYPE.

FILE /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=permissive
  
# 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

The SELINUX variable defines how SELinux should behave:

  • enforcing will enable and enforce policies. This is the target at the end, but we need to start in permissive mode first to make sure everything would work as expected.
  • permissive will enable policies, but not enforce them. Any violation is reported but not denied. This is where most users should start from as it will not impact the system, yet allow users to get acquainted with SELinux - and validate the warnings to see if the system can be switched towards enforcing or not later.
  • disabled will completely disable the policies. As this will not show any violations as well, it is not recommended.

The SELINUXTYPE variable selects the SELinux policy store to load. Most development is done using the strict policy store (as it provides full confinement), although the others are supported as well.

Make sure that the SELINUX variable is set to permissive right now. We will switch to enforcing later.

Installing policies and utilities, part two

Now continue with the installation of the SELinux policies. Rebuild the sec-policy/selinux-base package if SELINUXTYPE is changed to something else than strict, and then install the core SELinux policies through the sec-policy/selinux-base-policy package. This package contains the core SELinux policies needed to get the system up and running using SELinux. As Portage will try to label and reload policies we need to temporarily disable SELinux support again (as Portage wouldn't be able to label anything as it doesn't understand it yet).

Note
After you've emerged sec-policy/selinux-base package in part one of this installation it is now necessary to use FEATURES="-selinux -sesandbox" for sec-policy/selinux-base and sec-policy/selinux-base-policy packages.
root #FEATURES="-selinux -sesandbox" emerge -1 selinux-base
root #FEATURES="-selinux -sesandbox" emerge selinux-base-policy

Now it is finally time to rebuild all packages affected by the profile change. Don't forget to use etc-update or dispatch-conf afterwards as some changes to configuration files will need to be made. This operation will also pull in all SELinux policy packages needed for the various components already installed on the system.

root #emerge -uDN @world

Reboot and relabel

Important
Repeat these steps every time the system is rebooted from a non-SELinux enabled mode into a SELinux enabled mode, as running with a non-SELinux enabled kernel will not update the security attributes of the files created or manipulated during day-to-day activities on the system.

First reboot the system so that the installed policies are loaded.

root #shutdown -r now

Next relabel all devices and openrc related files. This will apply the correct security contexts (labels) onto the necessary files. We start by bind-mounting / onto /mnt/gentoo. This will allow us to relabel the mount points themselves rather than the mounted file systems that are already mounted on the main file system.

root #mkdir /mnt/gentoo
root #mount -o bind / /mnt/gentoo

In the following commands, substitute strict in the next command with targeted (or other policy store name) depending on the SELINUXTYPE value. Also, use lib instead of lib64 if the system is a 32-bit system.

root #setfiles -r /mnt/gentoo /etc/selinux/strict/contexts/files/file_contexts /mnt/gentoo/dev
root #setfiles -r /mnt/gentoo /etc/selinux/strict/contexts/files/file_contexts /mnt/gentoo/lib64
root #umount /mnt/gentoo

If the system uses a swapfile rather than a swap partition, label it accordingly:

root #semanage fcontext -a -t swapfile_t "/swapfile"
root #restorecon /swapfile

Now relabel the entire file system. The next command will apply the correct security context onto the files on the entire file system, based on the security context information provided by the SELinux policy modules installed.

root #rlpkg -a -r

If a SELinux policy module for a package is installed after that particular package, then rlpkg needs to be run for that package to make sure that the security contexts for its files are set correctly. For instance, if sec-policy/selinux-screen would be installed manually (due to a missing dependency) after installing app-misc/screen:

root #rlpkg screen

Reboot and set SELinux booleans

Reboot the system so that the newly applied file contexts are used. Log on and, if Gentoo is installed using the hardened sources (as is recommended), enable the SSP SELinux boolean.

root #setsebool -P global_ssp on

SELinux booleans enable (or disable) SELinux policy rules based on the boolean value. In this case, the boolean allows every domain read access to the /dev/urandom device.

Define the administrator accounts

If the SELINUXTYPE variable is set to strict, then it is necessary to map the account(s) used to manage the system (those that need access to Portage) to the staff_u SELinux user. If not, none of the accounts will be able to succesfully manage the system (except for root, but then the administrator will need to login as root directly and not through sudo or su.) By default, users are mapped to the user_u SELinux user who doesn't have the appropriate rights (nor access to the appropriate roles) to manage a system. Accounts that are mapped to staff_u can, but might need to switch roles from staff_r to sysadm_r before they are granted the appropriate privileges.

In the following example, we map the john Linux account to the staff_u SELinux user:

root #semanage login -a -s staff_u john
root #restorecon -R -F /home/john

When system administration tasks need to be executed, the user will need to switch the role to sysadm_r. For this, the newrole command can be used.

user $id -Z
staff_u:staff_r:staff_t
user $newrole -r sysadm_r
Password: (Enter your password)
user $id -Z
staff_u:sysadm_r:sysadm_t

In a targeted policy, the users will be of type unconfined_t and will already have the necessary privileges to perform system administrative tasks.

Supporting service administration

By default, the Gentoo Hardened SELinux policies will allow the sysadm_t domain access to all services. However, some of these services have policies that allow them to be assigned to individual, non-root users. This requires the user to be granted the system_r role (meaning the user can, under certain circumstances, have his role change towards the system role).

It is therefor recommended to grant the system_r role to the administrative SELinux users that are going to administer the system. These are most likely the root and staff_u SELinux user.

root #semanage user -m -R "staff_r sysadm_r system_r" root
root #semanage user -m -R "staff_r sysadm_r system_r" staff_u

Summary

That's it. SELinux is now fully configured on the system. Although it will boot in permissive mode (most likely) right now, everything is now in place to validate if SELinux will further prevent applications from working or not. If, after booting and logging in, the id -Z command shows the proper context, then the system is most likely ready to be switched into enforcing mode (by editing /etc/selinux/config).