Assigning contexts through PAM
End users log in to a Linux system through either a login process (triggered through a
getty process), a networked service (for example, the OpenSSH daemon), or through a graphical login manager (
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 the
root 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 the
The following code listing is an excerpt from CentOS’s
/etc/pam.d/remote file, limited to PAM’s session service directives. It triggers the
pam_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 exploits and 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 to
user_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.
pam_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 the
conf= option inside the PAM configuration itself.
sepermit.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
- SELinux usernames, prefixed with the
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:
exclusivemeans 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.
PAM_IGNOREas the return status if SELinux is in enforcing mode, and
PAM_AUTH_ERRif SELinux is in permissive mode. This allows special constructs/branches for this user in PAM based on the permissive state of the system.
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.
Polyinstantiation is an approach 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, except
root, 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
The following setting in
/etc/security/namespace.conf will remap these two locations:
/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
/var/tmp/tmp-inst. The end users do not know or see the remapped locations – for them,
/var/tmp are as they would expect.
The format (and thus polyinstantiation) of the subdirectories created depends on the third option within the
namespace.conf file. The supported options are as follows:
user, which will create a subdirectory named after the user (such as
level, which will create a subdirectory named after the user sensitivity level and username (such as
context, which will create a subdirectory named after the process context (including the sensitivity level) and username (such as
In the default
namespace.conf file, you might notice that this also has support for home directories. When enabled with the
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
# mkdir /tmp-inst && chmod 000 /tmp-inst
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