We saw how SELinux users define the role(s) that a user can hold. But how does SELinux enforce which role a user logs in through? And when logged in, how can a user switch their active role?
Defining allowed SELinux contexts
To select the context assigned to a successfully authenticated user, SELinux introduces the notion of adefault context. Based on the context of the service through which a user logs in (or through which the user executes commands), the system selects the right user context.
Inside the/etc/selinux/targeted/contexts
directory, a file calleddefault_contexts
exists. Each line in this file starts with the SELinux context information of the parent process and is then followed by an ordered list of all the contexts that could be picked based on the user’s allowed SELinux role(s).
Consider the following line of code for thesshd_t
context:
system_r:sshd_t:s0 user_r:user_t:s0 \
staff_r:staff_t:s0 \
sysadm_r:sysadm_t:s0 \
unconfined_r:unconfined_t:s0
This line of code mentions that when a user logs in through a process running in thesshd_t
domain, the listed roles are checked against the roles of the user. The user will transition to the first context listed that matches the roles the user can use.
For instance, assume we are mapped to an SELinux user that has access to both thestaff_r
andsysadm_r
roles. In that case, we will log in asstaff_r:staff_t
since that is the first match.
However, like theseusers
file for the Linux account mappings, thedefault_contexts
file is a default file that can be overruled through specific customizations. These customizations are stored in the/etc/selinux/targeted/contexts/users
subdirectory. These files are named after the SELinux user for which they take effect. This allows us to assign different contexts for particular SELinux users even if they share the same roles with other SELinux users. Because SELinux checks the entries per line, we do not need to copy the entire content of thedefault_contexts
file. Only the configuration lines that we want to see a different configuration for need to be listed; SELinux will automatically use thedefault_contexts
file for the rest.
Let’s modify the default contexts so that thestaff_u
SELinux user logs in with thesysadm_r
role (and with thesysadm_t
type) when logged in through SSH. To do so, use thesshd_t
line, modify it, and save the result as/etc/selinux/targeted/contexts/users/staff_u
:
system_r:sshd_t:s0 sysadm_r:sysadm_t:s
Specifically, for the SSH daemon, we also need to enable the ssh_sysadm_login
boolean, which is a special precaution SELinux policy developers have made to prevent users from immediately logging in with highly privileged accounts:
# setsebool ssh_sysadm_login on
With these settings in place, we’ve set sysadm_r:sysadm_t:s0
as the only possible context, ensuring that the target context is staff_u:sysadm_r:sysadm_t
Validating contexts with getseuser
To validate whether our change succeeded, we can ask SELinux what the result of a context choice will be without having to parse the files ourselves. We can accomplish this through the getseuser
command, which takes two arguments: the Linux user account and the context of the process that switches the user context.
Note:
The getseuser
command is a helper utility offered by the SELinux user space project, but is not made available on all distributions. You will find it on Debian and Gentoo, but not on CentOS or other Red Hat Enterprise Linux-derived distributions.
Here’s an example that checks what the context would be for the sven
user when they log in through a process running in the sshd_t
domain:
# getseuser sven system_u:system_r:sshd_t
seuser: user_u, level s0-s0
Context 0 user_u:user_r:user_t:s0
One of the advantages of the getseuser
command is that it asks the SELinux code what the context should be, which not only looks through the default_contexts
and customized files, but also checks whether the target context can be reached or not, and that there are no other constraints that prohibit the change to this context.
Switching roles with newrole
After havingsuccessfully authenticated and logged in, users will be assigned the context through the configuration mentioned in theSELinux users and rolessection. If the SELinux user has access to multiple roles, however, then the Linux user can use thenewrole
application to transition from one role to another.
Consider an SELinux system without unconfined domains and where we are, by default, logged in as thestaff_r
role. To perform administrative tasks, we need to switch to thesysadm_r
administrative role, which we can do with thenewrole
command. This command only works when working through a secure terminal listed in/etc/securetty
:
$ id -Z
staff_u:staff_r:staff_t:s0
$ newrole -r sysadm_r
Password: (Enter user password)
$ id -Z
staff_u:sysadm_r:sysadm_t:s0
Notice how the SELinux user remains constant but the role and domain have changed.
Thenewrole
command can also be used to transition to a specific sensitivity, as follows:
$ newrole -l s0-s0:c0.c100
When weswitchto another role or sensitivity, what we actually do is create a new session (with a new shell) that has this new role or sensitivity. The command does not change the context of the current session, nor does it exit from the current session.
We can return from our assigned role and go back to the first session by exiting (throughexit
,logout
, orCtrl+D).
Managing role access through sudo
Most administrators usesudo
for privilege delegation: allowing users to run certain commandsin a more privileged context than the user is otherwise allowed. Thesudo
application is also capable of switching SELinux roles and types.
We can pass the target role and type tosudo
directly. For instance, we can tellsudo
to switch to the administrative role when we edit a PostgreSQL configuration file:
$ sudo -r sysadm_r -t sysadm_t vim /var/lib/pgsql/data/pg_hba.conf
However, we can also configure sudo
through the /etc/sudoers
file to allow users to run commands within a certain role and/or type, or get a shell within a certain context. Consider a user that has access to both the user_r
and dbadm_r
roles (with the dbadm_r
role being a role designated for database administrators). Within the sudoers
file, the following line allows the myuser
user to run any command through sudo,
which, when triggered, will run with the dbadm_r
role and within the dbadm_t
domain:
myuser ALL=(ALL) TYPE=sysadm_t ROLE=sysadm_r ALL
Often, administrators will prefer sudo
over newrole
as the latter does not change the effective user ID, which is often required for end users when they want to invoke a more privileged command (concerning the root user or a service-specific runtime account) anyway. The sudo
application also has great logging capabilities, and we can even have commands switching roles without requiring the end user to explicitly mention the target role and type. Sadly, it does not support changing sensitivities.
Reaching other domains using runcon
Anotherapplication that can switch roles and sensitivities is theruncon
application. Theruncon
command is available for all users and is used to launch a specific command as a different role, type, and/or sensitivity. It even supports changing the SELinux user – assuming the SELinux policy lets you.
Theruncon
command does not have its own domain – it runs in the context of the user executing the command. As such, the privileges of the user domain itself govern the ability to change the role, type, sensitivity, or even SELinux user.
Most of the time, we will useruncon
to launch applications with a particular category. This allowsus to take advantage of the MCS approach in SELinux without requiring applications to be MCS-enabled:
$ runcon -l Salaries bash
$ id -Z
unconfined_u:unconfined_r:unconfined_t:Salaries
For instance, in the previous example, we run a shell session with the Salaries
category (prohibiting it from accessing resources that do not have the same or fewer categories set).
Switching to the system role
Sometimes, administrators will need to invoke applications that should not run under their current SELinuxuser context but instead as thesystem_u
SELinux user with thesystem_r
SELinux role. SELinux policy administrators acknowledge this need, and allow averylimited set of domains to switch the SELinux user to a different user – perhaps contrary to the purpose of the immutability of SELinux users mentioned earlier. Yet, as there are cases where this is needed, SELinux needs to accommodate this. One of the applications allowed to switch the SELinux user isrun_init
(through itsrun_init_t
domain).
Therun_init
application is mainly (almost exclusively) used to start background system services on a Linux system. Using this application, the daemons do not run under the user’s SELinux context but the system’s, as required by SELinux policies.
As this is only needed on systems where launching additional services is done through service scripts, distributions that usesystemd
do not require the use ofrun_init
.systemd
already runs with thesystem_r
role and is responsible for starting additional services. As such, no role transition is needed. Otherinit
systems, such as Gentoo’s OpenRC, integraterun_init
so that administrators do not generally need to invokerun_init
manually.
Most SELinux policies enable role-managed support for selective service management (for nonsystemd
distributions). This allows users that do not have complete system administration rights to still manipulate a select number of services on a Linux system, allowed by the SELinux policy. These users are to be granted thesystem_r
role, but once accomplished, they do not need to callrun_init
to manipulate specific services anymore. The transitions happen automatically and only for the services assigned to the user – other services cannot be launched by these users.
This finalizesour article on handling SELinux roles. We’ve learned how to manage SELinux roles and switching roles and contexts, as well as how to define the target role and type in the case of privilege escalation. In the last section of this chapter, we will look at how PAM is used to configure the SELinux context setup on the system.