(For more resources related to this topic, see here.)
Once logged in to a system, our user will run inside a certain context. This user context defines the rights and privileges that we, as a user, have on the system. The command to obtain current user information, id, also supports SELinux context information. Try it out, and use the -Z switch as follows:
$ id -Z
unconfined_u:unconfined_r:unconfined_t
On SELinux systems with a targeted policy type, chances are very high that all users are logged in as unconfined_u (the first part of the context). On more restricted systems, the user can be user_u (regular restricted users), staff_u (operators), sysadm_u (system administrators), or any other of the SELinux user types.
The SELinux user defines the roles that the user can switch to, which themselves define the domains that the user (or his processes) can run in. By default, a fixed number of SELinux users are available on the system, but administrators can create different SELinux users. It is also the administrator’s task to assign Linux logins to SELinux users.
SELinux is able to provide full system confinement: each and every application runs in its own restricted environment from where it cannot break out of. But that requires fine-grained policies that are equally fast developed as the new versions of all the applications that they confine.
The following diagram shows this relation between the policies, the domain applicability towards multiple processes and the development effort. As an example, postfix_cleanup_t is shown as a very fine-grained policy domain (which is used for the cleanup process involved in the Postfix mail infrastructure) whereas the unconfined_t domain is shown as the example for a very broad, almost unlimited access domain:
Most applications do not have a dedicated policy (although most security-sensitive or popular ones do) and policies do not adapt as fast as the applications themselves. For many servers though, this fine-grained mandatory access is not necessary. All that is needed is to confine the services that are exposed to the network. To support this, SELinux policy developers created the “unconfined” concept, that is, although still governed by SELinux, the domain or user is not really restricted.
Not only are those domains very powerful with respect to privilege, the idea is also that these domains do not need to switch to other domains (unless when they need to switch to a confined domain, of course) and that they are not restricted by constraints that are imposed on confined domains (including MLS).
An important asset in this unconfined story is the unconfined_t domain for the unconfined_u SELinux user (with the unconfined_r SELinux role). This is exactly the context that we get when logged in to a default Fedora installation or a Gentoo installation that uses the targeted policy store (or mcs /mls with USE=”unconfined”).
Next to the user domains, we also have unconfined process domains for daemons and other applications. Some of these run in the unconfined_t domain as well, but most of them run in their own domain even though they are still unconfined. The seinfo tool can tell us which domains are unconfined by asking for those domains that have the selinux_unconfined_type attribute set as follows:
# seinfo -aselinux_unconfined_type -x
Defining a domain is unconfined or cannot be toggled by administrators, as this is a pure SELinux policy matter.
Within SELinux systems, the moment a user logs in, the login system checks to which SELinux user his login is mapped. Then, when a SELinux user is found, the system looks up the role and domain that the user should be in.
When we logged in to the system and checked our context using id -Z, we noticed that the presented context is the same regardless of the username through which we logged in to the system. SELinux does not care which Linux user we are, as long as it knows which context we are in.
When our login process is triggered, a local definition file will be checked to see which SELinux user is mapped to our login. Let us take a look at the existing login mappings using semanage login –l as follows:
# semanage login -l
Login Name SELinux User MLS/MCS Range Service
__default__ unconfined_u s0-s0:c0.c1023 *
root unconfined_u s0-s0:c0.c1023 *
system_u system_u s0-s0:c0.c1023 *
In the output, two login names are special for SELinux: the __default__ and system_u definitions:
The SELinux user is not the only information of a SELinux mapping. In case of an MLS-enabled system, the mapping also contains information about the sensitivity range in which the user is allowed to work (MLS/MCS Range). This way, two users might both be mapped to the user_u restricted SELinux user, but one might only be allowed to access the low sensitivity (s0) whereas another user might also have access to higher sensitivities (for example, s1). Or, in case of MCS, one user might be mapped to a different set of categories different from another user.
As an exercise, let us create a new Linux user called myuser and make sure that, when this user is logged in, the context is that of the unprivileged SELinux user_u user. We accomplish this using the semanage login tool as follows:
# semanage login -a -s user_u myuser
The -s parameter is used to map a login to a SELinux user, whereas sensitivity (and categories) can be handled with the -r parameter. In the next example, we modify the newly created mapping by limiting the user to the sensitivity range s0-s2 and categories c0 to c4:
# semanage login -m -r “s0-s2:c0.c4” myuser
The changes take effect when a new login occurs so we should force a logout for these users. The following command locks our myuser account, kills all the processes of that user, and unlocks the user again as follows:
# passwd -l myuser
Locking password for user myuser.
passwd: Success
# pkill -KILL -u myuser
# passwd -u myuser
Unlocking password for user myuser.
passwd: Success
Also, when an existing user is modified, we should also reset the contexts of that users’ home directory (while he is not logged on). To accomplish this, use restorecon using the -F option as follows:
# restorecon -RF /home/myuser
That is quite easy. Of course, in larger environments, creating mappings this way for individual users is not manageable. In such cases, it might be better to use (primary) group information. Most regular users are part of the user’s Linux group, so let us assign those users to the user_u SELinux user. Accounts that are in the admins Linux group are mapped to sysadm_u . To accomplish this, we use the percentage sign to tell the SELinux tools that this mapping is for groups:
# semanage login -a -s user_u “%users”
# semanage login -a -s sysadm_u “%admins”
Now that the group mappings are in place, we can remove the myuser individual mapping we made earlier as follows:
# semanage login -d myuser
SELinux maps Linux users onto SELinux users and defines the roles that a user is allowed to be in through the SELinux user definitions. We learned how to manage those mappings and the SELinux users with the semanage application and were able to grant the right roles to the right people. We also saw how the same commands are used to grant proper sensitivity to the user and how we can describe these levels in the setrans.conf file. We used the chcat tool to do most of the category-related management activities.
Further resources on this subject:
I remember deciding to pursue my first IT certification, the CompTIA A+. I had signed…
Key takeaways The transformer architecture has proved to be revolutionary in outperforming the classical RNN…
Once we learn how to deploy an Ubuntu server, how to manage users, and how…
Key-takeaways: Clean code isn’t just a nice thing to have or a luxury in software projects; it's a necessity. If we…
While developing a web application, or setting dynamic pages and meta tags we need to deal with…
Software architecture is one of the most discussed topics in the software industry today, and…