1 SELinux #
This chapter gives a brief overview of SELinux implementation on SLE Micro.
SELinux was developed as an additional Linux security solution that uses the security framework in the Linux kernel. The purpose was to allow for a more granular security policy that goes beyond the standard Discretionary Access Controls (DAC), the traditional file permissions of owner/group/world, and read/write/execute.
SELinux uses labels attached to objects (for example, files and network sockets) and uses them for access decisions.
The default action of SELinux is to deny any access. SELinux allows only actions that were specifically allowed in the SELinux policy. Another feature of SELinux that increases security is that SELinux allows strict confinement of processes up to the point where the processes cannot access files of other processes on the same system.
SELinux was designed to enhance existing security solutions, not to replace them. For example, discretionary access control (DAC) is still applied even if the system is using SELinux. If DAC denies access first, SELinux is then not used as the access was already blocked by another mechanism.
1.1 Getting SELinux #
SELinux is installed by default when installing SLE Micro by YaST or is part of the pre-built images. The default mode is set to enforced on all deployment types, and the file system is labelled.
If in any case SELinux is not set up on your system, run the following command:
#
transactional-update setup-selinux
Reboot your system after the command has finished. The command installs the
SELinux policy if it is not installed, sets the enforcing
SELinux mode and rebuilds initramfs
.
1.2 SELinux modes #
SELinux can run in one of three modes: disabled
,
permissive
, or enforcing
.
Using the disabled
mode means that no rules from the
SELinux policy are applied and your system is not protected. Therefore, the
disabled
mode is not recommended.
In the permissive
mode, SELinux is active, the security
policy is loaded, the file system is labeled and access denial entries are
logged. However, the policy is not enforced and thus no access is actually
denied.
In the enforced
mode, the security policy is applied.
Each access that is not explicitly allowed by the policy is denied.
You can switch between the enforcing
and
permissive
modes by using the
setenforce
command. Alternatively, you can switch between
all SELinux modes by editing the /etc/selinux/config
configuration file. Changes performed by the setenforce
command are valid only until the next reboot. For persistent changes of the
SELinux mode, edit the /etc/selinux/config
configuration file.
The setenforce
command has the following syntax:
#
setenforce MODE_ID
where MODE_ID is 0 for
the permissive
mode or 1 for
the enforced
mode.
To verify the mode, run the following command:
#
getenforce
The command should return permissive
or
enforced
, depending on the provided
MODE_ID.
To change the SELinux mode permanently, in the file
/etc/selinux/config
, change the value of
SELINUX
to disabled
, or
permissive
, or enforced
as follows:
SELINUX=disabled
The changes in the file are applied after the next reboot.
disabled
mode
If you disable SELinux on your system and then enable it later, make sure
that you relabel your system. When SELinux is disabled, and you perform
changes to your file system, the changes are not reflected in the context
anymore (for example, new files do not have any context). Therefore, you
need to relabel your system by using the restorecon
command, using the autorelabel
boot parameter, or by
creating a file that triggers relabeling on the next boot. To create
the file, run the following command:
#
touch /etc/selinux/.autorelabel
After reboot, the file /etc/selinux/.autorelabel
is
replaced with another flag file:
/etc/selinux/.relabelled
to prevent relabeling on
subsequent reboots.
1.3 SELinux policy overview #
The policy is the key component in SELinux. Your SELinux policy defines rules that specify which objects can access which files, directories, ports, and processes on a system. To do this, a security context is defined for all of these.
An SELinux policy contains a huge number of rules. To make it more manageable, policies are often split into modules. This allows the administrator to switch protection on or off for different parts of the system.
When compiling the policy for your system, you have a choice to either work with a modular policy, or a monolithic policy, where one huge policy is used to protect everything on your system. It is strongly recommended to use a modular policy and not a monolithic policy. Modular policies are much easier to manage.
SLE Micro is shipped with the targeted
SELinux policy.
1.3.1 Creating policies for containers #
SLE Micro is delivered with a policy that by default does not
allow containers to access files outside the container data. On the
other hand, all network access is allowed. Typically, containers are
created with bind mounts and should be able to access other directories
like /home
or /var
.
You may want a possibility to allow access to these directories or, on the
contrary, restrict some ports to the container even if SELinux is used
on your system. In this case, you need to create new policy rules that
enable or disable the access. SLE Micro provides the Udica tool for
this purpose.
The following procedure describes how to create a custom policy for your containers:
Make sure that SELinux is in the enforcing mode. For details, refer to Section 1.2, “SELinux modes”.
Start a container using the following parameters:
#
podman run -v /home:/home:rw -v /var/:/var/:rw -p 21:21 -it sle15 bashThe container runs with the default policy that does not allow access to the mount points but does not restrict other ports.
You can exit the container.
Obtain the container ID:
#
podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e59f9d0f86f2 registry.opensuse.org/devel/bci/tumbleweed/containerfile/opensuse/bci/ruby:latest /bin/bash 8 minutes ago Up 8 seconds ago 0.0.0.0:21->21/tcp zen_ramanujanCreate a JSON file that Udica will use to create a custom policy for the container:
#
podman inspect e59f9d0f86f2 > OUTPUT_JSON_FILEFor example, substitute OUTPUT_JSON_FILE with
container.json
Run Udica to generate a policy according to the container parameters:
#
udica -j OUTPUT_JSON_FILE CUSTOM_CONTAINER_POLICYFor example:
#
udica -j container.json custom_policyAccording to the provided instructions, load the policy modules by running:
#
semodule -i custom_policy.cil /usr/share/udica/templates/{base_container.cil,net_container.cil,home_container.cil}Run a container with the new policy module by using the
--security-opt
option as follows:#
podman run --security-opt label=type:custom_policy.process -v /home:/home:rw -v /var/:/var/:rw -p 21:21 -it sle15 bash
1.4 SELinux security context #
The security context is a set of information assigned to a file or a process. It consists of SELinux user, role, type, level and category. This information is used to make access control decisions.
- SELinux user
is an identity defined in the policy that is authorized for a specific set of roles and for a specific level range. Each Linux user is mapped to an SELinux user. SELinux does not use the list of user accounts maintained by Linux in
/etc/passwd
, but uses its own database and mapping. By convention, the identity name is suffixed with_u
, for example:user_u
.- role
defines a set of permissions that a user can be granted. A role defines which types a user assigned to this role can access. By convention, the role name is suffixed with
_r
, for example:system_r
.- type
conveys information on how particular files and processes can interact. A process consists of files with a concrete SELinux type, and it cannot access files outside of this type. By convention, the type name is suffixed with
_t
, for example:var_t
.- level
is an optional attribute that specifies the range of levels of clearance in the multilevel security.
- category
is an optional attribute that allows you to add categories to processes, files, and users. A user can then access files that have the same category.
1.5 Tools for managing SELinux #
SLE Micro provides you with tools to manage SELinux on your system. If, in any case, the below described tools are not installed on your system, install the tools by running:
#
transactional-update pkg install policycoreutils-python-utils
After successful installation, reboot the system.
chcon
changes the security context of provided files to the context provided to the command
getenforce
displays the current SELinux mode
fixfiles
enables you to check for issues with a mismatched security context and then fix them
ls -Z PATH
shows security context of all files/directories in the specified PATH, for example:
#
ls -Z / system_u:object_r:bin_t:s0 bin system_u:object_r:boot_t:s0 boot system_u:object_r:device_t:s0 dev system_u:object_r:etc_t:s0 etc system_u:object_r:home_root_t:s0 home system_u:object_r:lib_t:s0 lib system_u:object_r:lib_t:s0 lib64 system_u:object_r:mnt_t:s0 mnt system_u:object_r:usr_t:s0 opt system_u:object_r:proc_t:s0 proc system_u:object_r:default_t:s0 root system_u:object_r:var_run_t:s0 run system_u:object_r:bin_t:s0 sbin system_u:object_r:var_t:s0 srv system_u:object_r:sysfs_t:s0 sys system_u:object_r:tmp_t:s0 tmp system_u:object_r:usr_t:s0 usr system_u:object_r:var_t:s0 varrestorecon
restores a file context to the default value (as stored in the SELinux policy)
semanage
enables you to adjust context and configure certain elements of SELinux policy. The command provides several subcommands. For details, use:
#
semanage --helpsetenforce
enables you to temporarily set a SELinux mode to
permissive
orenforcing
sestatus
displays the current status of SELinux, for example:
#
sestatus SELinux status: enabled SElinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Memory protection checking: requested (insecure) Max kernel policy version: 31
Z
option available to other commands
You can also use the Z
option with other commands, for
example: cp, ps
, and id
.