With all the information about SELinux users and roles, we have not touched upon how exactly applications or services create and assign an SELinux context to a user. As mentioned earlier on, this is coordinated through the use of Linux’s PAM services.
Assigning contexts through PAM
End userslog in to a Linux system through either a login process (triggered through agetty
process), a networked service (for example, the OpenSSH daemon), or through a graphical login manager (xdm
,kdm
,gdm
,slim
, and so on).
These services are responsible for switching our effective user ID (upon successful authentication, of course) so that we are not active on the system as theroot
user. For SELinux systems, these processes also need to switch the SELinux user (and role) accordingly, as otherwise, the context will be inherited from the service, which is obviously wrong for any interactive session.
In theory, all these applications can be made fully SELinux aware, linking with the SELinux user space libraries to get information about Linux mappings and SELinux users. Instead of converting all these applications, the developers decided to take the authentication route to the next level using the PAM services that Linux systems provide.
PAM offers a very flexible interface for handling different authentication methods on Linux (and Unix) systems. All applications mentioned earlier use PAM for their authentication steps. To enable SELinux support for these applications, we need to update their PAM configuration files to include thepam_selinux.so
library.
The following code listing is an excerpt from CentOS’s/etc/pam.d/remote
file, limited to PAM’s session service directives. It triggers thepam_selinux.so
library code as part of the authentication process, as follows:
session required pam_selinux.so close
session required pam_loginuid.so
session required pam_selinux.so open
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include password-auth
session include postlogin
The arguments supported by the pam_selinux.so
code are described in the pam_selinux
manual page. In the preceding example, the close
option clears the current context (if any), whereas the open
option sets the context of the user. The pam_selinux
module takes care of querying the SELinux configuration and finding the right mappings and context based on the service name used by the daemon.
Prohibiting access during permissive mode
Having SELinux active and enforcing on a system improves its resilience against successful exploitsand other malicious activities, especially when the system is used as a shell server (or provides other interactive services) and the users are confined – meaning they are mapped touser_u
or other confined SELinux users.
Some administrators might want to temporarily switch the system to permissive mode. This could be to troubleshoot issues or to support some changes made on the system. When using permissive mode, it would be a good idea to ensure that the interactive services are not usable for regular users.
Withpam_sepermit
, this can be enforced on the system. The PAM module will deny a set of defined users access to the system if the system is in permissive mode. By default, these users are mentioned in/etc/security/sepermit.conf
, but a different file can be configured through theconf=
option inside the PAM configuration itself.
In thesepermit.conf
file, there are three approaches to document which users should be denied access when the system is in permissive mode:
- Regular usernames
- Group names, prefixed with the
@
sign - SELinux usernames, prefixed with the
%
sign
Within this file, we list each user, group, or SELinux user on a single line. After each entry, we can (but don’t have to) add one or two options:
exclusive
means that the system will allow the user to be active even when the system is in permissive mode, but only a single session can be active. When the user logs out, all active processes will be killed.ignore
will returnPAM_IGNORE
as the return status if SELinux is in enforcing mode, andPAM_AUTH_ERR
if SELinux is in permissive mode. This allows special constructs/branches for this user in PAM based on the permissive state of the system.
To enable pam_sepermit
, it’s sufficient to enable the module in the auth PAM service as follows:
auth required pam_sepermit.so
Of course, don’t forget to remove all active user sessions when switching to permissive mode, as any running session is otherwise left untouched.
Polyinstantiating directories
The last PAM module we’ll look at ispam_namespace.so
. Before we dive into configuring thismodule, let’s first look at what polyinstantiation is about.
Polyinstantiationis anapproach where, when a user logs in to a system, the user gets a view on filesystem resources specific to its session, while optionally hiding the resources of other users. This differs from regular access controls, where the other resources are still visible, but might just be inaccessible.
This session-specific view, however, does not just use regular mounts. The module uses the Linux kernel namespace technology to force a (potentially more limited) view on the filesystem, isolated and specific to the user session. Other users have a different view on the filesystem.
Let’s use a common example. Assume that all users, exceptroot
, should not have access to the temporary files generated by other users. With standard access controls, these resources would still be visible (perhaps not readable, but their existence or the directories they reside in would be visible). Instead, with polyinstantiation, a user will only see their own/tmp
and/var/tmp
views.
The following setting in/etc/security/namespace.conf
will remap these two locations:
namespace.conf
/tmp /tmp/tmp-inst/ level root
/var/tmp /var/tmp/tmp-inst/ level root
On the real filesystem, those locations will be remapped to a subdirectory inside/tmp/tmp-inst
and/var/tmp/tmp-inst
. The end users do not know or see the remapped locations – for them,/tmp
and/var/tmp
are as they would expect.
The format (and thus polyinstantiation) of the subdirectories created depends on the third option within thenamespace.conf
file. The supported options are as follows:
user
, which will create a subdirectory named after the user (such aslisa
)level
, which will create a subdirectory named after the user sensitivity level and username (such assystem_u:object_r:tmp_t:s0-s0:c0.c1023_lisa
)context
, which will create a subdirectory named after the process context (including the sensitivity level) and username (such assystem_u:object_r:user_tmp_t:s0_lisa
)
For SELinux systems, the most common setting is level
Note:
In the default namespace.conf
file, you might notice that this also has support for home directories. When enabled with the level
or context
method, this will ensure that users have a sensitivity-specific home directory set. For instance, if the system configuration forces the user to have a lower sensitivity when logged in through SSH than when the user logs in through the terminal, a different home directory view will be used.
In the previous example, only the root user is exempt from these namespace changes. Additional users can be listed (comma-separated), or an explicit list of users can be given for which polyinstantiation needs to be enabled (if we prefix the user list with the ~
character). To allow the namespace changes to take place, the target locations need to be available on the system with the 000
permission:
# mkdir /tmp-inst & chmod 000 /tmp-inst
Next, enable pam_namespace.so
in the PAM configuration files at the session service:
session required pam_namespace.so
Finally, make sure that SELinux allows polyinstantiated directories. On CentOS, this is governed through the polyinstantiation_enabled
SELinux boolean:
# setsebool polyinstantiation_enabled on
Other distributions will have it through theallow_polyinstantiation
SELinux boolean.
With thepolyinstantiation support, we close off this final section of the chapter, where we learned how PAM is used to trigger SELinux context changes on the system.